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
42
43
44#include <linux/slab.h>
45#include <linux/fs.h>
46#include <linux/sysctl.h>
47#include <linux/workqueue.h>
48#include <linux/sunrpc/clnt.h>
49#include <linux/sunrpc/sched.h>
50#include <linux/sunrpc/svc_rdma.h>
51
52#define RPCDBG_FACILITY RPCDBG_SVCXPRT
53
54
55unsigned int svcrdma_ord = 16;
56static unsigned int min_ord = 1;
57static unsigned int max_ord = 255;
58unsigned int svcrdma_max_requests = RPCRDMA_MAX_REQUESTS;
59unsigned int svcrdma_max_bc_requests = RPCRDMA_MAX_BC_REQUESTS;
60static unsigned int min_max_requests = 4;
61static unsigned int max_max_requests = 16384;
62unsigned int svcrdma_max_req_size = RPCRDMA_DEF_INLINE_THRESH;
63static unsigned int min_max_inline = RPCRDMA_DEF_INLINE_THRESH;
64static unsigned int max_max_inline = RPCRDMA_MAX_INLINE_THRESH;
65static unsigned int svcrdma_stat_unused;
66static unsigned int zero;
67
68struct percpu_counter svcrdma_stat_read;
69struct percpu_counter svcrdma_stat_recv;
70struct percpu_counter svcrdma_stat_sq_starve;
71struct percpu_counter svcrdma_stat_write;
72
73enum {
74 SVCRDMA_COUNTER_BUFSIZ = sizeof(unsigned long long),
75};
76
77static int svcrdma_counter_handler(struct ctl_table *table, int write,
78 void *buffer, size_t *lenp, loff_t *ppos)
79{
80 struct percpu_counter *stat = (struct percpu_counter *)table->data;
81 char tmp[SVCRDMA_COUNTER_BUFSIZ + 1];
82 int len;
83
84 if (write) {
85 percpu_counter_set(stat, 0);
86 return 0;
87 }
88
89 len = snprintf(tmp, SVCRDMA_COUNTER_BUFSIZ, "%lld\n",
90 percpu_counter_sum_positive(stat));
91 if (len >= SVCRDMA_COUNTER_BUFSIZ)
92 return -EFAULT;
93 len = strlen(tmp);
94 if (*ppos > len) {
95 *lenp = 0;
96 return 0;
97 }
98 len -= *ppos;
99 if (len > *lenp)
100 len = *lenp;
101 if (len)
102 memcpy(buffer, tmp, len);
103 *lenp = len;
104 *ppos += len;
105
106 return 0;
107}
108
109static struct ctl_table_header *svcrdma_table_header;
110static struct ctl_table svcrdma_parm_table[] = {
111 {
112 .procname = "max_requests",
113 .data = &svcrdma_max_requests,
114 .maxlen = sizeof(unsigned int),
115 .mode = 0644,
116 .proc_handler = proc_dointvec_minmax,
117 .extra1 = &min_max_requests,
118 .extra2 = &max_max_requests
119 },
120 {
121 .procname = "max_req_size",
122 .data = &svcrdma_max_req_size,
123 .maxlen = sizeof(unsigned int),
124 .mode = 0644,
125 .proc_handler = proc_dointvec_minmax,
126 .extra1 = &min_max_inline,
127 .extra2 = &max_max_inline
128 },
129 {
130 .procname = "max_outbound_read_requests",
131 .data = &svcrdma_ord,
132 .maxlen = sizeof(unsigned int),
133 .mode = 0644,
134 .proc_handler = proc_dointvec_minmax,
135 .extra1 = &min_ord,
136 .extra2 = &max_ord,
137 },
138
139 {
140 .procname = "rdma_stat_read",
141 .data = &svcrdma_stat_read,
142 .maxlen = SVCRDMA_COUNTER_BUFSIZ,
143 .mode = 0644,
144 .proc_handler = svcrdma_counter_handler,
145 },
146 {
147 .procname = "rdma_stat_recv",
148 .data = &svcrdma_stat_recv,
149 .maxlen = SVCRDMA_COUNTER_BUFSIZ,
150 .mode = 0644,
151 .proc_handler = svcrdma_counter_handler,
152 },
153 {
154 .procname = "rdma_stat_write",
155 .data = &svcrdma_stat_write,
156 .maxlen = SVCRDMA_COUNTER_BUFSIZ,
157 .mode = 0644,
158 .proc_handler = svcrdma_counter_handler,
159 },
160 {
161 .procname = "rdma_stat_sq_starve",
162 .data = &svcrdma_stat_sq_starve,
163 .maxlen = SVCRDMA_COUNTER_BUFSIZ,
164 .mode = 0644,
165 .proc_handler = svcrdma_counter_handler,
166 },
167 {
168 .procname = "rdma_stat_rq_starve",
169 .data = &svcrdma_stat_unused,
170 .maxlen = sizeof(unsigned int),
171 .mode = 0644,
172 .proc_handler = proc_dointvec_minmax,
173 .extra1 = &zero,
174 .extra2 = &zero,
175 },
176 {
177 .procname = "rdma_stat_rq_poll",
178 .data = &svcrdma_stat_unused,
179 .maxlen = sizeof(unsigned int),
180 .mode = 0644,
181 .proc_handler = proc_dointvec_minmax,
182 .extra1 = &zero,
183 .extra2 = &zero,
184 },
185 {
186 .procname = "rdma_stat_rq_prod",
187 .data = &svcrdma_stat_unused,
188 .maxlen = sizeof(unsigned int),
189 .mode = 0644,
190 .proc_handler = proc_dointvec_minmax,
191 .extra1 = &zero,
192 .extra2 = &zero,
193 },
194 {
195 .procname = "rdma_stat_sq_poll",
196 .data = &svcrdma_stat_unused,
197 .maxlen = sizeof(unsigned int),
198 .mode = 0644,
199 .proc_handler = proc_dointvec_minmax,
200 .extra1 = &zero,
201 .extra2 = &zero,
202 },
203 {
204 .procname = "rdma_stat_sq_prod",
205 .data = &svcrdma_stat_unused,
206 .maxlen = sizeof(unsigned int),
207 .mode = 0644,
208 .proc_handler = proc_dointvec_minmax,
209 .extra1 = &zero,
210 .extra2 = &zero,
211 },
212 { },
213};
214
215static struct ctl_table svcrdma_table[] = {
216 {
217 .procname = "svc_rdma",
218 .mode = 0555,
219 .child = svcrdma_parm_table
220 },
221 { },
222};
223
224static struct ctl_table svcrdma_root_table[] = {
225 {
226 .procname = "sunrpc",
227 .mode = 0555,
228 .child = svcrdma_table
229 },
230 { },
231};
232
233static void svc_rdma_proc_cleanup(void)
234{
235 if (!svcrdma_table_header)
236 return;
237 unregister_sysctl_table(svcrdma_table_header);
238 svcrdma_table_header = NULL;
239
240 percpu_counter_destroy(&svcrdma_stat_write);
241 percpu_counter_destroy(&svcrdma_stat_sq_starve);
242 percpu_counter_destroy(&svcrdma_stat_recv);
243 percpu_counter_destroy(&svcrdma_stat_read);
244}
245
246static int svc_rdma_proc_init(void)
247{
248 int rc;
249
250 if (svcrdma_table_header)
251 return 0;
252
253 rc = percpu_counter_init(&svcrdma_stat_read, 0, GFP_KERNEL);
254 if (rc)
255 goto out_err;
256 rc = percpu_counter_init(&svcrdma_stat_recv, 0, GFP_KERNEL);
257 if (rc)
258 goto out_err;
259 rc = percpu_counter_init(&svcrdma_stat_sq_starve, 0, GFP_KERNEL);
260 if (rc)
261 goto out_err;
262 rc = percpu_counter_init(&svcrdma_stat_write, 0, GFP_KERNEL);
263 if (rc)
264 goto out_err;
265
266 svcrdma_table_header = register_sysctl_table(svcrdma_root_table);
267 return 0;
268
269out_err:
270 percpu_counter_destroy(&svcrdma_stat_sq_starve);
271 percpu_counter_destroy(&svcrdma_stat_recv);
272 percpu_counter_destroy(&svcrdma_stat_read);
273 return rc;
274}
275
276void svc_rdma_cleanup(void)
277{
278 dprintk("SVCRDMA Module Removed, deregister RPC RDMA transport\n");
279 svc_unreg_xprt_class(&svc_rdma_class);
280 svc_rdma_proc_cleanup();
281}
282
283int svc_rdma_init(void)
284{
285 int rc;
286
287 dprintk("SVCRDMA Module Init, register RPC RDMA transport\n");
288 dprintk("\tsvcrdma_ord : %d\n", svcrdma_ord);
289 dprintk("\tmax_requests : %u\n", svcrdma_max_requests);
290 dprintk("\tmax_bc_requests : %u\n", svcrdma_max_bc_requests);
291 dprintk("\tmax_inline : %d\n", svcrdma_max_req_size);
292
293 rc = svc_rdma_proc_init();
294 if (rc)
295 return rc;
296
297
298 svc_reg_xprt_class(&svc_rdma_class);
299 return 0;
300}
301