From: ebiederm@xmission.com (Eric W. Biederman)
To: Andrey Savochkin <saw@swsoft.com>
Cc: dlezcano@fr.ibm.com, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, serue@us.ibm.com, haveblue@us.ibm.com,
clg@fr.ibm.com, Andrew Morton <akpm@osdl.org>,
dev@sw.ru, herbert@13thfloor.at, devel@openvz.org,
sam@vilain.net, viro@ftp.linux.org.uk
Subject: Re: [RFC][patch 1/4] Network namespaces: cleanup of dev_base list use
Date: Mon, 26 Jun 2006 09:13:52 -0600 [thread overview]
Message-ID: <m1odwguez3.fsf@ebiederm.dsl.xmission.com> (raw)
In-Reply-To: <20060626134945.A28942@castle.nmd.msu.ru> (Andrey Savochkin's message of "Mon, 26 Jun 2006 13:49:45 +0400")
Andrey Savochkin <saw@swsoft.com> writes:
> Cleanup of dev_base list use, with the aim to make device list per-namespace.
> In almost every occasion, use of dev_base variable and dev->next pointer
> could be easily replaced by for_each_netdev loop.
> A few most complicated places were converted to using
> first_netdev()/next_netdev().
As a proof of concept patch this is ok.
As a real world patch this is much too big, which prevents review.
Plus it takes a few actions that are more than replace just
iterators through the device list.
In addition I suspect several if not all of these iterators
can be replaced with the an appropriate helper function.
The normal structure for a patch like this would be to
introduce the new helper function. for_each_netdev.
And then to replace all of the users while cc'ing the
maintainers of those drivers. With each different
driver being a different patch.
There is another topic for discussion in this patch as well.
How much of the context should be implicit and how much
should be explicit.
If the changes from netchannels had already been implemented, and all of
the network processing was happening in a process context then I would
trivially agree that implicit would be the way to go.
However short of always having code always execute in the proper
context I'm not comfortable with implicit parameters to functions.
Not that this the contents of this patch should address this but the
later patches should.
When I went through this, my patchset just added an explicit
continue if the devices was not in the appropriate namespace.
I actually prefer the multiple list implementation but at
the same time I think it is harder to get a clean implementation
out of it.
Eric
> --- ./drivers/block/aoe/aoecmd.c.vedevbase Wed Jun 21 18:50:28 2006
> +++ ./drivers/block/aoe/aoecmd.c Thu Jun 22 12:03:07 2006
> @@ -204,14 +204,17 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigne
> sl = sl_tail = NULL;
>
> read_lock(&dev_base_lock);
> - for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
> + for_each_netdev(dev) {
> dev_hold(ifp);
> - if (!is_aoe_netif(ifp))
> + if (!is_aoe_netif(ifp)) {
> + dev_put(ifp);
> continue;
> + }
>
> skb = new_skb(ifp, sizeof *h + sizeof *ch);
> if (skb == NULL) {
> printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc
> failure\n");
> + dev_put(ifp);
> continue;
> }
> if (sl_tail == NULL)
> @@ -229,6 +232,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigne
>
> skb->next = sl;
> sl = skb;
> + dev_put(ifp);
> }
> read_unlock(&dev_base_lock);
These hunks should use for_each_netdev(ifp);
> --- ./include/linux/netdevice.h.vedevbase Wed Jun 21 18:53:17 2006
> +++ ./include/linux/netdevice.h Thu Jun 22 18:57:50 2006
> @@ -289,8 +289,8 @@ struct net_device
>
> unsigned long state;
>
> - struct net_device *next;
> -
> + struct list_head dev_list;
> +
> /* The device initialization function. Called only once. */
> int (*init)(struct net_device *dev);
>
> @@ -543,9 +543,27 @@ struct packet_type {
> #include <linux/interrupt.h>
> #include <linux/notifier.h>
>
> -extern struct net_device loopback_dev; /* The loopback */
> -extern struct net_device *dev_base; /* All devices */
> -extern rwlock_t dev_base_lock; /* Device list lock */
> +extern struct net_device loopback_dev; /* The loopback */
> +extern struct list_head dev_base_head; /* All devices */
> +extern rwlock_t dev_base_lock; /* Device list lock */
> +
No need to change the loopback_dev and dev_base_lock here.
What is the advantage of changing the type of dev_base?
I can guess but there should be an explanation of it.
> +#define for_each_netdev(p) list_for_each_entry(p, &dev_base_head, dev_list)
> +
> +/* DO NOT USE first_netdev/next_netdev, use loop defined above */
> +#define first_netdev() ({ \
> + list_empty(&dev_base_head) ? NULL : \
> + list_entry(dev_base_head.next, \
> + struct net_device, \
> + dev_list); \
> + })
> +#define next_netdev(dev) ({ \
> + struct list_head *__next; \
> + __next = (dev)->dev_list.next; \
> + __next == &dev_base_head ? NULL : \
> + list_entry(__next, \
> + struct net_device, \
> + dev_list); \
> + })
>
> extern int netdev_boot_setup_check(struct net_device *dev);
> extern unsigned long netdev_boot_base(const char *prefix, int unit);
> @@ -1903,7 +1902,7 @@ static int dev_ifconf(char __user *arg)
> */
>
> total = 0;
> - for (dev = dev_base; dev; dev = dev->next) {
> + for_each_netdev(dev) {
> for (i = 0; i < NPROTO; i++) {
> if (gifconf_list[i]) {
> int done;
> @@ -1935,26 +1934,25 @@ static int dev_ifconf(char __user *arg)
Hmm. The proc code here appears to be more than non-trivial
restructuring. I'm not certain it is but it looks that way
which make review harder.
> * This is invoked by the /proc filesystem handler to display a device
> * in detail.
> */
> -static __inline__ struct net_device *dev_get_idx(loff_t pos)
> -{
> - struct net_device *dev;
> - loff_t i;
> -
> - for (i = 0, dev = dev_base; dev && i < pos; ++i, dev = dev->next);
> -
> - return i == pos ? dev : NULL;
> -}
> -
> void *dev_seq_start(struct seq_file *seq, loff_t *pos)
> {
> + struct net_device *dev;
> + loff_t off = 1;
> read_lock(&dev_base_lock);
> - return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN;
> + if (!*pos)
> + return SEQ_START_TOKEN;
> + for_each_netdev(dev) {
> + if (off++ == *pos)
> + return dev;
> + }
> + return NULL;
> }
>
> void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
> {
> + struct net_device *dev = v;
> ++*pos;
> - return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next;
> + return v == SEQ_START_TOKEN ? first_netdev() : next_netdev(dev);
> }
>
> void dev_seq_stop(struct seq_file *seq, void *v)
next prev parent reply other threads:[~2006-06-26 15:15 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-06-26 9:49 [patch 1/4] Network namespaces: cleanup of dev_base list use Andrey Savochkin
2006-06-26 9:52 ` [patch 2/4] " Andrey Savochkin
2006-06-26 9:54 ` [patch 3/4] Network namespaces: IPv4 FIB/routing in namespaces Andrey Savochkin
2006-06-26 9:55 ` [patch 4/4] Network namespaces: playing and debugging Andrey Savochkin
2006-06-26 15:04 ` Daniel Lezcano
2006-06-26 15:43 ` Andrey Savochkin
2006-06-26 17:29 ` Daniel Lezcano
2006-06-26 19:34 ` Andrey Savochkin
2006-06-26 14:56 ` [patch 3/4] Network namespaces: IPv4 FIB/routing in namespaces Daniel Lezcano
2006-06-26 15:46 ` Andrey Savochkin
2006-06-26 15:57 ` Daniel Lezcano
2006-06-26 19:39 ` Andrey Savochkin
2006-06-26 20:05 ` Herbert Poetzl
2006-06-27 9:25 ` Andrey Savochkin
2006-06-28 13:51 ` Daniel Lezcano
2006-06-28 14:19 ` Herbert Poetzl
2006-06-28 14:30 ` Andrey Savochkin
2006-06-28 14:34 ` Kirill Korotaev
2006-06-28 16:56 ` Daniel Lezcano
2006-06-28 17:10 ` Ben Greear
2006-06-28 15:05 ` Eric W. Biederman
2006-06-26 15:13 ` Eric W. Biederman [this message]
2006-06-26 15:42 ` [patch 1/4] Network namespaces: cleanup of dev_base list use Andrey Savochkin
2006-06-26 16:26 ` Eric W. Biederman
2006-06-26 20:14 ` Andrey Savochkin
2006-06-26 21:02 ` Eric W. Biederman
2006-06-27 6:59 ` [RFC][patch " Kirill Korotaev
2006-06-27 11:13 ` Eric W. Biederman
2006-06-27 15:08 ` Kirill Korotaev
2006-06-27 15:26 ` Serge E. Hallyn
2006-06-27 16:54 ` Eric W. Biederman
2006-06-27 17:20 ` [RFC] Network namespaces a path to mergable code Eric W. Biederman
2006-06-27 17:58 ` Andrey Savochkin
2006-06-27 22:20 ` Sam Vilain
2006-06-28 4:33 ` Eric W. Biederman
2006-06-28 5:59 ` Abdallah Chatila
2006-06-28 6:19 ` Sam Vilain
2006-06-28 6:55 ` Eric W. Biederman
2006-06-28 9:54 ` Cedric Le Goater
2006-06-28 14:03 ` Eric W. Biederman
2006-06-28 14:15 ` Serge E. Hallyn
2006-06-28 14:56 ` Eric W. Biederman
2006-06-28 4:20 ` Eric W. Biederman
2006-06-28 11:06 ` Andrey Savochkin
2006-06-28 16:51 ` Eric W. Biederman
2006-06-28 17:22 ` Andrey Savochkin
2006-06-28 17:40 ` Herbert Poetzl
2006-06-28 17:50 ` Eric W. Biederman
2006-06-28 18:11 ` Eric W. Biederman
2006-06-28 18:14 ` Eric W. Biederman
2006-06-28 18:51 ` Andrey Savochkin
2006-06-28 21:53 ` Daniel Lezcano
2006-06-28 22:54 ` James Morris
2006-06-29 0:19 ` Eric W. Biederman
2006-06-29 0:25 ` Eric W. Biederman
2006-06-29 9:42 ` Daniel Lezcano
2006-06-28 10:20 ` [RFC] " Cedric Le Goater
2006-06-28 15:20 ` Eric W. Biederman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m1odwguez3.fsf@ebiederm.dsl.xmission.com \
--to=ebiederm@xmission.com \
--cc=akpm@osdl.org \
--cc=clg@fr.ibm.com \
--cc=dev@sw.ru \
--cc=devel@openvz.org \
--cc=dlezcano@fr.ibm.com \
--cc=haveblue@us.ibm.com \
--cc=herbert@13thfloor.at \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=sam@vilain.net \
--cc=saw@swsoft.com \
--cc=serue@us.ibm.com \
--cc=viro@ftp.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).