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.
This commit is contained in:
mav 2017-08-28 19:52:57 +00:00
parent c0dcbc8b2b
commit b813aecdd3

View File

@ -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",