Thread (24 messages) 24 messages, 3 authors, 2011-08-31

Re: [PATCH 7/7] bnx2x: expose HW RX VLAN stripping toggle

flat view

From: Vlad Zolotarov <hidden>
Date: 2011-08-31 15:08:38
Subsystem: networking drivers, networking [general], the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

On Wednesday 31 August 2011 16:53:24 Michal Schmidt wrote:
On Wed, 31 Aug 2011 15:01:39 +0300 Vlad Zolotarov wrote:
quoted
On Tuesday 30 August 2011 22:30:11 Michal Schmidt wrote:
quoted
quoted
and then also in fp->flags.  Are the
fp->flags strictly mirroring hardware state (as in: there is no
way the states can differ in any point in time where the flags are
tested)?
Yes. This is the purpose of the second mirroring of the flag.
Michal,
although the above is true i'd say it's a bit of an overkill:
RX VLAN stripping is configured in a function level, so keeping it in
a per queue level is not needed.

The problem u were trying to resolve (and u resolved it) was to
separate the RX_VLAN_ENABLED flag semantics into two: requested
feature and HW configured feature in order to further check the
second in the fast path, while setting the first one in the
set_features(). Then the second lag is updated according to the first
one during the loading of the function (bnx2x_nic_load()).

Therefore it would be enough to just add those two flags in the
function (bp) level keeping the rest of your patch as it is. This
would also cancel the need for a patch 6.
Alright, I will remove the per-fp flag and move it to bp.

I will also apply the cheat suggested by Michał, so that:
 - dev->features & NETIF_F_HW_VLAN_RX is the requested state
 - bp->flags & RX_VLAN_STRIP_FLAG is the HW configured state
=> Only one new bp flag needed, not two.

BTW, Michał's cheat should apply to TPA_ENABLE_FLAG as well - it only
mirrors NETIF_F_LRO. But for TPA the HW configured state is really
per-queue (fp->disable_tpa). I will remove TPA_ENABLE_FLAG unless you
object to Michał's "cheat".
I agree the TPA_ENABLE_FLAG may and should be removed.
However I didn’t like the idea of relying on the current implementation 
of the calling function (__netdev_update_features()). If u want to change 
the implementation the way we rely on the dev->features in the 
ndo_set_features() flow, which is a semantics change, u'd rather change 
the __netdev_update_features() so that it sets the dev->features before 
ndo_set_features() call and restores it in case of a failure. Something like this:
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0a7f619..a5f6d3e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -943,8 +943,7 @@ struct net_device_ops {
                                                 struct net_device *slave_dev);
        u32                     (*ndo_fix_features)(struct net_device *dev,
                                                    u32 features);
-       int                     (*ndo_set_features)(struct net_device *dev,
-                                                   u32 features);
+       int                     (*ndo_set_features)(struct net_device *dev);
 };
 
 /*
diff --git a/net/core/dev.c b/net/core/dev.c
index b2e262e..474e539 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5321,7 +5321,7 @@ static u32 netdev_fix_features(struct net_device *dev, u32 features)
 
 int __netdev_update_features(struct net_device *dev)
 {
-       u32 features;
+       u32 features, old_features;
        int err = 0;
 
        ASSERT_RTNL();
@@ -5340,19 +5340,23 @@ int __netdev_update_features(struct net_device *dev)
        netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n",
                dev->features, features);
 
+       /* Remember the original features and set the new ones */
+       old_features = dev->features;
+       dev->features = features;
+
        if (dev->netdev_ops->ndo_set_features)
-               err = dev->netdev_ops->ndo_set_features(dev, features);
+               err = dev->netdev_ops->ndo_set_features(dev);
 
        if (unlikely(err < 0)) {
+               /* Restore the original features */
+               dev->features = old_features;
+
                netdev_err(dev,
                        "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
                        err, features, dev->features);
                return -1;
        }
 
-       if (!err)
-               dev->features = features;
-
        return 1;
 }
However, this would involve updating all other L2 drivers that implement ndo_set_features().

Pls., comment.

thanks,
vlad
Thanks,
Michal
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help