Re: [PATCH 2/5] lguest guest feedback tidyups

2007-05-10 Thread Christoph Hellwig
On Fri, May 11, 2007 at 11:21:30AM +1000, Rusty Russell wrote:
> 1) send-dma and bind-dma hypercall wrappers for drivers to use,
> 2) formalization of the convention that devices can use the irq
>corresponding to their index on the lguest_bus.
> 3) ___force to shut up sparse: guests *can* use ioremap as virtual mem.

No, they can't.  Even if in your case the underlying address spaces
happen to be the same anything returned by ioremap must use the proper
accessors.  That's the whole point of having this separation, otherwise
you wouldn't need to use ioremap at all.  So instead of sprinkling cast
around add lguest_read*/lguest_write* accessors that do the __force cast
once and make sure the ioremap return value is always accessed using those.

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [PATCH 0/5] lguest feedback tidyups

2007-05-10 Thread Christoph Hellwig
On Fri, May 11, 2007 at 11:17:26AM +1000, Rusty Russell wrote:
> - But the cost was high: lots of __force casts 8(

That sounds like something is very fishy.

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [PATCH 2/2] lguest: Convert to hrtimer framework

2007-05-10 Thread Rusty Russell
On Wed, 2007-05-09 at 09:37 -0400, James Morris wrote:
> Convert lguest to the hrtimer framework, enabling dynamic ticks and high 
> resolution timers.

Thanks very much for this James!  Applied after the Great Documentation
patch, so I'm adding some extra verbiage.

Cheers,
Rusty.

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


[PATCH 5/5] lguest console driver feedback tidyups

2007-05-10 Thread Rusty Russell
1) Use new lguest_send_dma & lguest_bind_dma functions.
2) sparse: lguest_cons can be static.

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 drivers/char/hvc_lguest.c |   15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

===
--- a/drivers/char/hvc_lguest.c
+++ b/drivers/char/hvc_lguest.c
@@ -36,7 +36,7 @@ static int put_chars(u32 vtermno, const 
dma.len[1] = 0;
dma.addr[0] = __pa(buf);
 
-   hcall(LHCALL_SEND_DMA, LGUEST_CONSOLE_DMA_KEY, __pa(&dma), 0);
+   lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma);
return count;
 }
 
@@ -59,7 +59,7 @@ static int get_chars(u32 vtermno, char *
return count;
 }
 
-struct hv_ops lguest_cons = {
+static struct hv_ops lguest_cons = {
.get_chars = get_chars,
.put_chars = put_chars,
 };
@@ -75,14 +75,17 @@ console_initcall(cons_init);
 
 static int lguestcons_probe(struct lguest_device *lgdev)
 {
-   lgdev->private = hvc_alloc(0, lgdev->index+1, &lguest_cons, 256);
+   int err;
+
+   lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256);
if (IS_ERR(lgdev->private))
return PTR_ERR(lgdev->private);
 
-   if (!hcall(LHCALL_BIND_DMA, LGUEST_CONSOLE_DMA_KEY, __pa(&cons_input),
-  (1<<8) + lgdev->index+1))
+   err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1,
+ lgdev_irq(lgdev));
+   if (err)
printk("lguest console: failed to bind buffer.\n");
-   return 0;
+   return err;
 }
 
 static struct lguest_driver lguestcons_drv = {


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


[PATCH 2/5] lguest guest feedback tidyups

2007-05-10 Thread Rusty Russell
1) send-dma and bind-dma hypercall wrappers for drivers to use,
2) formalization of the convention that devices can use the irq
   corresponding to their index on the lguest_bus.
3) ___force to shut up sparse: guests *can* use ioremap as virtual mem.
4) lguest.c should include "lguest_bus.h" for lguest_devices declaration.

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 drivers/lguest/lguest.c |   20 
 drivers/lguest/lguest_bus.c |2 +-
 include/linux/lguest_bus.h  |   13 -
 3 files changed, 33 insertions(+), 2 deletions(-)

