From e6f000753eed67885425bb72c3590bd63d01eec6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 28 Aug 2017 19:52:57 +0000 Subject: [PATCH] Fix fake interrupt when set doorbell is unmasked. Since the doorbell bit is already set when interrupt handler is called, the event was not propagated to upper layer. It was working normally because present code was not using masking actively, but that is going to change. MFC after: 2 weeks Sponsored by: iXsystems, Inc. --- sys/dev/ntb/ntb_hw/ntb_hw.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index dac36997cdb..9c8314f5a08 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -253,7 +253,8 @@ struct ntb_softc { uint64_t db_valid_mask; uint64_t db_link_mask; uint64_t db_mask; - uint64_t fake_db_bell; /* NTB_SB01BASE_LOCKUP*/ + uint64_t fake_db; /* NTB_SB01BASE_LOCKUP*/ + uint64_t force_db; /* NTB_SB01BASE_LOCKUP*/ int last_ts; /* ticks @ last irq */ @@ -1206,10 +1207,11 @@ intel_ntb_db_clear_mask(device_t dev, uint64_t bits) (uintmax_t)ntb->db_valid_mask)); DB_MASK_LOCK(ntb); - ibits = ntb->fake_db_bell & ntb->db_mask & bits; + ibits = ntb->fake_db & ntb->db_mask & bits; ntb->db_mask &= ~bits; if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { /* Simulate fake interrupts if unmasked DB bits are set. */ + ntb->force_db |= ibits; for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { if ((ibits & intel_ntb_db_vector_mask(dev, i)) != 0) swi_sched(ntb->int_info[i].tag, 0); @@ -1226,7 +1228,7 @@ intel_ntb_db_read(device_t dev) struct ntb_softc *ntb = device_get_softc(dev); if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) - return (ntb->fake_db_bell); + return (ntb->fake_db); return (db_ioread(ntb, ntb->self_reg->db_bell)); } @@ -1243,7 +1245,7 @@ intel_ntb_db_clear(device_t dev, uint64_t bits) if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { DB_MASK_LOCK(ntb); - ntb->fake_db_bell &= ~bits; + ntb->fake_db &= ~bits; DB_MASK_UNLOCK(ntb); return; } @@ -1291,11 +1293,16 @@ intel_ntb_interrupt(struct ntb_softc *ntb, uint32_t vec) (vec_mask & ntb->db_link_mask) == 0) { DB_MASK_LOCK(ntb); - /* Do not report same DB events again if not cleared yet. */ - vec_mask &= ~ntb->fake_db_bell; + /* + * Do not report same DB events again if not cleared yet, + * unless the mask was just cleared for them and this + * interrupt handler call can be the consequence of it. + */ + vec_mask &= ~ntb->fake_db | ntb->force_db; + ntb->force_db &= ~vec_mask; /* Update our internal doorbell register. */ - ntb->fake_db_bell |= vec_mask; + ntb->fake_db |= vec_mask; /* Do not report masked DB events. */ vec_mask &= ~ntb->db_mask; @@ -1512,7 +1519,7 @@ intel_ntb_xeon_init_dev(struct ntb_softc *ntb) ntb->xlat_reg = &xeon_sec_xlat; if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - ntb->fake_db_bell = 0; + ntb->force_db = ntb->fake_db = 0; ntb->msix_mw_idx = (ntb->mw_count + g_ntb_msix_idx) % ntb->mw_count; intel_ntb_printf(2, "Setting up MSIX mw idx %d means %u\n",