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: add queue config validation callback

I imagine (tm) that as the number of per-queue configuration
options grows some of them may conflict for certain drivers.
While the drivers can obviously do all the validation locally
doing so is fairly inconvenient as the config is fed to drivers
piecemeal via different ops (for different params and NIC-wide
vs per-queue).

Add a centralized callback for validating the queue config
in queue ops. The callback gets invoked before memory provider
is installed, and in the future should also be called when ring
params are modified.

The validation is done after each layer of configuration.
Since we can't fail MP un-binding we must make sure that
the config is valid both before and after MP overrides are
applied. This is moot for now since the set of MP and device
configs are disjoint. It will matter significantly in the future,
so adding it now so that we don't forget..

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

+76 -14
+10
include/net/netdev_queues.h
··· 143 143 * Queue config structs are passed to this helper before 144 144 * the user-requested settings are applied. 145 145 * 146 + * @ndo_validate_qcfg: (Optional) Check if queue config is supported. 147 + * Called when configuration affecting a queue may be 148 + * changing, either due to NIC-wide config, or config 149 + * scoped to the queue at a specified index. 150 + * When NIC-wide config is changed the callback will 151 + * be invoked for all queues. 152 + * 146 153 * @supported_params: Bitmask of supported parameters, see QCFG_*. 147 154 * 148 155 * Note that @ndo_queue_mem_alloc and @ndo_queue_mem_free may be called while ··· 173 166 int idx); 174 167 void (*ndo_default_qcfg)(struct net_device *dev, 175 168 struct netdev_queue_config *qcfg); 169 + int (*ndo_validate_qcfg)(struct net_device *dev, 170 + struct netdev_queue_config *qcfg, 171 + struct netlink_ext_ack *extack); 176 172 struct device * (*ndo_queue_get_dma_dev)(struct net_device *dev, 177 173 int idx); 178 174
+5
net/core/dev.h
··· 10 10 11 11 struct net; 12 12 struct netlink_ext_ack; 13 + struct netdev_queue_config; 13 14 struct cpumask; 14 15 15 16 /* Random bits of netdevice that don't need to be exposed */ ··· 91 90 /* rtnl helpers */ 92 91 extern struct list_head net_todo_list; 93 92 void netdev_run_todo(void); 93 + 94 + int netdev_queue_config_validate(struct net_device *dev, int rxq_idx, 95 + struct netdev_queue_config *qcfg, 96 + struct netlink_ext_ack *extack); 94 97 95 98 /* netdev management, shared between various uAPI entry points */ 96 99 struct netdev_name_node {
+52 -12
net/core/netdev_config.c
··· 4 4 #include <net/netdev_queues.h> 5 5 #include <net/netdev_rx_queue.h> 6 6 7 + #include "dev.h" 8 + 9 + static int netdev_nop_validate_qcfg(struct net_device *dev, 10 + struct netdev_queue_config *qcfg, 11 + struct netlink_ext_ack *extack) 12 + { 13 + return 0; 14 + } 15 + 16 + static int __netdev_queue_config(struct net_device *dev, int rxq_idx, 17 + struct netdev_queue_config *qcfg, 18 + struct netlink_ext_ack *extack, 19 + bool validate) 20 + { 21 + int (*validate_cb)(struct net_device *dev, 22 + struct netdev_queue_config *qcfg, 23 + struct netlink_ext_ack *extack); 24 + struct pp_memory_provider_params *mpp; 25 + int err; 26 + 27 + validate_cb = netdev_nop_validate_qcfg; 28 + if (validate && dev->queue_mgmt_ops->ndo_validate_qcfg) 29 + validate_cb = dev->queue_mgmt_ops->ndo_validate_qcfg; 30 + 31 + memset(qcfg, 0, sizeof(*qcfg)); 32 + 33 + /* Get defaults from the driver, in case user config not set */ 34 + if (dev->queue_mgmt_ops->ndo_default_qcfg) 35 + dev->queue_mgmt_ops->ndo_default_qcfg(dev, qcfg); 36 + err = validate_cb(dev, qcfg, extack); 37 + if (err) 38 + return err; 39 + 40 + /* Apply MP overrides */ 41 + mpp = &__netif_get_rx_queue(dev, rxq_idx)->mp_params; 42 + if (mpp->rx_page_size) 43 + qcfg->rx_page_size = mpp->rx_page_size; 44 + err = validate_cb(dev, qcfg, extack); 45 + if (err) 46 + return err; 47 + 48 + return 0; 49 + } 50 + 7 51 /** 8 52 * netdev_queue_config() - get configuration for a given queue 9 53 * @dev: net_device instance ··· 66 22 void netdev_queue_config(struct net_device *dev, int rxq_idx, 67 23 struct netdev_queue_config *qcfg) 68 24 { 69 - struct pp_memory_provider_params *mpp; 70 - 71 - memset(qcfg, 0, sizeof(*qcfg)); 72 - 73 - /* Get defaults from the driver, in case user config not set */ 74 - if (dev->queue_mgmt_ops->ndo_default_qcfg) 75 - dev->queue_mgmt_ops->ndo_default_qcfg(dev, qcfg); 76 - 77 - /* Apply MP overrides */ 78 - mpp = &__netif_get_rx_queue(dev, rxq_idx)->mp_params; 79 - if (mpp->rx_page_size) 80 - qcfg->rx_page_size = mpp->rx_page_size; 25 + __netdev_queue_config(dev, rxq_idx, qcfg, NULL, false); 81 26 } 82 27 EXPORT_SYMBOL(netdev_queue_config); 28 + 29 + int netdev_queue_config_validate(struct net_device *dev, int rxq_idx, 30 + struct netdev_queue_config *qcfg, 31 + struct netlink_ext_ack *extack) 32 + { 33 + return __netdev_queue_config(dev, rxq_idx, qcfg, extack, true); 34 + }
+9 -2
net/core/netdev_rx_queue.c
··· 7 7 #include <net/netdev_rx_queue.h> 8 8 #include <net/page_pool/memory_provider.h> 9 9 10 + #include "dev.h" 10 11 #include "page_pool_priv.h" 11 12 12 13 /* See also page_pool_is_unreadable() */ ··· 157 156 158 157 netdev_queue_config(dev, rxq_idx, &qcfg[0]); 159 158 rxq->mp_params = *p; 160 - netdev_queue_config(dev, rxq_idx, &qcfg[1]); 159 + ret = netdev_queue_config_validate(dev, rxq_idx, &qcfg[1], extack); 160 + if (ret) 161 + goto err_clear_mp; 161 162 162 163 ret = netdev_rx_queue_reconfig(dev, rxq_idx, &qcfg[0], &qcfg[1]); 163 164 if (ret) 164 - memset(&rxq->mp_params, 0, sizeof(rxq->mp_params)); 165 + goto err_clear_mp; 165 166 167 + return 0; 168 + 169 + err_clear_mp: 170 + memset(&rxq->mp_params, 0, sizeof(rxq->mp_params)); 166 171 return ret; 167 172 } 168 173