===
--- a/include/linux/lguest_bus.h
+++ b/include/linux/lguest_bus.h
@@ -7,7 +7,6 @@
 
 struct lguest_device {
/* Unique busid, and index into lguest_page->devices[] */
-   /* By convention, each device can use irq index+1 if it wants to. */
unsigned int index;
 
struct device dev;
@@ -15,6 +14,18 @@ struct lguest_device {
/* Driver can hang data off here. */
void *private;
 };
+
+/* By convention, each device can use irq index+1 if it wants to. */
+static inline int lgdev_irq(const struct lguest_device *dev)
+{
+   return dev->index + 1;
+}
+
+/* dma args must not be vmalloced! */
+void lguest_send_dma(unsigned long key, struct lguest_dma *dma);
+int lguest_bind_dma(unsigned long key, struct lguest_dma *dmas,
+   unsigned int num, u8 irq);
+void lguest_unbind_dma(unsigned long key, struct lguest_dma *dmas);
 
 struct lguest_driver {
const char *name;
===
--- a/drivers/lguest/lguest.c
+++ b/drivers/lguest/lguest.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -99,6 +100,25 @@ void async_hcall(unsigned long call,
next_call = 0;
}
local_irq_restore(flags);
+}
+
+void lguest_send_dma(unsigned long key, struct lguest_dma *dma)
+{
+   dma->used_len = 0;
+   hcall(LHCALL_SEND_DMA, key, __pa(dma), 0);
+}
+
+int lguest_bind_dma(unsigned long key, struct lguest_dma *dmas,
+   unsigned int num, u8 irq)
+{
+   if (!hcall(LHCALL_BIND_DMA, key, __pa(dmas), (num << 8) | irq))
+   return -ENOMEM;
+   return 0;
+}
+
+void lguest_unbind_dma(unsigned long key, struct lguest_dma *dmas)
+{
+   hcall(LHCALL_BIND_DMA, key, __pa(dmas), 0);
 }
 
 static unsigned long save_fl(void)
===
--- a/drivers/lguest/lguest_bus.c
+++ b/drivers/lguest/lguest_bus.c
@@ -136,7 +136,7 @@ static int __init lguest_bus_init(void)
return 0;
 
/* Devices are in page above top of "normal" mem. */
-   lguest_devices = ioremap(max_pfn << PAGE_SHIFT, PAGE_SIZE);
+   lguest_devices = (__force void*)ioremap(max_pfn

[PATCH 4/5] lguest block driver feedback tidyups

2007-05-10 Thread Rusty Russell
1) Use new dma wrapper functions, and handle bind failure (may happen
   in future)
2) Use new lgdev_irq() "get me a good interrupt number" function.
3)  __force the ioremap: guests can use it as normal memory.

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 drivers/block/lguest_blk.c |   16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

===
--- a/drivers/block/lguest_blk.c
+++ b/drivers/block/lguest_blk.c
@@ -123,7 +123,7 @@ static void do_write(struct blockdev *bd
pr_debug("lgb: WRITE sector %li\n", (long)req->sector);
setup_req(bd, 1, req, &send);
 
-   hcall(LHCALL_SEND_DMA, bd->phys_addr, __pa(&send), 0);
+   lguest_send_dma(bd->phys_addr, &send);
 }
 
 static void do_read(struct blockdev *bd, struct request *req)
@@ -134,7 +134,7 @@ static void do_read(struct blockdev *bd,
setup_req(bd, 0, req, &bd->dma);
 
empty_dma(&ping);
-   hcall(LHCALL_SEND_DMA, bd->phys_addr, __pa(&ping), 0);
+   lguest_send_dma(bd->phys_addr, &ping);
 }
 
 static void do_lgb_request(request_queue_t *q)
@@ -183,13 +183,13 @@ static int lguestblk_probe(struct lguest
return -ENOMEM;
 
spin_lock_init(&bd->lock);
-   bd->irq = lgdev->index+1;
+   bd->irq = lgdev_irq(lgdev);
bd->req = NULL;
bd->dma.used_len = 0;
bd->dma.len[0] = 0;
bd->phys_addr = (lguest_devices[lgdev->index].pfn << PAGE_SHIFT);
 
-   bd->lb_page = (void *)ioremap(bd->phys_addr, PAGE_SIZE);
+   bd->lb_page = (__force void *)ioremap(bd->phys_addr, PAGE_SIZE);
if (!bd->lb_page) {
err = -ENOMEM;
goto out_free_bd;
@@ -225,7 +225,9 @@ static int lguestblk_probe(struct lguest
if (err)
goto out_cleanup_queue;
 
-   hcall(LHCALL_BIND_DMA, bd->phys_addr, __pa(&bd->dma), (1<<8)+bd->irq);
+   err = lguest_bind_dma(bd->phys_addr, &bd->dma, 1, bd->irq);
+   if (err)
+   goto out_free_irq;
 
bd->disk->major = bd->major;
bd->disk->first_minor = 0;
@@ -241,6 +243,8 @@ static int lguestblk_probe(struct lguest
lgdev->private = bd;
return 0;
 
+out_free_irq:
+   free_irq(bd->irq, bd);
 out_cleanup_queue:
blk_cleanup_queue(bd->disk->queue);
 out_put_disk:
@@ -248,7 +252,7 @@ out_unregister_blkdev:
 out_unregister_blkdev:
unregister_blkdev(bd->major, "lguestblk");
 out_unmap:
-   iounmap(bd->lb_page);
+   iounmap((__force void *__iomem)bd->lb_page);
 out_free_bd:
kfree(bd);
return err;


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


[PATCH 3/5] lguest network driver feedback tidyups

2007-05-10 Thread Rusty Russell
Feedback from Jeff Garzik:
1) Use netdev_priv instead of dev->priv.
2) Check for ioremap failure
3) iounmap on failure.
4) Wrap SEND_DMA and BIND_DMA calls
5) Don't set NETIF_F_SG unless we set NETIF_F_NO_CSUM
6) Use SET_NETDEV_DEV()
7) Don't set dev->irq, mem_start & mem_end (deprecated)

