mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-11 11:56:48 +00:00
mlx4: do not fire tasklet unless necessary
All rx and rx netdev interrupts are handled by respectively by mlx4_en_rx_irq() and mlx4_en_tx_irq() which simply schedule a NAPI. But mlx4_eq_int() also fires a tasklet to service all items that were queued via mlx4_add_cq_to_tasklet(), but this handler was not called unless user cqe was handled. This is very confusing, as "mpstat -I SCPU ..." show huge number of tasklet invocations. This patch saves this overhead, by carefully firing the tasklet directly from mlx4_add_cq_to_tasklet(), removing four atomic operations per IRQ. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Tariq Toukan <tariqt@mellanox.com> Cc: Saeed Mahameed <saeedm@mellanox.com> Acked-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
99d5ceeea5
commit
01f0f42534
@ -81,8 +81,9 @@ void mlx4_cq_tasklet_cb(unsigned long data)
|
||||
|
||||
static void mlx4_add_cq_to_tasklet(struct mlx4_cq *cq)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct mlx4_eq_tasklet *tasklet_ctx = cq->tasklet_ctx.priv;
|
||||
unsigned long flags;
|
||||
bool kick;
|
||||
|
||||
spin_lock_irqsave(&tasklet_ctx->lock, flags);
|
||||
/* When migrating CQs between EQs will be implemented, please note
|
||||
@ -92,7 +93,10 @@ static void mlx4_add_cq_to_tasklet(struct mlx4_cq *cq)
|
||||
*/
|
||||
if (list_empty_careful(&cq->tasklet_ctx.list)) {
|
||||
atomic_inc(&cq->refcount);
|
||||
kick = list_empty(&tasklet_ctx->list);
|
||||
list_add_tail(&cq->tasklet_ctx.list, &tasklet_ctx->list);
|
||||
if (kick)
|
||||
tasklet_schedule(&tasklet_ctx->task);
|
||||
}
|
||||
spin_unlock_irqrestore(&tasklet_ctx->lock, flags);
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
|
||||
{
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
struct mlx4_eqe *eqe;
|
||||
int cqn = -1;
|
||||
int cqn;
|
||||
int eqes_found = 0;
|
||||
int set_ci = 0;
|
||||
int port;
|
||||
@ -840,13 +840,6 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
|
||||
|
||||
eq_set_ci(eq, 1);
|
||||
|
||||
/* cqn is 24bit wide but is initialized such that its higher bits
|
||||
* are ones too. Thus, if we got any event, cqn's high bits should be off
|
||||
* and we need to schedule the tasklet.
|
||||
*/
|
||||
if (!(cqn & ~0xffffff))
|
||||
tasklet_schedule(&eq->tasklet_ctx.task);
|
||||
|
||||
return eqes_found;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user