Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci workqueue and callout fixes
details: https://anonhg.NetBSD.org/src/rev/ad7ea7a81386
branches: trunk
changeset: 837356:ad7ea7a81386
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Fri Nov 30 11:37:11 2018 +0000
description:
workqueue and callout fixes
diffstat:
sys/dev/pci/if_ena.c | 41 ++++++++++++++++++++++++++---------------
1 files changed, 26 insertions(+), 15 deletions(-)
diffs (122 lines):
diff -r 54872da196e0 -r ad7ea7a81386 sys/dev/pci/if_ena.c
--- a/sys/dev/pci/if_ena.c Fri Nov 30 10:18:37 2018 +0000
+++ b/sys/dev/pci/if_ena.c Fri Nov 30 11:37:11 2018 +0000
@@ -31,7 +31,7 @@
#if 0
__FBSDID("$FreeBSD: head/sys/dev/ena/ena.c 333456 2018-05-10 09:37:54Z mw $");
#endif
-__KERNEL_RCSID(0, "$NetBSD: if_ena.c,v 1.9 2018/11/28 21:31:32 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ena.c,v 1.10 2018/11/30 11:37:11 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -641,9 +641,9 @@
}
/* Allocate workqueues */
- int rc = workqueue_create(&tx_ring->enqueue_tq, "ena_tx_enque",
- ena_deferred_mq_start, tx_ring, 0, IPL_NET, 0);
- if (unlikely(rc == 0)) {
+ int rc = workqueue_create(&tx_ring->enqueue_tq, "ena_tx_enq",
+ ena_deferred_mq_start, tx_ring, 0, IPL_NET, WQ_PERCPU | WQ_MPSAFE);
+ if (unlikely(rc != 0)) {
ena_trace(ENA_ALERT,
"Unable to create workqueue for enqueue task\n");
i = tx_ring->ring_size;
@@ -848,8 +848,8 @@
#endif
/* Allocate workqueues */
- int rc = workqueue_create(&rx_ring->cmpl_tq, "ena RX completion",
- ena_deferred_rx_cleanup, rx_ring, 0, IPL_NET, 0);
+ int rc = workqueue_create(&rx_ring->cmpl_tq, "ena_rx_comp",
+ ena_deferred_rx_cleanup, rx_ring, 0, IPL_NET, WQ_PERCPU | WQ_MPSAFE);
if (unlikely(rc != 0)) {
ena_trace(ENA_ALERT,
"Unable to create workqueue for RX completion task\n");
@@ -1422,7 +1422,8 @@
ena_com_update_dev_comp_head(io_cq);
}
- workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task, NULL);
+ if (atomic_cas_uint(&tx_ring->task_pending, 0, 1) == 0)
+ workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task, NULL);
return (work_done);
}
@@ -1638,6 +1639,8 @@
struct ena_ring *rx_ring = arg;
int budget = CLEAN_BUDGET;
+ atomic_swap_uint(&rx_ring->task_pending, 0);
+
ENA_RING_MTX_LOCK(rx_ring);
/*
* If deferred task was executed, perform cleanup of all awaiting
@@ -2913,6 +2916,8 @@
struct ena_ring *tx_ring = (struct ena_ring *)arg;
struct ifnet *ifp = tx_ring->adapter->ifp;
+ atomic_swap_uint(&tx_ring->task_pending, 0);
+
while (!drbr_empty(ifp, tx_ring->br) &&
(if_getdrvflags(ifp) & IFF_RUNNING) != 0) {
ENA_RING_MTX_LOCK(tx_ring);
@@ -2962,8 +2967,9 @@
is_drbr_empty = drbr_empty(ifp, tx_ring->br);
ret = drbr_enqueue(ifp, tx_ring->br, m);
if (unlikely(ret != 0)) {
- workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task,
- curcpu());
+ if (atomic_cas_uint(&tx_ring->task_pending, 0, 1) == 0)
+ workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task,
+ curcpu());
return (ret);
}
@@ -2971,8 +2977,9 @@
ena_start_xmit(tx_ring);
ENA_RING_MTX_UNLOCK(tx_ring);
} else {
- workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task,
- curcpu());
+ if (atomic_cas_uint(&tx_ring->task_pending, 0, 1) == 0)
+ workqueue_enqueue(tx_ring->enqueue_tq, &tx_ring->enqueue_task,
+ curcpu());
}
return (0);
@@ -3494,8 +3501,9 @@
device_printf(adapter->pdev,
"trigger refill for ring %d\n", i);
- workqueue_enqueue(rx_ring->cmpl_tq,
- &rx_ring->cmpl_task, curcpu());
+ if (atomic_cas_uint(&rx_ring->task_pending, 0, 1) == 0)
+ workqueue_enqueue(rx_ring->cmpl_tq,
+ &rx_ring->cmpl_task, curcpu());
rx_ring->empty_rx_queue = 0;
}
} else {
@@ -3765,9 +3773,11 @@
goto err_ifp_free;
}
+ callout_init(&adapter->timer_service, CALLOUT_MPSAFE);
+
/* Initialize reset task queue */
- rc = workqueue_create(&adapter->reset_tq, "ena_reset_enqueue",
- ena_reset_task, adapter, 0, IPL_NET, 0);
+ rc = workqueue_create(&adapter->reset_tq, "ena_reset_enq",
+ ena_reset_task, adapter, 0, IPL_NET, WQ_PERCPU | WQ_MPSAFE);
if (unlikely(rc != 0)) {
ena_trace(ENA_ALERT,
"Unable to create workqueue for reset task\n");
@@ -3831,6 +3841,7 @@
/* Free reset task and callout */
callout_halt(&adapter->timer_service, &adapter->global_mtx);
+ callout_destroy(&adapter->timer_service);
workqueue_wait(adapter->reset_tq, &adapter->reset_task);
workqueue_destroy(adapter->reset_tq);
adapter->reset_tq = NULL;
Home |
Main Index |
Thread Index |
Old Index