Sparse warnings:
8) __force the ioremap: guests can use it as normal memory.

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 drivers/net/lguest_net.c |   53 ++
 1 file changed, 31 insertions(+), 22 deletions(-)

===
--- a/drivers/net/lguest_net.c
+++ b/drivers/net/lguest_net.c
@@ -35,6 +35,9 @@ struct lguestnet_info
unsigned long peer_phys;
unsigned long mapsize;
 
+   /* The lguest_device I come from */
+   struct lguest_device *lgdev;
+
/* My peerid. */
unsigned int me;
 
@@ -84,7 +87,7 @@ static void skb_to_dma(const struct sk_b
 
 static void lguestnet_set_multicast(struct net_device *dev)
 {
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
 
if ((dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || dev->mc_count)
info->peer[info->me].mac[0] |= PROMISC_BIT;
@@ -110,13 +113,13 @@ static void transfer_packet(struct net_d
struct sk_buff *skb,
unsigned int peernum)
 {
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
struct lguest_dma dma;
 
skb_to_dma(skb, skb_headlen(skb), &dma);
pr_debug("xfer length %04x (%u)\n", htons(skb->len), skb->len);
 
-   hcall(LHCALL_SEND_DMA, peer_key(info,peernum), __pa(&dma), 0);
+   lguest_send_dma(peer_key(info, peernum), &dma);
if (dma.used_len != skb->len) {
dev->stats.tx_carrier_errors++;
pr_debug("Bad xfer to peer %i: %i of %i (dma %p/%i)\n",
@@ -137,7 +140,7 @@ static int lguestnet_start_xmit(struct s
 {
unsigned int i;
int broadcast;
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
 
pr_debug("%s: xmit %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -162,7 +165,7 @@ static int lguestnet_start_xmit(struct s
 /* Find a new skb to put in this slot in shared mem. */
 static int fill_slot(struct net_device *dev, unsigned int slot)
 {
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
/* Try to create and register a new one. */
info->skb[slot] = netdev_alloc_skb(dev, ETH_HLEN + ETH_DATA_LEN);
if (!info->skb[slot]) {
@@ -180,7 +183,7 @@ static irqreturn_t lguestnet_rcv(int irq
 static irqreturn_t lguestnet_rcv(int irq, void *dev_id)
 {
struct net_device *dev = dev_id;
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
unsigned int i, done = 0;
 
for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
@@ -220,7 +223,7 @@ static int lguestnet_open(struct net_dev
 static int lguestnet_open(struct net_device *dev)
 {
int i;
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
 
/* Set up our MAC address */
memcpy(info->peer[info->me].mac, dev->dev_addr, ETH_ALEN);
@@ -232,8 +235,8 @@ static int lguestnet_open(struct net_dev
if (fill_slot(dev, i) != 0)
goto cleanup;
}
-   if (!hcall(LHCALL_BIND_DMA, peer_key(info, info->me), __pa(info->dma),
-  (NUM_SKBS << 8) | dev->irq))
+   if (lguest_bind_dma(peer_key(info,info->me), info->dma,
+   NUM_SKBS, lgdev_irq(info->lgdev)) != 0)
goto cleanup;
return 0;
 
@@ -246,13 +249,13 @@ static int lguestnet_close(struct net_de
 static int lguestnet_close(struct net_device *dev)
 {
unsigned int i;
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
 
/* Clear all trace: others might deliver packets, we'll ignore it. */
memset(&info->peer[info->me], 0, sizeof(info->peer[info->me]));
 
/* Deregister sg lists. */
-   hcall(LHCALL_BIND_DMA, peer_key(info, info->me), __pa(info->dma), 0);
+   lguest_unbind_dma(peer_key(info, info->me), info->dma);
for (i = 0; i < ARRAY_SIZE(info->dma); i++)
dev_kfree_skb(info->skb[i]);
return 0;
@@ -290,30 +293,34 @@ static int lguestnet_probe(struct lguest
/* Turning on/off promisc will call dev->set_multicast_list.
 * We don't actually support multicast yet */
dev->set_multicast_list = lguestnet_set_multicast;
-   dev->mem_start = ((unsigned long)desc->pfn << PAGE_SHIFT);
-   dev->mem_end = dev->me

[PATCH 1/5] lguest host feedback tidyups

2007-05-10 Thread Rusty Russell
1) Sam Ravnborg says lg-objs is deprecated, use lg-y.
2) Sparse: page_tables.c unnecessary initialization
3) Lots of __force to shut sparse up: guest "physical" addresses are
   userspace virtual.
4) Change prototype of run_lguest and do cast in caller instead (when we add
   __iomem to cast, it runs over another line).

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 drivers/lguest/Makefile   |2 +-
 drivers/lguest/core.c |   16 
 drivers/lguest/hypercalls.c   |3 ++-
 drivers/lguest/interrupts_and_traps.c |4 ++--
 drivers/lguest/lg.h   |2 +-
 drivers/lguest/lguest_user.c  |2 +-
 drivers/lguest/page_tables.c  |2 +-
 7 files changed, 16 insertions(+), 15 deletions(-)

===
--- a/drivers/lguest/Makefile
+++ b/drivers/lguest/Makefile
@@ -3,5 +3,5 @@ obj-$(CONFIG_LGUEST_GUEST) += lguest.o l
 
 # Host requires the other files, which can be a module.
 obj-$(CONFIG_LGUEST)   += lg.o
-lg-objs := core.o hypercalls.o page_tables.o interrupts_and_traps.o \
+lg-y := core.o hypercalls.o page_tables.o interrupts_and_traps.o \
segments.o io.o lguest_user.o switcher.o
===
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -218,7 +218,7 @@ u32 lgread_u32(struct lguest *lg, u32 ad
 
/* Don't let them access lguest binary */
if (!lguest_address_ok(lg, addr, sizeof(val))
-   || get_user(val, (u32 __user *)addr) != 0)
+   || get_user(val, (__force u32 __user *)addr) != 0)
kill_guest(lg, "bad read address %u", addr);
return val;
 }
@@ -226,14 +226,14 @@ void lgwrite_u32(struct lguest *lg, u32 
 void lgwrite_u32(struct lguest *lg, u32 addr, u32 val)
 {
if (!lguest_address_ok(lg, addr, sizeof(val))
-   || put_user(val, (u32 __user *)addr) != 0)
+   || put_user(val, (__force u32 __user *)addr) != 0)
kill_guest(lg, "bad write address %u", addr);
 }
 
 void lgread(struct lguest *lg, void *b, u32 addr, unsigned bytes)
 {
if (!lguest_address_ok(lg, addr, bytes)
-   || copy_from_user(b, (void __user *)addr, bytes) != 0) {
+   || copy_from_user(b, (__force void __user *)addr, bytes) != 0) {
/* copy_from_user should do this, but as we rely on it... */
memset(b, 0, bytes);
kill_guest(lg, "bad read address %u len %u", addr, bytes);
@@ -243,7 +243,7 @@ void lgwrite(struct lguest *lg, u32 addr
 void lgwrite(struct lguest *lg, u32 addr, const void *b, unsigned bytes)
 {
if (!lguest_address_ok(lg, addr, bytes)
-   || copy_to_user((void __user *)addr, b, bytes) != 0)
+   || copy_to_user((__force void __user *)addr, b, bytes) != 0)
kill_guest(lg, "bad write address %u len %u", addr, bytes);
 }
 
@@ -294,7 +294,7 @@ static void run_guest_once(struct lguest
 : "memory", "%edx", "%ecx", "%edi", "%esi");
 }
 
-int run_guest(struct lguest *lg, char *__user user)
+int run_guest(struct lguest *lg, unsigned long __user *user)
 {
while (!lg->dead) {
unsigned int cr2 = 0; /* Damn gcc */
@@ -302,8 +302,8 @@ int run_guest(struct lguest *lg, char *_
/* Hypercalls first: we might have been out to userspace */
do_hypercalls(lg);
if (lg->dma_is_pending) {
-   if (put_user(lg->pending_dma, (unsigned long *)user) ||
-   put_user(lg->pending_key, (unsigned long *)user+1))
+   if (put_user(lg->pending_dma, user) ||
+   put_user(lg->pending_key, user+1))
return -EFAULT;
return sizeof(unsigned long)*2;
}
@@ -420,7 +420,7 @@ static int __init init(void)
lock_cpu_hotplug();
if (cpu_has_pge) { /* We have a broader idea of "global". */
cpu_had_pge = 1;
-   on_each_cpu(adjust_pge, 0, 0, 1);
+   on_each_cpu(adjust_pge, (void *)0, 0, 1);
clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
}
unlock_cpu_hotplug();
===
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -83,7 +83,8 @@ static void do_hcall(struct lguest *lg, 
guest_set_pmd(lg, regs->edx, regs->ebx);
break;
case LHCALL_LOAD_TLS:
-   guest_load_tls(lg, (struct desc_struct __user*)regs->edx);
+   guest_load_tls(lg,
+  (__force struct desc_struct __user*)regs->edx);
break;
case LHCALL_TS:
lg->ts = regs->edx;
===
--- a/drivers/lguest/interrupts_and

[PATCH 0/5] lguest feedback tidyups

2007-05-10 Thread Rusty Russell
Hi all,

Gratefully-received recent feedback from CC'd was applied to excellent
effect (and the advice from Matt Mackall about my personal appearance is
best unrequited).

The patch is split in 5 parts to correspond with the 9 parts Andrew
sent out before, but here's the summary:

1) Sparse (thanks Christoph Hellwig):
- lguest_const can be static now
- lguest.c should include "lguest_bus.h" for lguest_devices declaration.
- page_tables.c unnecessary initialization
- But the cost was high: lots of __force casts 8(
2) Jeff Garzik
- Use netdev_priv instead of dev->priv.
- Check for ioremap failure
- iounmap on failure.
- Wrap SEND_DMA and BIND_DMA calls
- Don't set NETIF_F_SG unless we set NETIF_F_NO_CSUM
- Use SET_NETDEV_DEV()
- Don't set dev->irq, mem_start & mem_end (deprecated)
3) Sam Ravnborg
- lg-objs is deprecated, use lg-y.

Cheers,
Rusty.

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread David Miller
From: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
Date: Thu, 10 May 2007 15:45:42 -0700

> David Miller wrote:
> > I'm not so certain now that we know it's the jiffies wrap point :-)
> >
> > The fixes in question are attached below and they were posted and
> > discussed on netdev:
> >   
> 
> Yep, this patch gets rid of my spinning thread.  I can't find this patch
> or any discussion on marc.info; is there a better netdev list archive?

I don't see it there either... let me check my mail archive...

Indeed, they were "posted" to netdev but were blocked by the vger
regexp filters on the keyword "urgent" so that postings never made it
to the list.  I removed that filter regexp so that never happens
again, sorry.
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread Chris Wright
* Jeremy Fitzhardinge ([EMAIL PROTECTED]) wrote:
> Yep, this patch gets rid of my spinning thread.  I can't find this patch
> or any discussion on marc.info; is there a better netdev list archive?

See the "linkwatch bustage in git-net" thread on netdev

http://thread.gmane.org/gmane.linux.network/61800/focus=61812
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread Jeremy Fitzhardinge
David Miller wrote:
> I'm not so certain now that we know it's the jiffies wrap point :-)
>
> The fixes in question are attached below and they were posted and
> discussed on netdev:
>   

Yep, this patch gets rid of my spinning thread.  I can't find this patch
or any discussion on marc.info; is there a better netdev list archive?

J
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread David Miller
From: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
Date: Thu, 10 May 2007 15:22:17 -0700

> Andrew Morton wrote:
> > Five minutes after boot is when jiffies wraps.  Are you sure it's
> > a list-screwup rather than a jiffy-wrap screwup?
> >   
> 
> 
> Hm, its suggestive, isn't it?  Apparently they've already fixed this in
> the sekret networking clubhouse, so I'll need to track it down.

I'm not so certain now that we know it's the jiffies wrap point :-)

The fixes in question are attached below and they were posted and
discussed on netdev:


commit fe47cdba83b3041e4ac1aa1418431020a4afe1e0
Author: Herbert Xu <[EMAIL PROTECTED]>
Date:   Tue May 8 23:22:43 2007 -0700

[NET] link_watch: Eliminate potential delay on wrap-around

When the jiffies wrap around or when the system boots up for the first
time, down events can be delayed indefinitely since we no longer
update linkwatch_nextevent when only urgent events are processed.

This patch fixes this by setting linkwatch_nextevent when a
wrap-around occurs.

Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>
Signed-off-by: David S. Miller <[EMAIL PROTECTED]>

diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index b5f4579..4674ae5 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -101,8 +101,10 @@ static void linkwatch_schedule_work(unsigned long delay)
return;
 
/* If we wrap around we'll delay it by at most HZ. */
-   if (delay > HZ)
+   if (delay > HZ) {
+   linkwatch_nextevent = jiffies;
delay = 0;
+   }
 
schedule_delayed_work(&linkwatch_work, delay);
 }

commit 4cba637dbb9a13706494a1c85174c8e736914010
Author: Herbert Xu <[EMAIL PROTECTED]>
Date:   Wed May 9 00:17:30 2007 -0700

[NET] link_watch: Always schedule urgent events

Urgent events may be delayed if we already have a non-urgent event
queued for that device.  This patch changes this by making sure that
an urgent event is always looked at immediately.

I've replaced the LW_RUNNING flag by LW_URGENT since whether work
is scheduled is already kept track by the work queue system.

The only complication is that we have to provide some exclusion for
the setting linkwatch_nextevent which is available in the actual
work function.

Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>
Signed-off-by: David S. Miller <[EMAIL PROTECTED]>

diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 4674ae5..a5e372b 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -26,7 +26,7 @@
 
 
 enum lw_bits {
-   LW_RUNNING = 0,
+   LW_URGENT = 0,
 };
 
 static unsigned long linkwatch_flags;
@@ -95,18 +95,41 @@ static void linkwatch_add_event(struct net_device *dev)
 }
 
 
-static void linkwatch_schedule_work(unsigned long delay)
+static void linkwatch_schedule_work(int urgent)
 {
-   if (test_and_set_bit(LW_RUNNING, &linkwatch_flags))
+   unsigned long delay = linkwatch_nextevent - jiffies;
+
+   if (test_bit(LW_URGENT, &linkwatch_flags))
return;
 
-   /* If we wrap around we'll delay it by at most HZ. */
-   if (delay > HZ) {
-   linkwatch_nextevent = jiffies;
+   /* Minimise down-time: drop delay for up event. */
+   if (urgent) {
+   if (test_and_set_bit(LW_URGENT, &linkwatch_flags))
+   return;
delay = 0;
}
 
-   schedule_delayed_work(&linkwatch_work, delay);
+   /* If we wrap around we'll delay it by at most HZ. */
+   if (delay > HZ)
+   delay = 0;
+
+   /*
+* This is true if we've scheduled it immeditately or if we don't
+* need an immediate execution and it's already pending.
+*/
+   if (schedule_delayed_work(&linkwatch_work, delay) == !delay)
+   return;
+
+   /* Don't bother if there is nothing urgent. */
+   if (!test_bit(LW_URGENT, &linkwatch_flags))
+   return;
+
+   /* It's already running which is good enough. */
+   if (!cancel_delayed_work(&linkwatch_work))
+   return;
+
+   /* Otherwise we reschedule it again for immediate exection. */
+   schedule_delayed_work(&linkwatch_work, 0);
 }
 
 
@@ -123,7 +146,11 @@ static void __linkwatch_run_queue(int urgent_only)
 */
if (!urgent_only)
linkwatch_nextevent = jiffies + HZ;
-   clear_bit(LW_RUNNING, &linkwatch_flags);
+   /* Limit wrap-around effect on delay. */
+   else if (time_after(linkwatch_nextevent, jiffies + HZ))
+   linkwatch_nextevent = jiffies;
+
+   clear_bit(LW_URGENT, &linkwatch_flags);
 
spin_lock_irq(&lweventlist_lock);
next = lweventlist;
@@ -166,7 +193,7 @@ static void __linkwatch_run_queue(int urgent_only)
}
 
if (lweventlist)
-   linkwatch_schedule_work(linkwatch_nextev

Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread Jeremy Fitzhardinge
Andrew Morton wrote:
> Five minutes after boot is when jiffies wraps.  Are you sure it's
> a list-screwup rather than a jiffy-wrap screwup?
>   


Hm, its suggestive, isn't it?  Apparently they've already fixed this in
the sekret networking clubhouse, so I'll need to track it down.

J
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread Andrew Morton
On Thu, 10 May 2007 15:00:05 -0700
Jeremy Fitzhardinge <[EMAIL PROTECTED]> wrote:

> Herbert Xu wrote:
> > [NET] link_watch: Move link watch list into net_device
> >
> > These days the link watch mechanism is an integral part of the
> > network subsystem as it manages the carrier status.  So it now
> > makes sense to allocate some memory for it in net_device rather
> > than allocating it on demand.
> 
> I think there's a problem with one of these two patches.  I've been
> noticing that one of my events/X threads has been going into a spin for
> about 5 mins after boot.  I added some debugging to
> kernel/workqueue.c:run_workqueue, since its that loop which seems to be
> spinning due to list corruption.
> 
> When I look to see if that loop has iterated for more than 100 times in
> one go (which seems unlikely),  I get this:
> 
> BUG: cpu 3, count=101 list screwup on c04babe4, func c03217e8
> func=linkwatch_event+0x0/0x2a
>  [] show_trace_log_lvl+0x1a/0x30
>  [] show_trace+0x12/0x14
>  [] dump_stack+0x16/0x18
>  [] run_workqueue+0x97/0x18c
>  [] worker_thread+0xe5/0xf5
>  [] kthread+0x3b/0x62
>  [] kernel_thread_helper+0x7/0x10
>  ===
> 
> 
> I wonder if the problem is that the linkwatch_work is being rescheduled
> when its already been scheduled, or something like that?

Five minutes after boot is when jiffies wraps.  Are you sure it's
a list-screwup rather than a jiffy-wrap screwup?
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread Jeremy Fitzhardinge
David Miller wrote:
> From: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
> Date: Thu, 10 May 2007 15:00:05 -0700
>
>   
>> Herbert Xu wrote:
>> 
>>> [NET] link_watch: Move link watch list into net_device
>>>
>>> These days the link watch mechanism is an integral part of the
>>> network subsystem as it manages the carrier status.  So it now
>>> makes sense to allocate some memory for it in net_device rather
>>> than allocating it on demand.
>>>   
>> I think there's a problem with one of these two patches.
>> 
>
> Yes, there are :-)
>
> Did you catch the follow-on bug fixes?
>   

Nope.  Guess I got dropped from the cc: list.  Was this on lkml or netdev?

J

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread David Miller
From: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
Date: Thu, 10 May 2007 15:00:05 -0700

> Herbert Xu wrote:
> > [NET] link_watch: Move link watch list into net_device
> >
> > These days the link watch mechanism is an integral part of the
> > network subsystem as it manages the carrier status.  So it now
> > makes sense to allocate some memory for it in net_device rather
> > than allocating it on demand.
> 
> I think there's a problem with one of these two patches.

Yes, there are :-)

Did you catch the follow-on bug fixes?

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [1/2] [NET] link_watch: Move link watch list into net_device

2007-05-10 Thread Jeremy Fitzhardinge
Herbert Xu wrote:
> [NET] link_watch: Move link watch list into net_device
>
> These days the link watch mechanism is an integral part of the
> network subsystem as it manages the carrier status.  So it now
> makes sense to allocate some memory for it in net_device rather
> than allocating it on demand.

I think there's a problem with one of these two patches.  I've been
noticing that one of my events/X threads has been going into a spin for
about 5 mins after boot.  I added some debugging to
kernel/workqueue.c:run_workqueue, since its that loop which seems to be
spinning due to list corruption.

When I look to see if that loop has iterated for more than 100 times in
one go (which seems unlikely),  I get this:

BUG: cpu 3, count=101 list screwup on c04babe4, func c03217e8
func=linkwatch_event+0x0/0x2a
 [] show_trace_log_lvl+0x1a/0x30
 [] show_trace+0x12/0x14
 [] dump_stack+0x16/0x18
 [] run_workqueue+0x97/0x18c
 [] worker_thread+0xe5/0xf5
 [] kthread+0x3b/0x62
 [] kernel_thread_helper+0x7/0x10
 ===


I wonder if the problem is that the linkwatch_work is being rescheduled
when its already been scheduled, or something like that?

J
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [patch 8/9] lguest: the block driver

2007-05-10 Thread Rene Herman

On 05/09/2007 12:22 PM, Pekka Enberg wrote:


+static void end_entire_request(struct request *req, int uptodate)
+{
+   if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
+   BUG();
+   add_disk_randomness(req->rq_disk);
+   blkdev_dequeue_request(req);
+   end_that_request_last(req, uptodate);
+}


Again, I would prefer this went straight into block/ll_rw_blk.c. Rene
and I am using something similar in the new Mitsumi driver although
one of us has a bug already, we're using req->nr_sectors for this...


The req->hard_nr_sectors is specifically marked block layer internal and 
since nr_sectors is what we're requesting and reading (we can't deal with 
partial transfers anyway since the drive won't tell us where it failed as 
far as I've been able to see and we do want to make read requests for as 
many sectors as possible at a time for speed) I believe that in our case the 
nr_sectors is fine.


Rene.

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization


Re: [patch 7/9] lguest: the net driver

2007-05-10 Thread Rusty Russell
On Thu, 2007-05-10 at 01:33 -0400, Jeff Garzik wrote:
> Rusty Russell wrote:
> > I realize your continual battle with this, but adding a layer of
> > indirection doesn't seem like it will add clarity.  The issues with
> > __pa() are reasonably known (don't hand it a vmalloc address, for
> > example).  Any wrapper I create would be another hurdle to jump 8(
> 
> You don't want this low level stuff in drivers.
[snip answers]

Hi Jeff,

This email was illuminating, thanks.  I've put NAPI, set_mac_address
and module unload in the documentation patch for future enthusiasts.
The rest is implemented here.

Here's the extract from my current "feedback" patch:

...
2) Jeff Garzik
- Use netdev_priv instead of dev->priv.
- Check for ioremap failure
- iounmap on failure.
- Wrap SEND_DMA and BIND_DMA calls
- Don't set NETIF_F_SG unless we set NETIF_F_NO_CSUM
- Use SET_NETDEV_DEV()
- Don't set dev->irq, mem_start & mem_end (deprecated)

diff -r 35c8b37f8d3c drivers/lguest/lguest.c
--- a/drivers/lguest/lguest.c   Wed May 09 23:23:56 2007 +1000
+++ b/drivers/lguest/lguest.c   Thu May 10 20:06:25 2007 +1000
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -99,6 +100,25 @@ void async_hcall(unsigned long call,
next_call = 0;
}
local_irq_restore(flags);
+}
+
+void lguest_send_dma(unsigned long key, struct lguest_dma *dma)
+{
+   dma->used_len = 0;
+   hcall(LHCALL_SEND_DMA, key, __pa(dma), 0);
+}
+
+int lguest_bind_dma(unsigned long key, struct lguest_dma *dmas,
+   unsigned int num, u8 irq)
+{
+   if (!hcall(LHCALL_BIND_DMA, key, __pa(dmas), (num << 8) | irq))
+   return -ENOMEM;
+   return 0;
+}
+
+void lguest_unbind_dma(unsigned long key, struct lguest_dma *dmas)
+{
+   hcall(LHCALL_BIND_DMA, key, __pa(dmas), 0);
 }
 
 static unsigned long save_fl(void)
diff -r 35c8b37f8d3c drivers/net/lguest_net.c
--- a/drivers/net/lguest_net.c  Wed May 09 23:23:56 2007 +1000
+++ b/drivers/net/lguest_net.c  Thu May 10 19:30:21 2007 +1000
@@ -35,6 +35,9 @@ struct lguestnet_info
unsigned long peer_phys;
unsigned long mapsize;
 
+   /* The lguest_device I come from */
+   struct lguest_device *lgdev;
+
/* My peerid. */
unsigned int me;
 
@@ -84,7 +87,7 @@ static void skb_to_dma(const struct sk_b
 
 static void lguestnet_set_multicast(struct net_device *dev)
 {
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
 
if ((dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || dev->mc_count)
info->peer[info->me].mac[0] |= PROMISC_BIT;
@@ -110,13 +113,13 @@ static void transfer_packet(struct net_d
struct sk_buff *skb,
unsigned int peernum)
 {
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
struct lguest_dma dma;
 
skb_to_dma(skb, skb_headlen(skb), &dma);
pr_debug("xfer length %04x (%u)\n", htons(skb->len), skb->len);
 
-   hcall(LHCALL_SEND_DMA, peer_key(info,peernum), __pa(&dma), 0);
+   lguest_send_dma(peer_key(info, peernum), &dma);
if (dma.used_len != skb->len) {
dev->stats.tx_carrier_errors++;
pr_debug("Bad xfer to peer %i: %i of %i (dma %p/%i)\n",
@@ -137,7 +140,7 @@ static int lguestnet_start_xmit(struct s
 {
unsigned int i;
int broadcast;
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
 
pr_debug("%s: xmit %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -162,7 +165,7 @@ static int lguestnet_start_xmit(struct s
 /* Find a new skb to put in this slot in shared mem. */
 static int fill_slot(struct net_device *dev, unsigned int slot)
 {
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
/* Try to create and register a new one. */
info->skb[slot] = netdev_alloc_skb(dev, ETH_HLEN + ETH_DATA_LEN);
if (!info->skb[slot]) {
@@ -180,7 +183,7 @@ static irqreturn_t lguestnet_rcv(int irq
 static irqreturn_t lguestnet_rcv(int irq, void *dev_id)
 {
struct net_device *dev = dev_id;
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
unsigned int i, done = 0;
 
for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
@@ -220,7 +223,7 @@ static int lguestnet_open(struct net_dev
 static int lguestnet_open(struct net_device *dev)
 {
int i;
-   struct lguestnet_info *info = dev->priv;
+   struct lguestnet_info *info = netdev_priv(dev);
 
/* Set up our MAC address */
memcpy(info->peer[info->me].mac, dev->dev_addr, ETH_ALEN);
@@ -232,8 +235,8 @@ static int lguestnet_open(struct net_dev