aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ntb/ntb_transport.c
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2017-08-28 20:00:21 +0000
committerAlexander Motin <mav@FreeBSD.org>2017-08-28 20:00:21 +0000
commit546ec4e544f9f03f324517db6ca57b3b73a63561 (patch)
treed2304200e2420c2b8e344c290a34c6d207bec2ef /sys/dev/ntb/ntb_transport.c
parente6f000753eed67885425bb72c3590bd63d01eec6 (diff)
downloadsrc-546ec4e544f9f03f324517db6ca57b3b73a63561.tar.gz
src-546ec4e544f9f03f324517db6ca57b3b73a63561.zip
Mask doorbells while processing them.
This fixes interrupt storms on hardware using legacy level-triggered interrupts, since doorbell processing could take time after interrupt handler completion, that triggered extra interrupts in a loop. MFC after: 2 weeks Sponsored by: iXsystems, Inc.
Notes
Notes: svn path=/head/; revision=322981
Diffstat (limited to 'sys/dev/ntb/ntb_transport.c')
-rw-r--r--sys/dev/ntb/ntb_transport.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/dev/ntb/ntb_transport.c b/sys/dev/ntb/ntb_transport.c
index 328c7a316139..3394adf5a87e 100644
--- a/sys/dev/ntb/ntb_transport.c
+++ b/sys/dev/ntb/ntb_transport.c
@@ -835,6 +835,7 @@ static void
ntb_transport_rxc_db(void *arg, int pending __unused)
{
struct ntb_transport_qp *qp = arg;
+ uint64_t qp_mask = 1ull << qp->qp_num;
int rc;
CTR0(KTR_NTB, "RX: transport_rx");
@@ -843,11 +844,13 @@ again:
;
CTR1(KTR_NTB, "RX: process_rxc returned %d", rc);
- if ((ntb_db_read(qp->dev) & (1ull << qp->qp_num)) != 0) {
+ if ((ntb_db_read(qp->dev) & qp_mask) != 0) {
/* If db is set, clear it and check queue once more. */
- ntb_db_clear(qp->dev, 1ull << qp->qp_num);
+ ntb_db_clear(qp->dev, qp_mask);
goto again;
}
+ if (qp->link_is_up)
+ ntb_db_clear_mask(qp->dev, qp_mask);
}
static int
@@ -1009,6 +1012,8 @@ ntb_transport_doorbell_callback(void *data, uint32_t vector)
vec_mask &= nt->qp_bitmap;
if ((vec_mask & (vec_mask - 1)) != 0)
vec_mask &= ntb_db_read(nt->dev);
+ if (vec_mask != 0)
+ ntb_db_set_mask(nt->dev, vec_mask);
while (vec_mask != 0) {
qp_num = ffsll(vec_mask) - 1;