Re: [PATCH 2/2] NET: Multiqueue network device support implementation.

2007-04-10 Thread Evgeniy Polyakov
On Tue, Apr 10, 2007 at 08:41:49AM -0700, Waskiewicz Jr, Peter P ([EMAIL 
PROTECTED]) wrote:
> > On Mon, Apr 09, 2007 at 02:28:41PM -0700, Peter P Waskiewicz 
> > Jr ([EMAIL PROTECTED]) wrote:
> > > + alloc_size = (sizeof(struct net_device_subqueue) * queue_count);
> > > + 
> > > + p = kzalloc(alloc_size, GFP_KERNEL);
> > > + if (!p) {
> > > + printk(KERN_ERR "alloc_netdev: Unable to 
> > allocate queues.\n");
> > > + return NULL;
> > 
> > I think you either do not want to print it, or want 
> > additional details about device...
> 
> Ok.  This is essentially the same output printed if the netdev itself
> cannot be allocated.  Should I update both strings to have more
> device-specific information?

I wonder, if it is ever possible with gfp_kernel...

I think different patch would be ok.

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 2/2] NET: Multiqueue network device support implementation.

2007-04-10 Thread Waskiewicz Jr, Peter P
> On Mon, Apr 09, 2007 at 02:28:41PM -0700, Peter P Waskiewicz 
> Jr ([EMAIL PROTECTED]) wrote:
> > +   alloc_size = (sizeof(struct net_device_subqueue) * queue_count);
> > + 
> > +   p = kzalloc(alloc_size, GFP_KERNEL);
> > +   if (!p) {
> > +   printk(KERN_ERR "alloc_netdev: Unable to 
> allocate queues.\n");
> > +   return NULL;
> 
> I think you either do not want to print it, or want 
> additional details about device...

Ok.  This is essentially the same output printed if the netdev itself
cannot be allocated.  Should I update both strings to have more
device-specific information?

> 
> > +   }
> > + 
> > +   dev->egress_subqueue = p;
> > +   dev->egress_subqueue_count = queue_count;
> > +
> > dev->get_stats = maybe_internal_stats;
> > setup(dev);
> > strcpy(dev->name, name);
> > return dev;
> >  }
> > -EXPORT_SYMBOL(alloc_netdev);
> > +EXPORT_SYMBOL(alloc_netdev_mq);
> >  
> >  /**
> >   * free_netdev - free network device
> > @@ -3345,6 +3358,7 @@ void free_netdev(struct net_device *dev)  {  
> > #ifdef CONFIG_SYSFS
> > /*  Compatibility with error handling in drivers */
> > +   kfree((char *)dev->egress_subqueue);
> > if (dev->reg_state == NETREG_UNINITIALIZED) {
> > kfree((char *)dev - dev->padded);
> > return;
> > @@ -3356,6 +3370,7 @@ void free_netdev(struct net_device *dev)
> > /* will free via device release */
> > put_device(&dev->dev);
> >  #else
> > +   kfree((char *)dev->egress_subqueue);
> 
> Still casting :)

The latest repost removes these casts.


Thanks for the feedback,

-PJ Waskiewicz
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] NET: Multiqueue network device support implementation.

2007-04-10 Thread Herbert Xu
Waskiewicz Jr, Peter P <[EMAIL PROTECTED]> wrote:
>
>> >@@ -3356,6 +3370,7 @@ void free_netdev(struct net_device *dev)
>> > /* will free via device release */
>> > put_device(&dev->dev);
>> > #else
>> >+kfree((char *)dev->egress_subqueue);
>> > kfree((char *)dev - dev->padded);
>> > #endif
>> > }
>> 
>> Ahem. Explain that cast.
> 
>This can be removed if needed; however, I'm just copying what
> the other kfree()'s are doing in this function.  Any instance of a
> typecast that I introduced in these patches are just following what
> others have done in that section of the code.  So the cast is just for
> consistency in this particular area.  If you'd like me to remove it, I
> can do that.

The other cast is there for the subtraction, not the kfree...

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] NET: Multiqueue network device support implementation.

