Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: remove the netif_get_rx_queue_lease_locked() helpers

The netif_get_rx_queue_lease_locked() API hides the locking
and the descend onto the leased queue. Making the code
harder to follow (at least to me). Remove the API and open
code the descend a bit. Most of the code now looks like:

if (!leased)
return __helper(x);

hw_rxq = ..
netdev_lock(hw_rxq->dev);
ret = __helper(x);
netdev_unlock(hw_rxq->dev);

return ret;

Of course if we have more code paths that need the wrapping
we may need to revisit. For now, IMHO, having to know what
netif_get_rx_queue_lease_locked() does is not worth the 20LoC
it saves.

Link: https://patch.msgid.link/20260408151251.72bd2482@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+113 -93
-5
include/net/netdev_rx_queue.h
··· 76 76 __netif_get_rx_queue_lease(struct net_device **dev, unsigned int *rxq, 77 77 enum netif_lease_dir dir); 78 78 79 - struct netdev_rx_queue * 80 - netif_get_rx_queue_lease_locked(struct net_device **dev, unsigned int *rxq); 81 - void netif_put_rx_queue_lease_locked(struct net_device *orig_dev, 82 - struct net_device *dev); 83 - 84 79 int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq); 85 80 void netdev_rx_queue_lease(struct netdev_rx_queue *rxq_dst, 86 81 struct netdev_rx_queue *rxq_src);
+1
net/core/dev.h
··· 101 101 102 102 bool netif_rxq_has_mp(struct net_device *dev, unsigned int rxq_idx); 103 103 bool netif_rxq_is_leased(struct net_device *dev, unsigned int rxq_idx); 104 + bool netif_is_queue_leasee(const struct net_device *dev); 104 105 105 106 void __netif_mp_uninstall_rxq(struct netdev_rx_queue *rxq, 106 107 const struct pp_memory_provider_params *p);
+38 -21
net/core/netdev-genl.c
··· 395 395 struct netdev_rx_queue *rxq; 396 396 struct net *net, *peer_net; 397 397 398 - rxq = __netif_get_rx_queue_lease(&netdev, &q_idx, 399 - NETIF_PHYS_TO_VIRT); 398 + rxq = __netif_get_rx_queue_lease(&netdev, &q_idx, NETIF_PHYS_TO_VIRT); 400 399 if (!rxq || orig_netdev == netdev) 401 400 return 0; 402 401 ··· 436 437 } 437 438 438 439 static int 440 + __netdev_nl_queue_fill_mp(struct sk_buff *rsp, struct netdev_rx_queue *rxq) 441 + { 442 + struct pp_memory_provider_params *params = &rxq->mp_params; 443 + 444 + if (params->mp_ops && 445 + params->mp_ops->nl_fill(params->mp_priv, rsp, rxq)) 446 + return -EMSGSIZE; 447 + 448 + #ifdef CONFIG_XDP_SOCKETS 449 + if (rxq->pool) 450 + if (nla_put_empty_nest(rsp, NETDEV_A_QUEUE_XSK)) 451 + return -EMSGSIZE; 452 + #endif 453 + return 0; 454 + } 455 + 456 + static int 457 + netdev_nl_queue_fill_mp(struct sk_buff *rsp, struct net_device *netdev, 458 + struct netdev_rx_queue *rxq) 459 + { 460 + struct netdev_rx_queue *hw_rxq; 461 + int ret; 462 + 463 + hw_rxq = rxq->lease; 464 + if (!hw_rxq || !netif_is_queue_leasee(netdev)) 465 + return __netdev_nl_queue_fill_mp(rsp, rxq); 466 + 467 + netdev_lock(hw_rxq->dev); 468 + ret = __netdev_nl_queue_fill_mp(rsp, hw_rxq); 469 + netdev_unlock(hw_rxq->dev); 470 + return ret; 471 + } 472 + 473 + static int 439 474 netdev_nl_queue_fill_one(struct sk_buff *rsp, struct net_device *netdev, 440 475 u32 q_idx, u32 q_type, const struct genl_info *info) 441 476 { 442 - struct pp_memory_provider_params *params; 443 - struct net_device *orig_netdev = netdev; 444 - struct netdev_rx_queue *rxq, *rxq_lease; 477 + struct netdev_rx_queue *rxq; 445 478 struct netdev_queue *txq; 446 479 void *hdr; 447 480 ··· 493 462 goto nla_put_failure; 494 463 if (netdev_nl_queue_fill_lease(rsp, netdev, q_idx, q_type)) 495 464 goto nla_put_failure; 496 - 497 - rxq_lease = netif_get_rx_queue_lease_locked(&netdev, &q_idx); 498 - if (rxq_lease) 499 - rxq = rxq_lease; 500 - params = &rxq->mp_params; 501 - if (params->mp_ops && 502 - params->mp_ops->nl_fill(params->mp_priv, rsp, rxq)) 503 - goto nla_put_failure_lease; 504 - #ifdef CONFIG_XDP_SOCKETS 505 - if (rxq->pool) 506 - if (nla_put_empty_nest(rsp, NETDEV_A_QUEUE_XSK)) 507 - goto nla_put_failure_lease; 508 - #endif 509 - netif_put_rx_queue_lease_locked(orig_netdev, netdev); 465 + if (netdev_nl_queue_fill_mp(rsp, netdev, rxq)) 466 + goto nla_put_failure; 510 467 break; 511 468 case NETDEV_QUEUE_TYPE_TX: 512 469 txq = netdev_get_tx_queue(netdev, q_idx); ··· 512 493 513 494 return 0; 514 495 515 - nla_put_failure_lease: 516 - netif_put_rx_queue_lease_locked(orig_netdev, netdev); 517 496 nla_put_failure: 518 497 genlmsg_cancel(rsp, hdr); 519 498 return -EMSGSIZE;
+11 -5
net/core/netdev_queues.c
··· 37 37 unsigned int idx, 38 38 enum netdev_queue_type type) 39 39 { 40 - struct net_device *orig_dev = dev; 40 + struct netdev_rx_queue *hw_rxq; 41 41 struct device *dma_dev; 42 + 43 + netdev_ops_assert_locked(dev); 42 44 43 45 /* Only RX side supports queue leasing today. */ 44 46 if (type != NETDEV_QUEUE_TYPE_RX || !netif_rxq_is_leased(dev, idx)) 45 47 return __netdev_queue_get_dma_dev(dev, idx); 46 - 47 - if (!netif_get_rx_queue_lease_locked(&dev, &idx)) 48 + if (!netif_is_queue_leasee(dev)) 48 49 return NULL; 49 50 50 - dma_dev = __netdev_queue_get_dma_dev(dev, idx); 51 - netif_put_rx_queue_lease_locked(orig_dev, dev); 51 + hw_rxq = __netif_get_rx_queue(dev, idx)->lease; 52 + 53 + netdev_lock(hw_rxq->dev); 54 + idx = get_netdev_rx_queue_index(hw_rxq); 55 + dma_dev = __netdev_queue_get_dma_dev(hw_rxq->dev, idx); 56 + netdev_unlock(hw_rxq->dev); 57 + 52 58 return dma_dev; 53 59 } 54 60
+14 -34
net/core/netdev_rx_queue.c
··· 57 57 return false; 58 58 } 59 59 60 + bool netif_is_queue_leasee(const struct net_device *dev) 61 + { 62 + return netif_lease_dir_ok(dev, NETIF_VIRT_TO_PHYS); 63 + } 64 + 60 65 struct netdev_rx_queue * 61 66 __netif_get_rx_queue_lease(struct net_device **dev, unsigned int *rxq_idx, 62 67 enum netif_lease_dir dir) ··· 77 72 *dev = rxq->dev; 78 73 } 79 74 return rxq; 80 - } 81 - 82 - struct netdev_rx_queue * 83 - netif_get_rx_queue_lease_locked(struct net_device **dev, unsigned int *rxq_idx) 84 - { 85 - struct net_device *orig_dev = *dev; 86 - struct netdev_rx_queue *rxq; 87 - 88 - /* Locking order is always from the virtual to the physical device 89 - * see netdev_nl_queue_create_doit(). 90 - */ 91 - netdev_ops_assert_locked(orig_dev); 92 - rxq = __netif_get_rx_queue_lease(dev, rxq_idx, NETIF_VIRT_TO_PHYS); 93 - if (rxq && orig_dev != *dev) 94 - netdev_lock(*dev); 95 - return rxq; 96 - } 97 - 98 - void netif_put_rx_queue_lease_locked(struct net_device *orig_dev, 99 - struct net_device *dev) 100 - { 101 - if (orig_dev != dev) 102 - netdev_unlock(dev); 103 75 } 104 76 105 77 /* See also page_pool_is_unreadable() */ ··· 246 264 const struct pp_memory_provider_params *p, 247 265 struct netlink_ext_ack *extack) 248 266 { 249 - struct net_device *orig_dev = dev; 250 267 int ret; 251 268 252 269 if (!netdev_need_ops_lock(dev)) ··· 260 279 if (!netif_rxq_is_leased(dev, rxq_idx)) 261 280 return __netif_mp_open_rxq(dev, rxq_idx, p, extack); 262 281 263 - if (!netif_get_rx_queue_lease_locked(&dev, &rxq_idx)) { 282 + if (!__netif_get_rx_queue_lease(&dev, &rxq_idx, NETIF_VIRT_TO_PHYS)) { 264 283 NL_SET_ERR_MSG(extack, "rx queue leased to a virtual netdev"); 265 284 return -EBUSY; 266 285 } 267 286 if (!dev->dev.parent) { 268 287 NL_SET_ERR_MSG(extack, "rx queue belongs to a virtual netdev"); 269 - ret = -EOPNOTSUPP; 270 - goto out; 288 + return -EOPNOTSUPP; 271 289 } 272 290 291 + netdev_lock(dev); 273 292 ret = __netif_mp_open_rxq(dev, rxq_idx, p, extack); 274 - out: 275 - netif_put_rx_queue_lease_locked(orig_dev, dev); 293 + netdev_unlock(dev); 276 294 return ret; 277 295 } 278 296 ··· 306 326 void netif_mp_close_rxq(struct net_device *dev, unsigned int ifq_idx, 307 327 const struct pp_memory_provider_params *old_p) 308 328 { 309 - struct net_device *orig_dev = dev; 310 - 311 329 if (WARN_ON_ONCE(ifq_idx >= dev->real_num_rx_queues)) 312 330 return; 313 331 if (!netif_rxq_is_leased(dev, ifq_idx)) 314 332 return __netif_mp_close_rxq(dev, ifq_idx, old_p); 315 333 316 - if (WARN_ON_ONCE(!netif_get_rx_queue_lease_locked(&dev, &ifq_idx))) 334 + if (!__netif_get_rx_queue_lease(&dev, &ifq_idx, NETIF_VIRT_TO_PHYS)) { 335 + WARN_ON_ONCE(1); 317 336 return; 318 - 337 + } 338 + netdev_lock(dev); 319 339 __netif_mp_close_rxq(dev, ifq_idx, old_p); 320 - netif_put_rx_queue_lease_locked(orig_dev, dev); 340 + netdev_unlock(dev); 321 341 } 322 342 323 343 void __netif_mp_uninstall_rxq(struct netdev_rx_queue *rxq,
+49 -28
net/xdp/xsk.c
··· 31 31 #include <net/netdev_rx_queue.h> 32 32 #include <net/xdp.h> 33 33 34 + #include "../core/dev.h" 35 + 34 36 #include "xsk_queue.h" 35 37 #include "xdp_umem.h" 36 38 #include "xsk.h" ··· 119 117 } 120 118 EXPORT_SYMBOL(xsk_get_pool_from_qid); 121 119 120 + static void __xsk_clear_pool_at_qid(struct net_device *dev, u16 queue_id) 121 + { 122 + if (queue_id < dev->num_rx_queues) 123 + dev->_rx[queue_id].pool = NULL; 124 + if (queue_id < dev->num_tx_queues) 125 + dev->_tx[queue_id].pool = NULL; 126 + } 127 + 122 128 void xsk_clear_pool_at_qid(struct net_device *dev, u16 queue_id) 123 129 { 124 - struct net_device *orig_dev = dev; 125 - unsigned int id = queue_id; 130 + struct netdev_rx_queue *hw_rxq; 126 131 127 - if (id < dev->real_num_rx_queues) 128 - WARN_ON_ONCE(!netif_get_rx_queue_lease_locked(&dev, &id)); 132 + if (!netif_rxq_is_leased(dev, queue_id)) 133 + return __xsk_clear_pool_at_qid(dev, queue_id); 134 + WARN_ON_ONCE(!netif_is_queue_leasee(dev)); 129 135 130 - if (id < dev->num_rx_queues) 131 - dev->_rx[id].pool = NULL; 132 - if (id < dev->num_tx_queues) 133 - dev->_tx[id].pool = NULL; 136 + hw_rxq = __netif_get_rx_queue(dev, queue_id)->lease; 134 137 135 - netif_put_rx_queue_lease_locked(orig_dev, dev); 138 + netdev_lock(hw_rxq->dev); 139 + queue_id = get_netdev_rx_queue_index(hw_rxq); 140 + __xsk_clear_pool_at_qid(hw_rxq->dev, queue_id); 141 + netdev_unlock(hw_rxq->dev); 142 + } 143 + 144 + static int __xsk_reg_pool_at_qid(struct net_device *dev, 145 + struct xsk_buff_pool *pool, u16 queue_id) 146 + { 147 + if (xsk_get_pool_from_qid(dev, queue_id)) 148 + return -EBUSY; 149 + 150 + if (queue_id < dev->real_num_rx_queues) 151 + dev->_rx[queue_id].pool = pool; 152 + if (queue_id < dev->real_num_tx_queues) 153 + dev->_tx[queue_id].pool = pool; 154 + 155 + return 0; 136 156 } 137 157 138 158 /* The buffer pool is stored both in the _rx struct and the _tx struct as we do ··· 164 140 int xsk_reg_pool_at_qid(struct net_device *dev, struct xsk_buff_pool *pool, 165 141 u16 queue_id) 166 142 { 167 - struct net_device *orig_dev = dev; 168 - unsigned int id = queue_id; 169 - int ret = 0; 143 + struct netdev_rx_queue *hw_rxq; 144 + int ret; 170 145 171 - if (id >= max(dev->real_num_rx_queues, 172 - dev->real_num_tx_queues)) 146 + if (queue_id >= max(dev->real_num_rx_queues, 147 + dev->real_num_tx_queues)) 173 148 return -EINVAL; 174 149 175 - if (id < dev->real_num_rx_queues) { 176 - if (!netif_get_rx_queue_lease_locked(&dev, &id)) 177 - return -EBUSY; 178 - if (xsk_get_pool_from_qid(dev, id)) { 179 - ret = -EBUSY; 180 - goto out; 181 - } 182 - } 150 + if (queue_id >= dev->real_num_rx_queues || 151 + !netif_rxq_is_leased(dev, queue_id)) 152 + return __xsk_reg_pool_at_qid(dev, pool, queue_id); 153 + if (!netif_is_queue_leasee(dev)) 154 + return -EBUSY; 183 155 184 - if (id < dev->real_num_rx_queues) 185 - dev->_rx[id].pool = pool; 186 - if (id < dev->real_num_tx_queues) 187 - dev->_tx[id].pool = pool; 188 - out: 189 - netif_put_rx_queue_lease_locked(orig_dev, dev); 156 + hw_rxq = __netif_get_rx_queue(dev, queue_id)->lease; 157 + 158 + netdev_lock(hw_rxq->dev); 159 + queue_id = get_netdev_rx_queue_index(hw_rxq); 160 + ret = __xsk_reg_pool_at_qid(hw_rxq->dev, pool, queue_id); 161 + netdev_unlock(hw_rxq->dev); 162 + 190 163 return ret; 191 164 } 192 165