> -----Original Message----- > From: Jason Gunthorpe <jgg@xxxxxxxx> > Sent: Tuesday, October 8, 2019 2:10 PM > To: Leon Romanovsky <leon@xxxxxxxxxx> > Cc: Doug Ledford <dledford@xxxxxxxxxx>; Parav Pandit > <parav@xxxxxxxxxxxx>; RDMA mailing list <linux-rdma@xxxxxxxxxxxxxxx>; > Leon Romanovsky <leonro@xxxxxxxxxxxx> > Subject: Re: [PATCH rdma-next] IB/cma: Honor traffic class from lower > netdevice for RoCE > > > On Wed, Oct 02, 2019 at 03:19:59PM +0300, Leon Romanovsky wrote: > > From: Parav Pandit <parav@xxxxxxxxxxxx> > > > > When macvlan netdevice is used for RoCE, consider the tos->prio->tc > > mapping as SL using its lower netdevice. > > 1. If lower netdevice is VLAN netdevice, consider such VLAN netdevice > > and it's parent netdevice for mapping 2. If lower netdevice is not a > > VLAN netdevice, consider tc mapping directly from such lower netdevice > > > > Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx> > > Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> > > drivers/infiniband/core/cma.c | 59 +++++++++++++++++++++++++++++------ > > 1 file changed, 50 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/infiniband/core/cma.c > > b/drivers/infiniband/core/cma.c index 0e3cf3461999..18b5ad8c7d5f > > 100644 > > +++ b/drivers/infiniband/core/cma.c > > @@ -2827,22 +2827,63 @@ static int cma_resolve_iw_route(struct > rdma_id_private *id_priv) > > return 0; > > } > > > > -static int iboe_tos_to_sl(struct net_device *ndev, int tos) > > +static int get_vlan_ndev_tc(struct net_device *vlan_ndev, int prio) > > { > > - int prio; > > struct net_device *dev; > > > > - prio = rt_tos2priority(tos); > > - dev = is_vlan_dev(ndev) ? vlan_dev_real_dev(ndev) : ndev; > > + dev = vlan_dev_real_dev(vlan_ndev); > > if (dev->num_tc) > > return netdev_get_prio_tc_map(dev, prio); > > > > -#if IS_ENABLED(CONFIG_VLAN_8021Q) > > + return (vlan_dev_get_egress_qos_mask(vlan_ndev, prio) & > > + VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; } > > + > > +struct iboe_prio_tc_map { > > + int input_prio; > > + int output_tc; > > + bool found; > > +}; > > + > > +static int get_lower_vlan_dev_tc(struct net_device *dev, void *data) > > +{ > > + struct iboe_prio_tc_map *map = data; > > + > > + if (is_vlan_dev(dev)) > > + map->output_tc = get_vlan_ndev_tc(dev, map->input_prio); > > + else if (dev->num_tc) > > + map->output_tc = netdev_get_prio_tc_map(dev, map- > >input_prio); > > + else > > + map->output_tc = 0; > > + /* We are interested only in first level VLAN device, so always > > + * return 1 to stop iterating over next level devices. > > + */ > > + map->found = true; > > + return 1; > > +} > > + > > +static int iboe_tos_to_sl(struct net_device *ndev, int tos) { > > + struct iboe_prio_tc_map prio_tc_map = {}; > > + int prio = rt_tos2priority(tos); > > + > > + /* If VLAN device, get it directly from the VLAN netdev */ > > if (is_vlan_dev(ndev)) > > - return (vlan_dev_get_egress_qos_mask(ndev, prio) & > > - VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; > > -#endif > > - return 0; > > + return get_vlan_ndev_tc(ndev, prio); > > + > > + prio_tc_map.input_prio = prio; > > + netdev_walk_all_lower_dev_rcu(ndev, > > + get_lower_vlan_dev_tc, > > + &prio_tc_map); > > Kinda looks like you have to hold rcu before calling this? > Oh yes, my bad. rcu lock unlock calls are missing around netdev_walk_all_lower_dev_rcu(). Will respin through Leon's tree. > Jason