2007-04-10 Thread Evgeniy Polyakov
On Mon, Apr 09, 2007 at 02:28:41PM -0700, Peter P Waskiewicz Jr ([EMAIL 
PROTECTED]) wrote:
> + alloc_size = (sizeof(struct net_device_subqueue) * queue_count);
> + 
> + p = kzalloc(alloc_size, GFP_KERNEL);
> + if (!p) {
> + printk(KERN_ERR "alloc_netdev: Unable to allocate queues.\n");
> + return NULL;

I think you either do not want to print it, or want additional details
about device...

> + }
> + 
> + dev->egress_subqueue = p;
> + dev->egress_subqueue_count = queue_count;
> +
>   dev->get_stats = maybe_internal_stats;
>   setup(dev);
>   strcpy(dev->name, name);
>   return dev;
>  }
> -EXPORT_SYMBOL(alloc_netdev);
> +EXPORT_SYMBOL(alloc_netdev_mq);
>  
>  /**
>   *   free_netdev - free network device
> @@ -3345,6 +3358,7 @@ void free_netdev(struct net_device *dev)
>  {
>  #ifdef CONFIG_SYSFS
>   /*  Compatibility with error handling in drivers */
> + kfree((char *)dev->egress_subqueue);
>   if (dev->reg_state == NETREG_UNINITIALIZED) {
>   kfree((char *)dev - dev->padded);
>   return;
> @@ -3356,6 +3370,7 @@ void free_netdev(struct net_device *dev)
>   /* will free via device release */
>   put_device(&dev->dev);
>  #else
> + kfree((char *)dev->egress_subqueue);

Still casting :)


-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 2/2] NET: Multiqueue network device support implementation.

2007-04-09 Thread Waskiewicz Jr, Peter P
> Hi,
> 
> 
> On Apr 9 2007 14:28, Peter P Waskiewicz Jr wrote:
> >@@ -3345,6 +3358,7 @@ void free_netdev(struct net_device *dev)  {  
> >#ifdef CONFIG_SYSFS
> > /*  Compatibility with error handling in drivers */
> >+kfree((char *)dev->egress_subqueue);
> > if (dev->reg_state == NETREG_UNINITIALIZED) {
> > kfree((char *)dev - dev->padded);
> > return;
> >@@ -3356,6 +3370,7 @@ void free_netdev(struct net_device *dev)
> > /* will free via device release */
> > put_device(&dev->dev);
> > #else
> >+kfree((char *)dev->egress_subqueue);
> > kfree((char *)dev - dev->padded);
> > #endif
> > }
> 
> Ahem. Explain that cast.

Jan,
This can be removed if needed; however, I'm just copying what
the other kfree()'s are doing in this function.  Any instance of a
typecast that I introduced in these patches are just following what
others have done in that section of the code.  So the cast is just for
consistency in this particular area.  If you'd like me to remove it, I
can do that.

Thanks,

-PJ Waskiewicz
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] NET: Multiqueue network device support implementation.

2007-04-09 Thread Jan Engelhardt
Hi,


On Apr 9 2007 14:28, Peter P Waskiewicz Jr wrote:
>@@ -3345,6 +3358,7 @@ void free_netdev(struct net_device *dev)
> {
> #ifdef CONFIG_SYSFS
>   /*  Compatibility with error handling in drivers */
>+  kfree((char *)dev->egress_subqueue);
>   if (dev->reg_state == NETREG_UNINITIALIZED) {
>   kfree((char *)dev - dev->padded);
>   return;
>@@ -3356,6 +3370,7 @@ void free_netdev(struct net_device *dev)
>   /* will free via device release */
>   put_device(&dev->dev);
> #else
>+  kfree((char *)dev->egress_subqueue);
>   kfree((char *)dev - dev->padded);
> #endif
> }

Ahem. Explain that cast.



Jan
-- 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] NET: Multiqueue network device support implementation.

2007-04-09 Thread Peter P Waskiewicz Jr
From: Peter P Waskiewicz Jr <[EMAIL PROTECTED]>

Added an API and associated supporting routines for multiqueue network devices.
This allows network devices supporting multiple TX queues to configure each
queue within the netdevice and manage each queue independantly.  Changes to the
PRIO Qdisc also allow a user to map multiple flows to individual TX queues,
taking advantage of each queue on the device.

