Commit 6199c896 authored by Jim Foraker's avatar Jim Foraker Committed by Roland Dreier

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: default avatarRam Vepa <ram.vepa@qlogic.com>
Signed-off-by: default avatarJim Foraker <foraker1@llnl.gov>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent f665acb3
...@@ -396,6 +396,7 @@ static int get_linkdowndefaultstate(struct qib_pportdata *ppd) ...@@ -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,12 +407,25 @@ static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags) ...@@ -406,12 +407,25 @@ 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 &&
(smp->method == IB_MGMT_METHOD_GET ||
smp->method == IB_MGMT_METHOD_SET ||
smp->method == IB_MGMT_METHOD_TRAP_REPRESS))
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) if (ibp->mkey_violations != 0xFFFF)
++ibp->mkey_violations; ++ibp->mkey_violations;
if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period) if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period)
...@@ -420,8 +434,8 @@ static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags) ...@@ -420,8 +434,8 @@ static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags)
/* Generate a trap notice. */ /* Generate a trap notice. */
qib_bad_mkey(ibp, smp); qib_bad_mkey(ibp, smp);
ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
} else if (ibp->mkey_lease_timeout) }
ibp->mkey_lease_timeout = 0; }
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment