Skip to content

Commit b943f17

Browse files
Rick Farringtondavem330
authored andcommitted
liquidio: fix race condition in instruction completion processing
In lio_enable_irq, the pkt_in_done count register was being cleared to zero. However, there could be some completed instructions which were not yet processed due to budget and limit constraints. So, only write this register with the number of actual completions that were processed. Signed-off-by: Rick Farrington <ricardo.farrington@cavium.com> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 9ecc660 commit b943f17

File tree

3 files changed

+7
-2
lines changed

3 files changed

+7
-2
lines changed

drivers/net/ethernet/cavium/liquidio/octeon_device.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,8 +1450,9 @@ void lio_enable_irq(struct octeon_droq *droq, struct octeon_instr_queue *iq)
14501450
}
14511451
if (iq) {
14521452
spin_lock_bh(&iq->lock);
1453-
writel(iq->pkt_in_done, iq->inst_cnt_reg);
1454-
iq->pkt_in_done = 0;
1453+
writel(iq->pkts_processed, iq->inst_cnt_reg);
1454+
iq->pkt_in_done -= iq->pkts_processed;
1455+
iq->pkts_processed = 0;
14551456
/* this write needs to be flushed before we release the lock */
14561457
mmiowb();
14571458
spin_unlock_bh(&iq->lock);

drivers/net/ethernet/cavium/liquidio/octeon_iq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ struct octeon_instr_queue {
9494

9595
u32 pkt_in_done;
9696

97+
u32 pkts_processed;
98+
9799
/** A spinlock to protect access to the input ring.*/
98100
spinlock_t iq_flush_running_lock;
99101

drivers/net/ethernet/cavium/liquidio/request_manager.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ int octeon_init_instr_queue(struct octeon_device *oct,
123123
iq->do_auto_flush = 1;
124124
iq->db_timeout = (u32)conf->db_timeout;
125125
atomic_set(&iq->instr_pending, 0);
126+
iq->pkts_processed = 0;
126127

127128
/* Initialize the spinlock for this instruction queue */
128129
spin_lock_init(&iq->lock);
@@ -495,6 +496,7 @@ octeon_flush_iq(struct octeon_device *oct, struct octeon_instr_queue *iq,
495496
lio_process_iq_request_list(oct, iq, 0);
496497

497498
if (inst_processed) {
499+
iq->pkts_processed += inst_processed;
498500
atomic_sub(inst_processed, &iq->instr_pending);
499501
iq->stats.instr_processed += inst_processed;
500502
}

0 commit comments

Comments
 (0)