From: Nikolay Aleksandrov <nikolay@redhat.com>
To: Veaceslav Falico <vfalico@redhat.com>
Cc: netdev@vger.kernel.org, Patrick McHardy <kaber@trash.net>,
"David S. Miller" <davem@davemloft.net>
Subject: Re: [PATCH v2 net-next 2/6] vlan: add __vlan_find_dev_next()
Date: Fri, 09 Aug 2013 13:07:31 +0200 [thread overview]
Message-ID: <5204CD73.9010309@redhat.com> (raw)
In-Reply-To: <1375981079-2936-3-git-send-email-vfalico@redhat.com>
On 08/08/2013 06:57 PM, Veaceslav Falico wrote:
> RFC -> v1: make the function accept/return vlan's net_device, this way we
> won't have troubles with VLAN 0, and the user code will be
> cleaner and faster.
> v1 -> v2: don't check for the master device - if we'll want in the future
> to convert a slave device - it will fail, but now we don't
> actually care.
>
> Add a new exported function __vlan_find_dev_next(dev, vlan_dev), which
> returns the a vlan's net_device that is used by the dev and is its id is
> greater or equal to vlan_dev's vlan id. If vlan_dev is NULL, return first
> vlan, if nothing is found return NULL.
>
> This function must be under rcu_read_lock(), is aware of master devices and
> doesn't guarantee that, once it returns, the vlan dev will still be used by
> dev as its vlan.
>
> It's basically a helper for "for_each_vlan_in_dev(dev, vlan_dev)" logic,
> and is supposed to be used like this:
>
> vlan_dev = NULL;
>
> while ((vlan_dev = __vlan_find_dev_next(dev, vlan_dev))) {
> if (!vlan_dev)
> continue;
>
> do_work(vlan_dev);
> }
>
> In that case we're sure that vlan_dev at least was used as a vlan, and won't
> go away while we're holding rcu_read_lock().
>
> However, if we don't hold rtnl_lock(), we can't be sure that that vlan_dev
> is still in dev's vlan_list.
>
> CC: Patrick McHardy <kaber@trash.net>
> CC: "David S. Miller" <davem@davemloft.net>
> Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
> ---
We already discussed privately my comments about this new function, I'll leave
them here just for the sake of having them documented:
My proposition is to drop these changes altogether (the new function, and the
vlan.h macro change) and instead add something like the following (I haven't
tested it, it's only to illustrate the idea) in if_vlan.h so it'll be accessible
to everyone:
Version 1 (circular so you can simplify the bonding ALB code, I haven't left
spaces because of auto-wrapping):
#define dev_for_each_vlan_from(dev, vlandev, proto, from, i)
for (i=from+1, vlandev=__vlan_find_dev_deep(dev, proto, from); \
i!=from; \
i=(i+1)%VLAN_N_VID, vlandev=__vlan_find_dev_deep(dev, proto, i)) \
if (vlandev)
#define dev_for_each_vlan(dev, vlandev, proto, i)
dev_for_each_vlan_from(dev, vlandev, proto, 0, i)
Version 2 is the same but a little shorter, without the circular part.
This way you reuse the already provided function __vlan_find_dev_deep and the
churn is smaller, also __vlan_find_dev_deep takes care of the master issue (that
is if dev doesn't have a vlan_info, then its master's vlan_info will be used).
Also the code will look much nicer IMO changing this:
while ((vlan_dev = __vlan_find_dev_next))
to
dev_for_each_vlan(dev, vlan_dev, proto, i)
There're also 2 nice side-effects, first you'll only walk over 4096 entries (for
the specified vlan proto only) and the bonding ALB code will simplify from the
ambiguous looking:
vlan_id = bond->alb_info.current_alb_vlan;
vlan_dev = __vlan_find_dev_deep(bond->dev,
htons(ETH_P_8021Q),
vlan_id);
/* search for the next one, if not found - for any */
if (vlan_dev)
vlan_dev = __vlan_find_dev_next(bond->dev,
vlan_dev);
if (!vlan_dev)
vlan_dev = __vlan_find_dev_next(bond->dev,
NULL);
if (vlan_dev) {
vlan_id = vlan_dev_vlan_id(vlan_dev);
bond->alb_info.current_alb_vlan = vlan_id;
} else {
bond->alb_info.current_alb_vlan = 0;
rcu_read_unlock();
kfree_skb(skb);
continue;
}
to something like (again untested, sorry for the style - line wrapping):
vlan_id = bond->alb_info.current_alb_vlan+1;
/* since from here is current+1, if there aren't any
* vlans up to current, it'll get current again if it's
* available
*/
dev_for_each_vlan_from(bond->dev, vlan_dev, htons(ETH_P_8021Q), vlan_id, i)
break;
if (vlan_dev) {
vlan_id = vlan_dev_vlan_id(vlan_dev);
bond->alb_info.current_alb_vlan = vlan_id;
} else {
bond->alb_info.current_alb_vlan = 0;
rcu_read_unlock();
kfree_skb(skb);
continue;
}
Cheers,
Nik
next prev parent reply other threads:[~2013-08-09 11:11 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-08 16:57 [PATCH net-next v2 0/6] bonding: remove bond->vlan_list Veaceslav Falico
2013-08-08 16:57 ` [PATCH v2 net-next 1/6] bonding: add rcu to vlan_uses_dev() and make bond_vlan_used() use it Veaceslav Falico
2013-08-09 11:06 ` Nikolay Aleksandrov
2013-08-09 11:11 ` Veaceslav Falico
2013-08-08 16:57 ` [PATCH v2 net-next 2/6] vlan: add __vlan_find_dev_next() Veaceslav Falico
2013-08-09 7:30 ` Veaceslav Falico
2013-08-09 11:07 ` Nikolay Aleksandrov [this message]
2013-08-14 15:28 ` Veaceslav Falico
2013-08-08 16:57 ` [PATCH v2 net-next 3/6] bonding: make bond_alb use 8021q's dev->vlan_info instead of vlan_list Veaceslav Falico
2013-08-09 11:13 ` Nikolay Aleksandrov
2013-08-09 11:24 ` Veaceslav Falico
2013-08-08 16:57 ` [PATCH v2 net-next 4/6] bonding: convert bond_has_this_ip to use bond->dev->vlan_info Veaceslav Falico
2013-08-08 16:57 ` [PATCH v2 net-next 5/6] bonding: convert bond_arp_send_all " Veaceslav Falico
2013-08-09 11:42 ` Nikolay Aleksandrov
2013-08-08 16:57 ` [PATCH v2 net-next 6/6] bonding: remove unused bond->vlan_list Veaceslav Falico
2013-08-09 11:44 ` Nikolay Aleksandrov
2013-08-26 16:31 ` [PATCH net-next v2 0/6] bonding: remove bond->vlan_list Veaceslav Falico
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=5204CD73.9010309@redhat.com \
--to=nikolay@redhat.com \
--cc=davem@davemloft.net \
--cc=kaber@trash.net \
--cc=netdev@vger.kernel.org \
--cc=vfalico@redhat.com \
/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).