On Mon, Jan 09, 2017 at 11:45:02AM -0800, Florian Fainelli wrote:
> Add switchdev_port_bridge_getlink_deferred() which does a deferred
> object dump operation, this is required for e.g: DSA switches which
> typically have sleeping I/O operations which is incompatible with being
> in atomic context obviously.
> 
> Signed-off-by: Florian Fainelli <f.faine...@gmail.com>
> ---
>  include/net/switchdev.h   |  3 ++
>  net/switchdev/switchdev.c | 79 
> ++++++++++++++++++++++++++++++++++++++---------
>  2 files changed, 67 insertions(+), 15 deletions(-)
> 
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index eba80c4fc56f..087761b0df49 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -189,6 +189,9 @@ int call_switchdev_notifiers(unsigned long val, struct 
> net_device *dev,
>  int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
>                                 struct net_device *dev, u32 filter_mask,
>                                 int nlflags);
> +int switchdev_port_bridge_getlink_deferred(struct sk_buff *skb, u32 pid,
> +                                        u32 seq, struct net_device *dev,
> +                                        u32 filter_mask, int nlflags);
>  int switchdev_port_bridge_setlink(struct net_device *dev,
>                                 struct nlmsghdr *nlh, u16 flags);
>  int switchdev_port_bridge_dellink(struct net_device *dev,
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> index 4fa9972d72d2..ab614a9dd872 100644
> --- a/net/switchdev/switchdev.c
> +++ b/net/switchdev/switchdev.c
> @@ -776,12 +776,14 @@ static int switchdev_port_vlan_dump_cb(struct 
> switchdev_obj *obj)
>       return err;
>  }
>  
> -static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device 
> *dev,
> -                                 u32 filter_mask)
> +static int __switchdev_port_vlan_fill(struct sk_buff *skb,
> +                                   struct net_device *dev,
> +                                   u32 filter_mask, u32 obj_flags)
>  {
>       struct switchdev_vlan_dump dump = {
>               .vlan.obj.orig_dev = dev,
>               .vlan.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
> +             .vlan.obj.flags = obj_flags,
>               .skb = skb,
>               .filter_mask = filter_mask,
>       };
> @@ -802,17 +804,27 @@ static int switchdev_port_vlan_fill(struct sk_buff 
> *skb, struct net_device *dev,
>       return err == -EOPNOTSUPP ? 0 : err;
>  }
>  
> -/**
> - *   switchdev_port_bridge_getlink - Get bridge port attributes
> - *
> - *   @dev: port device
> - *
> - *   Called for SELF on rtnl_bridge_getlink to get bridge port
> - *   attributes.
> - */
> -int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
> -                               struct net_device *dev, u32 filter_mask,
> -                               int nlflags)
> +static int switchdev_port_vlan_fill_deferred(struct sk_buff *skb,
> +                                          struct net_device *dev,
> +                                          u32 filter_mask)
> +{
> +     return __switchdev_port_vlan_fill(skb, dev, filter_mask,
> +                                       SWITCHDEV_F_DEFER);
> +}
> +
> +static int switchdev_port_vlan_fill(struct sk_buff *skb,
> +                                 struct net_device *dev,
> +                                 u32 filter_mask)
> +{
> +     return __switchdev_port_vlan_fill(skb, dev, filter_mask, 0);
> +}
> +
> +static int __switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid,
> +                                        u32 seq, struct net_device *dev,
> +                                        u32 filter_mask, int nlflags,
> +                                        int (*fill_cb)(struct sk_buff *skb,
> +                                                       struct net_device *d,
> +                                                       u32 filter_mask))
>  {
>       struct switchdev_attr attr = {
>               .orig_dev = dev,
> @@ -829,12 +841,49 @@ int switchdev_port_bridge_getlink(struct sk_buff *skb, 
> u32 pid, u32 seq,
>       if (err && err != -EOPNOTSUPP)
>               return err;
>  
> -     return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode,
> +     return ndo_dflt_bridge_getlink(skb, pid, seq, d, mode,

Was this s/dev/d/ by mistake?

>                                      attr.u.brport_flags, mask, nlflags,
> -                                    filter_mask, switchdev_port_vlan_fill);
> +                                    filter_mask, fill_cb);
> +}
> +
> +/**
> + *   switchdev_port_bridge_getlink - Get bridge port attributes
> + *
> + *   @dev: port device
> + *
> + *   Called for SELF on rtnl_bridge_getlink to get bridge port
> + *   attributes.
> + */
> +int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
> +                               struct net_device *dev, u32 filter_mask,
> +                               int nlflags)
> +{
> +     return __switchdev_port_bridge_getlink(skb, pid, seq, dev, filter_mask,
> +                                            nlflags,
> +                                            switchdev_port_vlan_fill);
>  }
>  EXPORT_SYMBOL_GPL(switchdev_port_bridge_getlink);
>  
> +/**
> + *   switchdev_port_bridge_getlink_deferred - Get bridge port attributes
> + *   (deferred variant)
> + *
> + *   @dev: port device
> + *
> + *   Called for SELF on rtnl_bridge_getlink to get bridge port
> + *   attributes.
> + */
> +int switchdev_port_bridge_getlink_deferred(struct sk_buff *skb, u32 pid,
> +                                        u32 seq, struct net_device *dev,
> +                                        u32 filter_mask,
> +                                        int nlflags)
> +{
> +     return __switchdev_port_bridge_getlink(skb, pid, seq, dev, filter_mask,
> +                                            nlflags,
> +                                            
> switchdev_port_vlan_fill_deferred);
> +}
> +EXPORT_SYMBOL_GPL(switchdev_port_bridge_getlink_deferred);
> +
>  static int switchdev_port_br_setflag(struct net_device *dev,
>                                    struct nlattr *nlattr,
>                                    unsigned long brport_flag)
> -- 
> 2.9.3
> 

Reply via email to