diff options
author | Jim Foraker <foraker1@llnl.gov> | 2012-05-02 14:39:11 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-05-14 15:42:42 -0400 |
commit | 6199c8961e1bcd38c112bee9028d482e2a7768eb (patch) | |
tree | c11b56db34106b8f1b758516a152213c85918145 /drivers/infiniband | |
parent | f665acb3cbc4d7d83bd655d21e4c7edc45029c46 (diff) |
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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_mad.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index 9292c76380fd..ed611e8df64f 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c | |||
@@ -396,6 +396,7 @@ static int get_linkdowndefaultstate(struct qib_pportdata *ppd) | |||
396 | 396 | ||
397 | static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags) | 397 | static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags) |
398 | { | 398 | { |
399 | int valid_mkey = 0; | ||
399 | int ret = 0; | 400 | int ret = 0; |
400 | 401 | ||
401 | /* Is the mkey in the process of expiring? */ | 402 | /* 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) | |||
406 | ibp->mkeyprot = 0; | 407 | ibp->mkeyprot = 0; |
407 | } | 408 | } |
408 | 409 | ||
409 | /* M_Key checking depends on Portinfo:M_Key_protect_bits */ | 410 | if ((mad_flags & IB_MAD_IGNORE_MKEY) || ibp->mkey == 0 || |
410 | if ((mad_flags & IB_MAD_IGNORE_MKEY) == 0 && ibp->mkey != 0 && | 411 | ibp->mkey == smp->mkey) |
411 | ibp->mkey != smp->mkey && | 412 | valid_mkey = 1; |
412 | (smp->method == IB_MGMT_METHOD_SET || | 413 | |
413 | smp->method == IB_MGMT_METHOD_TRAP_REPRESS || | 414 | /* Unset lease timeout on any valid Get/Set/TrapRepress */ |
414 | (smp->method == IB_MGMT_METHOD_GET && ibp->mkeyprot >= 2))) { | 415 | if (valid_mkey && ibp->mkey_lease_timeout && |
415 | if (ibp->mkey_violations != 0xFFFF) | 416 | (smp->method == IB_MGMT_METHOD_GET || |
416 | ++ibp->mkey_violations; | 417 | smp->method == IB_MGMT_METHOD_SET || |
417 | if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period) | 418 | smp->method == IB_MGMT_METHOD_TRAP_REPRESS)) |
418 | ibp->mkey_lease_timeout = jiffies + | ||
419 | ibp->mkey_lease_period * HZ; | ||
420 | /* Generate a trap notice. */ | ||
421 | qib_bad_mkey(ibp, smp); | ||
422 | ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; | ||
423 | } else if (ibp->mkey_lease_timeout) | ||
424 | ibp->mkey_lease_timeout = 0; | 419 | ibp->mkey_lease_timeout = 0; |
425 | 420 | ||
421 | if (!valid_mkey) { | ||
422 | switch (smp->method) { | ||
423 | case IB_MGMT_METHOD_GET: | ||
424 | /* Bad mkey not a violation below level 2 */ | ||
425 | if (ibp->mkeyprot < 2) | ||
426 | break; | ||
427 | case IB_MGMT_METHOD_SET: | ||
428 | case IB_MGMT_METHOD_TRAP_REPRESS: | ||
429 | if (ibp->mkey_violations != 0xFFFF) | ||
430 | ++ibp->mkey_violations; | ||
431 | if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period) | ||
432 | ibp->mkey_lease_timeout = jiffies + | ||
433 | ibp->mkey_lease_period * HZ; | ||
434 | /* Generate a trap notice. */ | ||
435 | qib_bad_mkey(ibp, smp); | ||
436 | ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; | ||
437 | } | ||
438 | } | ||
439 | |||
426 | return ret; | 440 | return ret; |
427 | } | 441 | } |
428 | 442 | ||