IB/rdmavt,hfi1,qib: Fix memory leak
authorJubin John <jubin.john@intel.com>
Wed, 20 Apr 2016 13:05:24 +0000 (06:05 -0700)
committerDoug Ledford <dledford@redhat.com>
Thu, 28 Apr 2016 20:32:27 +0000 (16:32 -0400)
rdi->ports has memory allocated in rvt_alloc_device(), but does not get
freed because the hfi1 and qib drivers drivers call ib_dealloc_device()
directly instead of going through rdmavt. Add a rvt_dealloc_device()
that frees rdi->ports and then calls ib_dealloc_device(). Switch hfi1
and qib drivers to calling rvt_dealloc_device() instead of
ib_dealloc_device() directly.

Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Reviewed-by: Brian Welty <brian.welty@intel.com>
Signed-off-by: Jubin John <jubin.john@intel.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/qib/qib_init.c
drivers/infiniband/sw/rdmavt/vt.c
drivers/staging/rdma/hfi1/init.c
include/rdma/rdma_vt.h

index 3f062f0dd9d8082f9fb2986ee13b61c4a867a362..f253111e682ea7494782bfa2a12c97ead940affb 100644 (file)
@@ -1090,7 +1090,7 @@ void qib_free_devdata(struct qib_devdata *dd)
        qib_dbg_ibdev_exit(&dd->verbs_dev);
 #endif
        free_percpu(dd->int_counter);
-       ib_dealloc_device(&dd->verbs_dev.rdi.ibdev);
+       rvt_dealloc_device(&dd->verbs_dev.rdi);
 }
 
 u64 qib_int_counter(struct qib_devdata *dd)
@@ -1183,7 +1183,7 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
 bail:
        if (!list_empty(&dd->list))
                list_del_init(&dd->list);
-       ib_dealloc_device(&dd->verbs_dev.rdi.ibdev);
+       rvt_dealloc_device(&dd->verbs_dev.rdi);
        return ERR_PTR(ret);
 }
 
index 6caf5272ba1f70b96ab19a7a4df1e51f08dfb41c..e1cc2cc42f2550e1a2113b8c471f4456b182dd14 100644 (file)
@@ -106,6 +106,19 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, int nports)
 }
 EXPORT_SYMBOL(rvt_alloc_device);
 
+/**
+ * rvt_dealloc_device - deallocate rdi
+ * @rdi: structure to free
+ *
+ * Free a structure allocated with rvt_alloc_device()
+ */
+void rvt_dealloc_device(struct rvt_dev_info *rdi)
+{
+       kfree(rdi->ports);
+       ib_dealloc_device(&rdi->ibdev);
+}
+EXPORT_SYMBOL(rvt_dealloc_device);
+
 static int rvt_query_device(struct ib_device *ibdev,
                            struct ib_device_attr *props,
                            struct ib_udata *uhw)
index cfcdc16b41c371a18a4e1cec24b51c4c421b7e80..00edd500a69a62e6dcdaa7eb10d60e48e8bb3c11 100644 (file)
@@ -1007,7 +1007,7 @@ void hfi1_free_devdata(struct hfi1_devdata *dd)
        free_percpu(dd->rcv_limit);
        hfi1_dev_affinity_free(dd);
        free_percpu(dd->send_schedule);
-       ib_dealloc_device(&dd->verbs_dev.rdi.ibdev);
+       rvt_dealloc_device(&dd->verbs_dev.rdi);
 }
 
 /*
@@ -1110,7 +1110,7 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra)
 bail:
        if (!list_empty(&dd->list))
                list_del_init(&dd->list);
-       ib_dealloc_device(&dd->verbs_dev.rdi.ibdev);
+       rvt_dealloc_device(&dd->verbs_dev.rdi);
        return ERR_PTR(ret);
 }
 
index a8696551abb1ef16da877252555e572a9b046429..d57ceee90d26fee02ba6535976d19e024239429e 100644 (file)
@@ -467,6 +467,7 @@ static inline struct rvt_qp *rvt_lookup_qpn(struct rvt_dev_info *rdi,
 }
 
 struct rvt_dev_info *rvt_alloc_device(size_t size, int nports);
+void rvt_dealloc_device(struct rvt_dev_info *rdi);
 int rvt_register_device(struct rvt_dev_info *rvd);
 void rvt_unregister_device(struct rvt_dev_info *rvd);
 int rvt_check_ah(struct ib_device *ibdev, struct ib_ah_attr *ah_attr);