qed: Fix missing DORQ attentions
When the DORQ (doorbell block) is overflowed, all PFs get attentions at the same time. If one PF finished handling the attention before another PF even started, the second PF might miss the DORQ's attention bit and not handle the attention at all. If the DORQ attention is missed and the issue is not resolved, another attention will not be sent, therefore each attention is treated as a potential DORQ attention. As a result, the attention callback is called more frequently so the debug print was moved to reduce its quantity. The number of periodic doorbell recovery handler schedules was reduced because it was the previous way to mitigating the missed attention issue. Signed-off-by: Denis Bolotin <dbolotin@marvell.com> Signed-off-by: Michal Kalderon <mkalderon@marvell.com> Signed-off-by: Ariel Elior <aelior@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b61b04ad81
commit
d4476b8a61
3 changed files with 20 additions and 3 deletions
|
@ -436,6 +436,7 @@ struct qed_db_recovery_info {
|
|||
|
||||
/* Lock to protect the doorbell recovery mechanism list */
|
||||
spinlock_t lock;
|
||||
bool dorq_attn;
|
||||
u32 db_recovery_counter;
|
||||
};
|
||||
|
||||
|
|
|
@ -438,17 +438,19 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
|
|||
struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
|
||||
int rc;
|
||||
|
||||
int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
|
||||
DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts);
|
||||
p_hwfn->db_recovery_info.dorq_attn = true;
|
||||
|
||||
/* int_sts may be zero since all PFs were interrupted for doorbell
|
||||
* overflow but another one already handled it. Can abort here. If
|
||||
* This PF also requires overflow recovery we will be interrupted again.
|
||||
* The masked almost full indication may also be set. Ignoring.
|
||||
*/
|
||||
int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
|
||||
if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL))
|
||||
return 0;
|
||||
|
||||
DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts);
|
||||
|
||||
/* check if db_drop or overflow happened */
|
||||
if (int_sts & (DORQ_REG_INT_STS_DB_DROP |
|
||||
DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) {
|
||||
|
@ -505,6 +507,17 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void qed_dorq_attn_handler(struct qed_hwfn *p_hwfn)
|
||||
{
|
||||
if (p_hwfn->db_recovery_info.dorq_attn)
|
||||
goto out;
|
||||
|
||||
/* Call DORQ callback if the attention was missed */
|
||||
qed_dorq_attn_cb(p_hwfn);
|
||||
out:
|
||||
p_hwfn->db_recovery_info.dorq_attn = false;
|
||||
}
|
||||
|
||||
/* Instead of major changes to the data-structure, we have a some 'special'
|
||||
* identifiers for sources that changed meaning between adapters.
|
||||
*/
|
||||
|
@ -1078,6 +1091,9 @@ static int qed_int_deassertion(struct qed_hwfn *p_hwfn,
|
|||
}
|
||||
}
|
||||
|
||||
/* Handle missed DORQ attention */
|
||||
qed_dorq_attn_handler(p_hwfn);
|
||||
|
||||
/* Clear IGU indication for the deasserted bits */
|
||||
DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview +
|
||||
GTT_BAR0_MAP_REG_IGU_CMD +
|
||||
|
|
|
@ -970,7 +970,7 @@ static void qed_update_pf_params(struct qed_dev *cdev,
|
|||
}
|
||||
}
|
||||
|
||||
#define QED_PERIODIC_DB_REC_COUNT 100
|
||||
#define QED_PERIODIC_DB_REC_COUNT 10
|
||||
#define QED_PERIODIC_DB_REC_INTERVAL_MS 100
|
||||
#define QED_PERIODIC_DB_REC_INTERVAL \
|
||||
msecs_to_jiffies(QED_PERIODIC_DB_REC_INTERVAL_MS)
|
||||
|
|
Loading…
Reference in a new issue