From 21cfca33587d45ccdc5aaaedf97a909ccc4a0a27 Mon Sep 17 00:00:00 2001 From: Harish Chegondi Date: Sun, 14 Feb 2016 12:11:28 -0800 Subject: [PATCH] IB/qib: Destroy SMI AH before de-allocating the protection domain If SMI AH is not destroyed before de-allocating the PD, it would result in non-zero PD use count when de-allocating the PD, triggering a WARN_ON() at drivers/infiniband/core/verbs.c:284 ib_dealloc_pd+0x69/0xb0 [ib_core]() when unloading the qib driver on systems with dual-port card. This problem has always been there in qib and was detected only after the commit 7dd78647a2c2 ("IB/core: Make ib_dealloc_pd return void") introduced a WARN_ON in ib_dealloc_pd() that triggers if a PD's use count is non-zero before de-allocating the PD. Below is the call trace from the dmesg log. [ 7264.966129] Call Trace: [ 7264.969652] [] dump_stack+0x44/0x64 [ 7264.976181] [] warn_slowpath_common+0x86/0xc0 [ 7264.983656] [] warn_slowpath_null+0x1a/0x20 [ 7264.990961] [] ib_dealloc_pd+0x69/0xb0 [ib_core] [ 7264.998717] [] ib_mad_port_close+0xb8/0x120 [ib_mad] [ 7265.006866] [] ib_mad_remove_device+0x6f/0xc0 [ib_mad] [ 7265.015224] [] ib_unregister_device+0xa7/0x140 [ib_core] [ 7265.023738] [] rvt_unregister_device+0x29/0x80 [rdmavt] [ 7265.032181] [] qib_unregister_ib_device+0x22/0x210 [ib_qib] [ 7265.040993] [] qib_remove_one+0x1f/0x250 [ib_qib] [ 7265.048823] [] pci_device_remove+0x39/0xc0 [ 7265.055984] [] __device_release_driver+0x9a/0x140 [ 7265.063821] [] driver_detach+0xb8/0xc0 [ 7265.070579] [] bus_remove_driver+0x55/0xd0 [ 7265.077717] [] driver_unregister+0x2c/0x50 [ 7265.084849] [] pci_unregister_driver+0x2a/0x80 [ 7265.092366] [] qib_ib_cleanup+0x37/0x65 [ib_qib] [ 7265.100068] [] SyS_delete_module+0x190/0x220 [ 7265.107379] [] entry_SYSCALL_64_fastpath+0x12/0x71 Reviewed-by: Mike Marciniszyn Reviewed-by: Dennis Dalessandro Signed-off-by: Harish Chegondi Signed-off-by: Doug Ledford --- drivers/infiniband/hw/qib/qib_iba7322.c | 2 -- drivers/infiniband/hw/qib/qib_mad.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index ca28c19d9618..82d7c4bf5970 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -2910,8 +2910,6 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd) spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); qib_qsfp_deinit(&dd->pport[i].cpspec->qsfp_data); } - if (dd->pport[i].ibport_data.smi_ah) - ib_destroy_ah(&dd->pport[i].ibport_data.smi_ah->ibah); } } diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index 73ca2c2a79a7..0bd18375d7df 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c @@ -2496,4 +2496,7 @@ void qib_notify_free_mad_agent(struct rvt_dev_info *rdi, int port_idx) if (dd->pport[port_idx].cong_stats.timer.data) del_timer_sync(&dd->pport[port_idx].cong_stats.timer); + + if (dd->pport[port_idx].ibport_data.smi_ah) + ib_destroy_ah(&dd->pport[port_idx].ibport_data.smi_ah->ibah); } -- 2.20.1