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: use netdev_queue_config() for mp restart

We should follow the prepare/commit approach for queue configuration.
The qcfg struct should be added to dev->cfg rather than directly to
queue objects so that we can clone and discard the pending config
easily.

Remove the qcfg in struct netdev_rx_queue, and switch remaining callers
to netdev_queue_config(). netdev_queue_config() will construct the qcfg
on the fly based on device defaults and state of the queue.

ndo_default_qcfg becomes optional because having the callback itself
does not have any meaningful semantics to us.

Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Link: https://patch.msgid.link/20260122005113.2476634-5-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+37 -39
+3 -1
include/net/netdev_queues.h
··· 139 139 * @ndo_queue_get_dma_dev: Get dma device for zero-copy operations to be used 140 140 * for this queue. Return NULL on error. 141 141 * 142 - * @ndo_default_qcfg: Populate queue config struct with defaults. Optional. 142 + * @ndo_default_qcfg: (Optional) Populate queue config struct with defaults. 143 + * Queue config structs are passed to this helper before 144 + * the user-requested settings are applied. 143 145 * 144 146 * @supported_params: Bitmask of supported parameters, see QCFG_*. 145 147 *
-17
net/core/dev.c
··· 11282 11282 } 11283 11283 } 11284 11284 11285 - static void init_rx_queue_cfgs(struct net_device *dev) 11286 - { 11287 - const struct netdev_queue_mgmt_ops *qops = dev->queue_mgmt_ops; 11288 - struct netdev_rx_queue *rxq; 11289 - int i; 11290 - 11291 - if (!qops || !qops->ndo_default_qcfg) 11292 - return; 11293 - 11294 - for (i = 0; i < dev->num_rx_queues; i++) { 11295 - rxq = __netif_get_rx_queue(dev, i); 11296 - qops->ndo_default_qcfg(dev, &rxq->qcfg); 11297 - } 11298 - } 11299 - 11300 11285 /** 11301 11286 * register_netdevice() - register a network device 11302 11287 * @dev: device to register ··· 11326 11341 dev->name_node = netdev_name_node_head_alloc(dev); 11327 11342 if (!dev->name_node) 11328 11343 goto out; 11329 - 11330 - init_rx_queue_cfgs(dev); 11331 11344 11332 11345 /* Init, if this function is available */ 11333 11346 if (dev->netdev_ops->ndo_init) {
+9 -3
net/core/netdev_config.c
··· 22 22 void netdev_queue_config(struct net_device *dev, int rxq_idx, 23 23 struct netdev_queue_config *qcfg) 24 24 { 25 - struct netdev_queue_config *stored; 25 + struct pp_memory_provider_params *mpp; 26 26 27 27 memset(qcfg, 0, sizeof(*qcfg)); 28 28 29 - stored = &__netif_get_rx_queue(dev, rxq_idx)->qcfg; 30 - qcfg->rx_page_size = stored->rx_page_size; 29 + /* Get defaults from the driver, in case user config not set */ 30 + if (dev->queue_mgmt_ops->ndo_default_qcfg) 31 + dev->queue_mgmt_ops->ndo_default_qcfg(dev, qcfg); 32 + 33 + /* Apply MP overrides */ 34 + mpp = &__netif_get_rx_queue(dev, rxq_idx)->mp_params; 35 + if (mpp->rx_page_size) 36 + qcfg->rx_page_size = mpp->rx_page_size; 31 37 } 32 38 EXPORT_SYMBOL(netdev_queue_config);
+25 -18
net/core/netdev_rx_queue.c
··· 18 18 } 19 19 EXPORT_SYMBOL(netif_rxq_has_unreadable_mp); 20 20 21 - int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx) 21 + static int netdev_rx_queue_reconfig(struct net_device *dev, 22 + unsigned int rxq_idx, 23 + struct netdev_queue_config *qcfg_old, 24 + struct netdev_queue_config *qcfg_new) 22 25 { 23 26 struct netdev_rx_queue *rxq = __netif_get_rx_queue(dev, rxq_idx); 24 27 const struct netdev_queue_mgmt_ops *qops = dev->queue_mgmt_ops; 25 - struct netdev_queue_config qcfg; 26 28 void *new_mem, *old_mem; 27 29 int err; 28 30 ··· 32 30 !qops->ndo_queue_mem_alloc || !qops->ndo_queue_start) 33 31 return -EOPNOTSUPP; 34 32 35 - if (WARN_ON_ONCE(qops->supported_params && !qops->ndo_default_qcfg)) 36 - return -EINVAL; 37 - 38 33 netdev_assert_locked(dev); 39 - 40 - memset(&qcfg, 0, sizeof(qcfg)); 41 - if (qops->ndo_default_qcfg) 42 - qops->ndo_default_qcfg(dev, &qcfg); 43 - 44 - if (rxq->mp_params.rx_page_size) 45 - qcfg.rx_page_size = rxq->mp_params.rx_page_size; 46 34 47 35 new_mem = kvzalloc(qops->ndo_queue_mem_size, GFP_KERNEL); 48 36 if (!new_mem) ··· 44 52 goto err_free_new_mem; 45 53 } 46 54 47 - err = qops->ndo_queue_mem_alloc(dev, &qcfg, new_mem, rxq_idx); 55 + err = qops->ndo_queue_mem_alloc(dev, qcfg_new, new_mem, rxq_idx); 48 56 if (err) 49 57 goto err_free_old_mem; 50 58 ··· 57 65 if (err) 58 66 goto err_free_new_queue_mem; 59 67 60 - err = qops->ndo_queue_start(dev, &qcfg, new_mem, rxq_idx); 68 + err = qops->ndo_queue_start(dev, qcfg_new, new_mem, rxq_idx); 61 69 if (err) 62 70 goto err_start_queue; 63 71 } else { ··· 69 77 kvfree(old_mem); 70 78 kvfree(new_mem); 71 79 72 - rxq->qcfg = qcfg; 73 80 return 0; 74 81 75 82 err_start_queue: ··· 79 88 * WARN if we fail to recover the old rx queue, and at least free 80 89 * old_mem so we don't also leak that. 81 90 */ 82 - if (qops->ndo_queue_start(dev, &rxq->qcfg, old_mem, rxq_idx)) { 91 + if (qops->ndo_queue_start(dev, qcfg_old, old_mem, rxq_idx)) { 83 92 WARN(1, 84 93 "Failed to restart old queue in error path. RX queue %d may be unhealthy.", 85 94 rxq_idx); ··· 97 106 98 107 return err; 99 108 } 109 + 110 + int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx) 111 + { 112 + struct netdev_queue_config qcfg; 113 + 114 + netdev_queue_config(dev, rxq_idx, &qcfg); 115 + return netdev_rx_queue_reconfig(dev, rxq_idx, &qcfg, &qcfg); 116 + } 100 117 EXPORT_SYMBOL_NS_GPL(netdev_rx_queue_restart, "NETDEV_INTERNAL"); 101 118 102 119 int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx, ··· 112 113 struct netlink_ext_ack *extack) 113 114 { 114 115 const struct netdev_queue_mgmt_ops *qops = dev->queue_mgmt_ops; 116 + struct netdev_queue_config qcfg[2]; 115 117 struct netdev_rx_queue *rxq; 116 118 int ret; 117 119 ··· 154 154 } 155 155 #endif 156 156 157 + netdev_queue_config(dev, rxq_idx, &qcfg[0]); 157 158 rxq->mp_params = *p; 158 - ret = netdev_rx_queue_restart(dev, rxq_idx); 159 + netdev_queue_config(dev, rxq_idx, &qcfg[1]); 160 + 161 + ret = netdev_rx_queue_reconfig(dev, rxq_idx, &qcfg[0], &qcfg[1]); 159 162 if (ret) 160 163 memset(&rxq->mp_params, 0, sizeof(rxq->mp_params)); 161 164 ··· 179 176 void __net_mp_close_rxq(struct net_device *dev, unsigned int ifq_idx, 180 177 const struct pp_memory_provider_params *old_p) 181 178 { 179 + struct netdev_queue_config qcfg[2]; 182 180 struct netdev_rx_queue *rxq; 183 181 int err; 184 182 ··· 199 195 rxq->mp_params.mp_priv != old_p->mp_priv)) 200 196 return; 201 197 198 + netdev_queue_config(dev, ifq_idx, &qcfg[0]); 202 199 memset(&rxq->mp_params, 0, sizeof(rxq->mp_params)); 203 - err = netdev_rx_queue_restart(dev, ifq_idx); 200 + netdev_queue_config(dev, ifq_idx, &qcfg[1]); 201 + 202 + err = netdev_rx_queue_reconfig(dev, ifq_idx, &qcfg[0], &qcfg[1]); 204 203 WARN_ON(err && err != -ENETDOWN); 205 204 } 206 205