Removed typecast when assigning net_device_subqueue in alloc_etherdev_mq.

Signed-off-by: Peter P. Waskiewicz Jr <[EMAIL PROTECTED]>
Signed-off-by: Auke Kok <[EMAIL PROTECTED]>
---

 include/linux/etherdevice.h |3 +-
 include/linux/netdevice.h   |   66 ++-
 include/linux/skbuff.h  |2 +
 net/core/dev.c  |   25 +---
 net/core/skbuff.c   |3 ++
 net/ethernet/eth.c  |9 +++---
 net/sched/sch_generic.c |4 +--
 net/sched/sch_prio.c|   55 +++-
 8 files changed, 146 insertions(+), 21 deletions(-)

diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 745c988..446de39 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -39,7 +39,8 @@ extern void   eth_header_cache_update(struct hh_cache 
*hh, struct net_device *dev
 extern int eth_header_cache(struct neighbour *neigh,
 struct hh_cache *hh);
 
-extern struct net_device *alloc_etherdev(int sizeof_priv);
+extern struct net_device *alloc_etherdev_mq(int sizeof_priv, int queue_count);
+#define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
 static inline void eth_copy_and_sum (struct sk_buff *dest, 
 const unsigned char *src, 
 int len, int base)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 71fc8ff..db06169 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -106,6 +106,14 @@ struct netpoll_info;
 #define MAX_HEADER (LL_MAX_HEADER + 48)
 #endif
 
+struct net_device_subqueue
+{
+   /* Give a control state for each queue.  This struct may contain
+* per-queue locks in the future.
+*/
+   unsigned long   state;
+};
+
 /*
  * Network device statistics. Akin to the 2.0 ether stats but
  * with byte counters.
@@ -324,6 +332,7 @@ struct net_device
 #define NETIF_F_GSO2048/* Enable software GSO. */
 #define NETIF_F_LLTX   4096/* LockLess TX */
 #define NETIF_F_INTERNAL_STATS 8192/* Use stats structure in net_device */
+#define NETIF_F_MULTI_QUEUE16384   /* Has multiple TX/RX queues */
 
/* Segmentation offload features */
 #define NETIF_F_GSO_SHIFT  16
@@ -534,6 +543,14 @@ struct net_device
struct device   dev;
/* space for optional statistics and wireless sysfs groups */
struct attribute_group  *sysfs_groups[3];
+
+   /* To retrieve statistics per subqueue - FOR FUTURE USE */
+   struct net_device_stats* (*get_subqueue_stats)(struct net_device *dev,
+   int queue_index);
+
+   /* The TX queue control structures */
+   struct net_device_subqueue  *egress_subqueue;
+   int egress_subqueue_count;
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
@@ -675,6 +692,48 @@ static inline int netif_running(const struct net_device 
*dev)
return test_bit(__LINK_STATE_START, &dev->state);
 }
 
+/*
+ * Routines to manage the subqueues on a device.  We only need start
+ * stop, and a check if it's stopped.  All other device management is
+ * done at the overall netdevice level.
+ * Also test the device if we're multiqueue.
+ */
+static inline void netif_start_subqueue(struct net_device *dev, u16 
queue_index)
+{
+   clear_bit(__LINK_STATE_XOFF, &dev->egress_subqueue[queue_index].state);
+}
+
+static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETPOLL_TRAP
+   if (netpoll_trap())
+   return;
+#endif
+   set_bit(__LINK_STATE_XOFF, &dev->egress_subqueue[queue_index].state);
+}
+
+static inline int netif_subqueue_stopped(const struct net_device *dev,
+ u16 queue_index)
+{
+   return test_bit(__LINK_STATE_XOFF,
+   &dev->egress_subqueue[queue_index].state);
+}
+
+static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETPOLL_TRAP
+   if (netpoll_trap())
+   return;
+#endif
+   if (test_and_clear_bit(__LINK_STATE_XOFF,
+  &dev->egress_subqueue[queue_index].state))
+   __netif_schedule(dev);
+}
+
+static inline int netif_is_multiqueue(const struct net_device *dev)
+{
+   return (!!(NETIF_F_MULTI_QUEUE & dev->features));
+}
 
 /* Use this va