Files
linux/net/core/netdev_config.c
Jakub Kicinski 8e3245cb30 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>
2026-01-23 11:49:02 -08:00

79 lines
2.3 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
#include <linux/netdevice.h>
#include <net/netdev_queues.h>
#include <net/netdev_rx_queue.h>
#include "dev.h"
static int netdev_nop_validate_qcfg(struct net_device *dev,
struct netdev_queue_config *qcfg,
struct netlink_ext_ack *extack)
{
return 0;
}
static int __netdev_queue_config(struct net_device *dev, int rxq_idx,
struct netdev_queue_config *qcfg,
struct netlink_ext_ack *extack,
bool validate)
{
int (*validate_cb)(struct net_device *dev,
struct netdev_queue_config *qcfg,
struct netlink_ext_ack *extack);
struct pp_memory_provider_params *mpp;
int err;
validate_cb = netdev_nop_validate_qcfg;
if (validate && dev->queue_mgmt_ops->ndo_validate_qcfg)
validate_cb = dev->queue_mgmt_ops->ndo_validate_qcfg;
memset(qcfg, 0, sizeof(*qcfg));
/* Get defaults from the driver, in case user config not set */
if (dev->queue_mgmt_ops->ndo_default_qcfg)
dev->queue_mgmt_ops->ndo_default_qcfg(dev, qcfg);
err = validate_cb(dev, qcfg, extack);
if (err)
return err;
/* Apply MP overrides */
mpp = &__netif_get_rx_queue(dev, rxq_idx)->mp_params;
if (mpp->rx_page_size)
qcfg->rx_page_size = mpp->rx_page_size;
err = validate_cb(dev, qcfg, extack);
if (err)
return err;
return 0;
}
/**
* netdev_queue_config() - get configuration for a given queue
* @dev: net_device instance
* @rxq_idx: index of the queue of interest
* @qcfg: queue configuration struct (output)
*
* Render the configuration for a given queue. This helper should be used
* by drivers which support queue configuration to retrieve config for
* a particular queue.
*
* @qcfg is an output parameter and is always fully initialized by this
* function. Some values may not be set by the user, drivers may either
* deal with the "unset" values in @qcfg, or provide the callback
* to populate defaults in queue_management_ops.
*/
void netdev_queue_config(struct net_device *dev, int rxq_idx,
struct netdev_queue_config *qcfg)
{
__netdev_queue_config(dev, rxq_idx, qcfg, NULL, false);
}
EXPORT_SYMBOL(netdev_queue_config);
int netdev_queue_config_validate(struct net_device *dev, int rxq_idx,
struct netdev_queue_config *qcfg,
struct netlink_ext_ack *extack)
{
return __netdev_queue_config(dev, rxq_idx, qcfg, extack, true);
}