1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41#include "ehca_tools.h"
42#include "ehca_iverbs.h"
43
44static struct kmem_cache *pd_cache;
45
46struct ib_pd *ehca_alloc_pd(struct ib_device *device,
47 struct ib_ucontext *context, struct ib_udata *udata)
48{
49 struct ehca_pd *pd;
50 int i;
51
52 pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL);
53 if (!pd) {
54 ehca_err(device, "device=%p context=%p out of memory",
55 device, context);
56 return ERR_PTR(-ENOMEM);
57 }
58
59 for (i = 0; i < 2; i++) {
60 INIT_LIST_HEAD(&pd->free[i]);
61 INIT_LIST_HEAD(&pd->full[i]);
62 }
63 mutex_init(&pd->lock);
64
65
66
67
68
69 if (!context) {
70
71
72
73
74 struct ehca_shca *shca = container_of(device, struct ehca_shca,
75 ib_device);
76 pd->fw_pd.value = shca->pd->fw_pd.value;
77 } else
78 pd->fw_pd.value = (u64)pd;
79
80 return &pd->ib_pd;
81}
82
83int ehca_dealloc_pd(struct ib_pd *pd)
84{
85 struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
86 int i, leftovers = 0;
87 struct ipz_small_queue_page *page, *tmp;
88
89 for (i = 0; i < 2; i++) {
90 list_splice(&my_pd->full[i], &my_pd->free[i]);
91 list_for_each_entry_safe(page, tmp, &my_pd->free[i], list) {
92 leftovers = 1;
93 free_page(page->page);
94 kmem_cache_free(small_qp_cache, page);
95 }
96 }
97
98 if (leftovers)
99 ehca_warn(pd->device,
100 "Some small queue pages were not freed");
101
102 kmem_cache_free(pd_cache, my_pd);
103
104 return 0;
105}
106
107int ehca_init_pd_cache(void)
108{
109 pd_cache = kmem_cache_create("ehca_cache_pd",
110 sizeof(struct ehca_pd), 0,
111 SLAB_HWCACHE_ALIGN,
112 NULL);
113 if (!pd_cache)
114 return -ENOMEM;
115 return 0;
116}
117
118void ehca_cleanup_pd_cache(void)
119{
120 if (pd_cache)
121 kmem_cache_destroy(pd_cache);
122}
123