dim: add new interfaces for initialization and getting results

DIM-related mode and work have been collected in one same place,
so new interfaces are added to provide convenience.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20240621101353.107425-5-hengqi@linux.alibaba.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Heng Qi 2024-06-21 18:13:52 +08:00 committed by Jakub Kicinski
parent f750dfe825
commit 13ba28c5cd
2 changed files with 116 additions and 0 deletions

View File

@ -256,6 +256,54 @@ int net_dim_init_irq_moder(struct net_device *dev, u8 profile_flags,
*/ */
void net_dim_free_irq_moder(struct net_device *dev); void net_dim_free_irq_moder(struct net_device *dev);
/**
* net_dim_setting - initialize DIM's cq mode and schedule worker
* @dev: target network device
* @dim: DIM context
* @is_tx: true indicates the tx direction, false indicates the rx direction
*/
void net_dim_setting(struct net_device *dev, struct dim *dim, bool is_tx);
/**
* net_dim_work_cancel - synchronously cancel dim's worker
* @dim: DIM context
*/
void net_dim_work_cancel(struct dim *dim);
/**
* net_dim_get_rx_irq_moder - get DIM rx results based on profile_ix
* @dev: target network device
* @dim: DIM context
*
* Return: DIM irq moderation
*/
struct dim_cq_moder
net_dim_get_rx_irq_moder(struct net_device *dev, struct dim *dim);
/**
* net_dim_get_tx_irq_moder - get DIM tx results based on profile_ix
* @dev: target network device
* @dim: DIM context
*
* Return: DIM irq moderation
*/
struct dim_cq_moder
net_dim_get_tx_irq_moder(struct net_device *dev, struct dim *dim);
/**
* net_dim_set_rx_mode - set DIM rx cq mode
* @dev: target network device
* @rx_mode: target rx cq mode
*/
void net_dim_set_rx_mode(struct net_device *dev, u8 rx_mode);
/**
* net_dim_set_tx_mode - set DIM tx cq mode
* @dev: target network device
* @tx_mode: target tx cq mode
*/
void net_dim_set_tx_mode(struct net_device *dev, u8 tx_mode);
/** /**
* dim_on_top - check if current state is a good place to stop (top location) * dim_on_top - check if current state is a good place to stop (top location)
* @dim: DIM context * @dim: DIM context

View File

@ -165,6 +165,74 @@ void net_dim_free_irq_moder(struct net_device *dev)
} }
EXPORT_SYMBOL(net_dim_free_irq_moder); EXPORT_SYMBOL(net_dim_free_irq_moder);
void net_dim_setting(struct net_device *dev, struct dim *dim, bool is_tx)
{
struct dim_irq_moder *irq_moder = dev->irq_moder;
if (!irq_moder)
return;
if (is_tx) {
INIT_WORK(&dim->work, irq_moder->tx_dim_work);
dim->mode = READ_ONCE(irq_moder->dim_tx_mode);
return;
}
INIT_WORK(&dim->work, irq_moder->rx_dim_work);
dim->mode = READ_ONCE(irq_moder->dim_rx_mode);
}
EXPORT_SYMBOL(net_dim_setting);
void net_dim_work_cancel(struct dim *dim)
{
cancel_work_sync(&dim->work);
}
EXPORT_SYMBOL(net_dim_work_cancel);
struct dim_cq_moder net_dim_get_rx_irq_moder(struct net_device *dev,
struct dim *dim)
{
struct dim_cq_moder res, *profile;
rcu_read_lock();
profile = rcu_dereference(dev->irq_moder->rx_profile);
res = profile[dim->profile_ix];
rcu_read_unlock();
res.cq_period_mode = dim->mode;
return res;
}
EXPORT_SYMBOL(net_dim_get_rx_irq_moder);
struct dim_cq_moder net_dim_get_tx_irq_moder(struct net_device *dev,
struct dim *dim)
{
struct dim_cq_moder res, *profile;
rcu_read_lock();
profile = rcu_dereference(dev->irq_moder->tx_profile);
res = profile[dim->profile_ix];
rcu_read_unlock();
res.cq_period_mode = dim->mode;
return res;
}
EXPORT_SYMBOL(net_dim_get_tx_irq_moder);
void net_dim_set_rx_mode(struct net_device *dev, u8 rx_mode)
{
WRITE_ONCE(dev->irq_moder->dim_rx_mode, rx_mode);
}
EXPORT_SYMBOL(net_dim_set_rx_mode);
void net_dim_set_tx_mode(struct net_device *dev, u8 tx_mode)
{
WRITE_ONCE(dev->irq_moder->dim_tx_mode, tx_mode);
}
EXPORT_SYMBOL(net_dim_set_tx_mode);
static int net_dim_step(struct dim *dim) static int net_dim_step(struct dim *dim)
{ {
if (dim->tired == (NET_DIM_PARAMS_NUM_PROFILES * 2)) if (dim->tired == (NET_DIM_PARAMS_NUM_PROFILES * 2))