mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
IB/qib: Fix M_Key lease timeout handling
If a port has an M_Key lease set, the M_Key protect bits set to 1, and a SubnSet arrives with an invalid M_Key, an M_Key mismatch trap is generated, the lease timer begins as expected, and eventually the M_Key protect bits will be set back to 0 as per the spec. However, if any other SMP with an invalid M_Key arrives, the lease timer is expired and the M_Key protect bits remain in force. This is not according to to spec. In particular, C14-17 says that a lease timer that is underway is not affected by protection level checks (ie, at protection level 1, a SubnGet with a bad M_Key may be successful, but does not stop the timer), and C14-19 says that the timer shall stop when a valid M_Key has been received. C14-19 is the only compliance statement that specifies a stopping condition for the timer. This behavior is magnified if the port's Master SM LID attribute points at itself. In that case, the M_Key mismatch trap is sufficient to expire the timer, and the mkey lease attribute is rendered useless. Reviewed-by: Ram Vepa <ram.vepa@qlogic.com> Signed-off-by: Jim Foraker <foraker1@llnl.gov> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
f665acb3cb
commit
6199c8961e
@ -396,6 +396,7 @@ static int get_linkdowndefaultstate(struct qib_pportdata *ppd)
|
|||||||
|
|
||||||
static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags)
|
static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags)
|
||||||
{
|
{
|
||||||
|
int valid_mkey = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Is the mkey in the process of expiring? */
|
/* Is the mkey in the process of expiring? */
|
||||||
@ -406,23 +407,36 @@ static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags)
|
|||||||
ibp->mkeyprot = 0;
|
ibp->mkeyprot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* M_Key checking depends on Portinfo:M_Key_protect_bits */
|
if ((mad_flags & IB_MAD_IGNORE_MKEY) || ibp->mkey == 0 ||
|
||||||
if ((mad_flags & IB_MAD_IGNORE_MKEY) == 0 && ibp->mkey != 0 &&
|
ibp->mkey == smp->mkey)
|
||||||
ibp->mkey != smp->mkey &&
|
valid_mkey = 1;
|
||||||
(smp->method == IB_MGMT_METHOD_SET ||
|
|
||||||
smp->method == IB_MGMT_METHOD_TRAP_REPRESS ||
|
/* Unset lease timeout on any valid Get/Set/TrapRepress */
|
||||||
(smp->method == IB_MGMT_METHOD_GET && ibp->mkeyprot >= 2))) {
|
if (valid_mkey && ibp->mkey_lease_timeout &&
|
||||||
if (ibp->mkey_violations != 0xFFFF)
|
(smp->method == IB_MGMT_METHOD_GET ||
|
||||||
++ibp->mkey_violations;
|
smp->method == IB_MGMT_METHOD_SET ||
|
||||||
if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period)
|
smp->method == IB_MGMT_METHOD_TRAP_REPRESS))
|
||||||
ibp->mkey_lease_timeout = jiffies +
|
|
||||||
ibp->mkey_lease_period * HZ;
|
|
||||||
/* Generate a trap notice. */
|
|
||||||
qib_bad_mkey(ibp, smp);
|
|
||||||
ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
|
|
||||||
} else if (ibp->mkey_lease_timeout)
|
|
||||||
ibp->mkey_lease_timeout = 0;
|
ibp->mkey_lease_timeout = 0;
|
||||||
|
|
||||||
|
if (!valid_mkey) {
|
||||||
|
switch (smp->method) {
|
||||||
|
case IB_MGMT_METHOD_GET:
|
||||||
|
/* Bad mkey not a violation below level 2 */
|
||||||
|
if (ibp->mkeyprot < 2)
|
||||||
|
break;
|
||||||
|
case IB_MGMT_METHOD_SET:
|
||||||
|
case IB_MGMT_METHOD_TRAP_REPRESS:
|
||||||
|
if (ibp->mkey_violations != 0xFFFF)
|
||||||
|
++ibp->mkey_violations;
|
||||||
|
if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period)
|
||||||
|
ibp->mkey_lease_timeout = jiffies +
|
||||||
|
ibp->mkey_lease_period * HZ;
|
||||||
|
/* Generate a trap notice. */
|
||||||
|
qib_bad_mkey(ibp, smp);
|
||||||
|
ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user