diff options
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_pd.c')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_pd.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c index c85312ad292b..3dafd7ff36cd 100644 --- a/drivers/infiniband/hw/ehca/ehca_pd.c +++ b/drivers/infiniband/hw/ehca/ehca_pd.c | |||
@@ -49,6 +49,7 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device, | |||
49 | struct ib_ucontext *context, struct ib_udata *udata) | 49 | struct ib_ucontext *context, struct ib_udata *udata) |
50 | { | 50 | { |
51 | struct ehca_pd *pd; | 51 | struct ehca_pd *pd; |
52 | int i; | ||
52 | 53 | ||
53 | pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL); | 54 | pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL); |
54 | if (!pd) { | 55 | if (!pd) { |
@@ -58,6 +59,11 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device, | |||
58 | } | 59 | } |
59 | 60 | ||
60 | pd->ownpid = current->tgid; | 61 | pd->ownpid = current->tgid; |
62 | for (i = 0; i < 2; i++) { | ||
63 | INIT_LIST_HEAD(&pd->free[i]); | ||
64 | INIT_LIST_HEAD(&pd->full[i]); | ||
65 | } | ||
66 | mutex_init(&pd->lock); | ||
61 | 67 | ||
62 | /* | 68 | /* |
63 | * Kernel PD: when device = -1, 0 | 69 | * Kernel PD: when device = -1, 0 |
@@ -81,6 +87,9 @@ int ehca_dealloc_pd(struct ib_pd *pd) | |||
81 | { | 87 | { |
82 | u32 cur_pid = current->tgid; | 88 | u32 cur_pid = current->tgid; |
83 | struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); | 89 | struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); |
90 | int i, leftovers = 0; | ||
91 | extern struct kmem_cache *small_qp_cache; | ||
92 | struct ipz_small_queue_page *page, *tmp; | ||
84 | 93 | ||
85 | if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && | 94 | if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && |
86 | my_pd->ownpid != cur_pid) { | 95 | my_pd->ownpid != cur_pid) { |
@@ -89,8 +98,20 @@ int ehca_dealloc_pd(struct ib_pd *pd) | |||
89 | return -EINVAL; | 98 | return -EINVAL; |
90 | } | 99 | } |
91 | 100 | ||
92 | kmem_cache_free(pd_cache, | 101 | for (i = 0; i < 2; i++) { |
93 | container_of(pd, struct ehca_pd, ib_pd)); | 102 | list_splice(&my_pd->full[i], &my_pd->free[i]); |
103 | list_for_each_entry_safe(page, tmp, &my_pd->free[i], list) { | ||
104 | leftovers = 1; | ||
105 | free_page(page->page); | ||
106 | kmem_cache_free(small_qp_cache, page); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | if (leftovers) | ||
111 | ehca_warn(pd->device, | ||
112 | "Some small queue pages were not freed"); | ||
113 | |||
114 | kmem_cache_free(pd_cache, my_pd); | ||
94 | 115 | ||
95 | return 0; | 116 | return 0; |
96 | } | 117 | } |