IB/cma: Honor traffic class from lower netdevice for RoCE
PATCH 1/1 IB/cma: Honor traffic class from lower netdevice for RoCE
From: Parav Pandit <[email protected]>
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
--- drivers/infiniband/core/cma.c | 59 +++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 9 deletions(-)
drivers/infiniband/core/cma.c +50 -9
@@ -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); +/* If map is found from lower device, use it; Otherwise +* continue with the current netdevice to get priority to tc map. +*/ +if (prio_tc_map.found) +return prio_tc_map.output_tc; +else if (ndev->num_tc) +return netdev_get_prio_tc_map (ndev, prio); +else +return 0 ; }static int cma_resolve_iboe_route (struct rdma_id_private *id_priv)
Signature · 1 line
2.20.1
Quoted 68 lines · Leon Romanovsky
From: Parav Pandit <[email protected]>
When macvlan netdevice is used for RoCE, consider the
tos->prio->tcmapping 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 netdeviceSigned-off-by Parav Pandit <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>drivers/infiniband/core/cma.c | 59 +++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 9 deletions(-)drivers/infiniband/core/cma.c +36
-5+++ 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))
drivers/infiniband/core/cma.c static int cma_resolve_iw_route(struct rdma_id_private *id_priv) · line 2877
Quoted 10 lines
drivers/infiniband/core/cma.c +6
-4-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?
Jason
Quoted 86 lines
-----Original Message-----
From: Jason Gunthorpe <[email protected]>
Sent: Tuesday, October 8, 2019 2:10 PM
To: Leon Romanovsky <[email protected]>
Cc: Doug Ledford <[email protected]>; Parav Pandit <[email protected]>; RDMA mailing list <[email protected]>; Leon Romanovsky <[email protected]>
Subject: Re: [PATCH rdma-next] IB/cma: Honor traffic class from lower netdevice for RoCEReview static int cma_resolve_iw_route(struct
Quoted 18 lines · Leon Romanovsky
From: Parav Pandit <[email protected]>
When macvlan netdevice is used for RoCE, consider the
tos->prio->tcmapping 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 netdeviceSigned-off-by Parav Pandit <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>
drivers/infiniband/core/cma.c| 59 +++++++++++++++++++++++++++++------1 file changed, 50 insertions(+), 9 deletions(-)(quoted diff) +0
-0
b/drivers/infiniband/core/cma.cindex0e3cf3461999..18b5ad8c7d5f100644
+++b/drivers/infiniband/core/cma.c(quoted diff) +0
-0@@ -2827,22 +2827,63 @@ static int cma_resolve_iw_route(struct
rdma_id_private*id_priv)Quoted 53 lines
drivers/infiniband/core/cma.c +33
-9return 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 ;
Quoted 9 lines
drivers/infiniband/core/cma.c static int cma_resolve_iw_route(struct rdma_id_private *id_priv) · line 2877
Quoted 6 lines
drivers/infiniband/core/cma.c +6
-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.
Quoted 1 line
Jason