8a2644600d3eb550e02efd66ece8b1d7d111a15c
[firefly-linux-kernel-4.4.55.git] / drivers / staging / lustre / lustre / libcfs / module.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/mm.h>
39 #include <linux/string.h>
40 #include <linux/stat.h>
41 #include <linux/errno.h>
42 #include <linux/unistd.h>
43 #include <net/sock.h>
44 #include <linux/uio.h>
45
46 #include <linux/uaccess.h>
47
48 #include <linux/fs.h>
49 #include <linux/file.h>
50 #include <linux/list.h>
51
52 #include <linux/sysctl.h>
53 #include <linux/debugfs.h>
54
55 # define DEBUG_SUBSYSTEM S_LNET
56
57 #include "../../include/linux/libcfs/libcfs.h"
58 #include <asm/div64.h>
59
60 #include "../../include/linux/libcfs/libcfs_crypto.h"
61 #include "../../include/linux/lnet/lib-lnet.h"
62 #include "../../include/linux/lnet/lnet.h"
63 #include "tracefile.h"
64
65 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
66 MODULE_DESCRIPTION("Portals v3.1");
67 MODULE_LICENSE("GPL");
68
69 extern struct miscdevice libcfs_dev;
70 extern struct cfs_wi_sched *cfs_sched_rehash;
71 extern void libcfs_init_nidstrings(void);
72
73 static void insert_debugfs(void);
74 static void remove_debugfs(void);
75
76 static struct dentry *lnet_debugfs_root;
77 extern char lnet_upcall[1024];
78 /**
79  * The path of debug log dump upcall script.
80  */
81 extern char lnet_debug_log_upcall[1024];
82
83 #define CTL_LNET        (0x100)
84
85 enum {
86         PSDEV_DEBUG = 1,          /* control debugging */
87         PSDEV_SUBSYSTEM_DEBUG,    /* control debugging */
88         PSDEV_PRINTK,        /* force all messages to console */
89         PSDEV_CONSOLE_RATELIMIT,  /* ratelimit console messages */
90         PSDEV_CONSOLE_MAX_DELAY_CS, /* maximum delay over which we skip messages */
91         PSDEV_CONSOLE_MIN_DELAY_CS, /* initial delay over which we skip messages */
92         PSDEV_CONSOLE_BACKOFF,    /* delay increase factor */
93         PSDEV_DEBUG_PATH,        /* crashdump log location */
94         PSDEV_DEBUG_DUMP_PATH,    /* crashdump tracelog location */
95         PSDEV_CPT_TABLE,          /* information about cpu partitions */
96         PSDEV_LNET_UPCALL,      /* User mode upcall script  */
97         PSDEV_LNET_MEMUSED,       /* bytes currently PORTAL_ALLOCated */
98         PSDEV_LNET_CATASTROPHE,   /* if we have LBUGged or panic'd */
99         PSDEV_LNET_PANIC_ON_LBUG, /* flag to panic on LBUG */
100         PSDEV_LNET_DUMP_KERNEL,   /* snapshot kernel debug buffer to file */
101         PSDEV_LNET_DAEMON_FILE,   /* spool kernel debug buffer to file */
102         PSDEV_LNET_DEBUG_MB,      /* size of debug buffer */
103         PSDEV_LNET_DEBUG_LOG_UPCALL, /* debug log upcall script */
104         PSDEV_LNET_WATCHDOG_RATELIMIT,  /* ratelimit watchdog messages  */
105         PSDEV_LNET_FORCE_LBUG,    /* hook to force an LBUG */
106         PSDEV_LNET_FAIL_LOC,      /* control test failures instrumentation */
107         PSDEV_LNET_FAIL_VAL,      /* userdata for fail loc */
108 };
109
110 static void kportal_memhog_free (struct libcfs_device_userstate *ldu)
111 {
112         struct page **level0p = &ldu->ldu_memhog_root_page;
113         struct page **level1p;
114         struct page **level2p;
115         int        count1;
116         int        count2;
117
118         if (*level0p != NULL) {
119
120                 level1p = (struct page **)page_address(*level0p);
121                 count1 = 0;
122
123                 while (count1 < PAGE_CACHE_SIZE/sizeof(struct page *) &&
124                        *level1p != NULL) {
125
126                         level2p = (struct page **)page_address(*level1p);
127                         count2 = 0;
128
129                         while (count2 < PAGE_CACHE_SIZE/sizeof(struct page *) &&
130                                *level2p != NULL) {
131
132                                 __free_page(*level2p);
133                                 ldu->ldu_memhog_pages--;
134                                 level2p++;
135                                 count2++;
136                         }
137
138                         __free_page(*level1p);
139                         ldu->ldu_memhog_pages--;
140                         level1p++;
141                         count1++;
142                 }
143
144                 __free_page(*level0p);
145                 ldu->ldu_memhog_pages--;
146
147                 *level0p = NULL;
148         }
149
150         LASSERT (ldu->ldu_memhog_pages == 0);
151 }
152
153 static int kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
154                      gfp_t flags)
155 {
156         struct page **level0p;
157         struct page **level1p;
158         struct page **level2p;
159         int        count1;
160         int        count2;
161
162         LASSERT (ldu->ldu_memhog_pages == 0);
163         LASSERT (ldu->ldu_memhog_root_page == NULL);
164
165         if (npages < 0)
166                 return -EINVAL;
167
168         if (npages == 0)
169                 return 0;
170
171         level0p = &ldu->ldu_memhog_root_page;
172         *level0p = alloc_page(flags);
173         if (*level0p == NULL)
174                 return -ENOMEM;
175         ldu->ldu_memhog_pages++;
176
177         level1p = (struct page **)page_address(*level0p);
178         count1 = 0;
179         memset(level1p, 0, PAGE_CACHE_SIZE);
180
181         while (ldu->ldu_memhog_pages < npages &&
182                count1 < PAGE_CACHE_SIZE/sizeof(struct page *)) {
183
184                 if (cfs_signal_pending())
185                         return -EINTR;
186
187                 *level1p = alloc_page(flags);
188                 if (*level1p == NULL)
189                         return -ENOMEM;
190                 ldu->ldu_memhog_pages++;
191
192                 level2p = (struct page **)page_address(*level1p);
193                 count2 = 0;
194                 memset(level2p, 0, PAGE_CACHE_SIZE);
195
196                 while (ldu->ldu_memhog_pages < npages &&
197                        count2 < PAGE_CACHE_SIZE/sizeof(struct page *)) {
198
199                         if (cfs_signal_pending())
200                                 return -EINTR;
201
202                         *level2p = alloc_page(flags);
203                         if (*level2p == NULL)
204                                 return -ENOMEM;
205                         ldu->ldu_memhog_pages++;
206
207                         level2p++;
208                         count2++;
209                 }
210
211                 level1p++;
212                 count1++;
213         }
214
215         return 0;
216 }
217
218 /* called when opening /dev/device */
219 static int libcfs_psdev_open(unsigned long flags, void *args)
220 {
221         struct libcfs_device_userstate *ldu;
222
223         try_module_get(THIS_MODULE);
224
225         LIBCFS_ALLOC(ldu, sizeof(*ldu));
226         if (ldu != NULL) {
227                 ldu->ldu_memhog_pages = 0;
228                 ldu->ldu_memhog_root_page = NULL;
229         }
230         *(struct libcfs_device_userstate **)args = ldu;
231
232         return 0;
233 }
234
235 /* called when closing /dev/device */
236 static int libcfs_psdev_release(unsigned long flags, void *args)
237 {
238         struct libcfs_device_userstate *ldu;
239
240         ldu = (struct libcfs_device_userstate *)args;
241         if (ldu != NULL) {
242                 kportal_memhog_free(ldu);
243                 LIBCFS_FREE(ldu, sizeof(*ldu));
244         }
245
246         module_put(THIS_MODULE);
247         return 0;
248 }
249
250 static DECLARE_RWSEM(ioctl_list_sem);
251 static LIST_HEAD(ioctl_list);
252
253 int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand)
254 {
255         int rc = 0;
256
257         down_write(&ioctl_list_sem);
258         if (!list_empty(&hand->item))
259                 rc = -EBUSY;
260         else
261                 list_add_tail(&hand->item, &ioctl_list);
262         up_write(&ioctl_list_sem);
263
264         return rc;
265 }
266 EXPORT_SYMBOL(libcfs_register_ioctl);
267
268 int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)
269 {
270         int rc = 0;
271
272         down_write(&ioctl_list_sem);
273         if (list_empty(&hand->item))
274                 rc = -ENOENT;
275         else
276                 list_del_init(&hand->item);
277         up_write(&ioctl_list_sem);
278
279         return rc;
280 }
281 EXPORT_SYMBOL(libcfs_deregister_ioctl);
282
283 static int libcfs_ioctl_int(struct cfs_psdev_file *pfile, unsigned long cmd,
284                             void *arg, struct libcfs_ioctl_data *data)
285 {
286         int err = -EINVAL;
287
288         switch (cmd) {
289         case IOC_LIBCFS_CLEAR_DEBUG:
290                 libcfs_debug_clear_buffer();
291                 return 0;
292         /*
293          * case IOC_LIBCFS_PANIC:
294          * Handled in arch/cfs_module.c
295          */
296         case IOC_LIBCFS_MARK_DEBUG:
297                 if (data->ioc_inlbuf1 == NULL ||
298                     data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0')
299                         return -EINVAL;
300                 libcfs_debug_mark_buffer(data->ioc_inlbuf1);
301                 return 0;
302         case IOC_LIBCFS_MEMHOG:
303                 if (pfile->private_data == NULL) {
304                         err = -EINVAL;
305                 } else {
306                         kportal_memhog_free(pfile->private_data);
307                         /* XXX The ioc_flags is not GFP flags now, need to be fixed */
308                         err = kportal_memhog_alloc(pfile->private_data,
309                                                    data->ioc_count,
310                                                    data->ioc_flags);
311                         if (err != 0)
312                                 kportal_memhog_free(pfile->private_data);
313                 }
314                 break;
315
316         case IOC_LIBCFS_PING_TEST: {
317                 extern void (kping_client)(struct libcfs_ioctl_data *);
318                 void (*ping)(struct libcfs_ioctl_data *);
319
320                 CDEBUG(D_IOCTL, "doing %d pings to nid %s (%s)\n",
321                        data->ioc_count, libcfs_nid2str(data->ioc_nid),
322                        libcfs_nid2str(data->ioc_nid));
323                 ping = symbol_get(kping_client);
324                 if (!ping)
325                         CERROR("symbol_get failed\n");
326                 else {
327                         ping(data);
328                         symbol_put(kping_client);
329                 }
330                 return 0;
331         }
332
333         default: {
334                 struct libcfs_ioctl_handler *hand;
335                 err = -EINVAL;
336                 down_read(&ioctl_list_sem);
337                 list_for_each_entry(hand, &ioctl_list, item) {
338                         err = hand->handle_ioctl(cmd, data);
339                         if (err != -EINVAL) {
340                                 if (err == 0)
341                                         err = libcfs_ioctl_popdata(arg,
342                                                         data, sizeof (*data));
343                                 break;
344                         }
345                 }
346                 up_read(&ioctl_list_sem);
347                 break;
348         }
349         }
350
351         return err;
352 }
353
354 static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, void *arg)
355 {
356         char    *buf;
357         struct libcfs_ioctl_data *data;
358         int err = 0;
359
360         LIBCFS_ALLOC_GFP(buf, 1024, GFP_IOFS);
361         if (buf == NULL)
362                 return -ENOMEM;
363
364         /* 'cmd' and permissions get checked in our arch-specific caller */
365         if (libcfs_ioctl_getdata(buf, buf + 800, (void *)arg)) {
366                 CERROR("PORTALS ioctl: data error\n");
367                 err = -EINVAL;
368                 goto out;
369         }
370         data = (struct libcfs_ioctl_data *)buf;
371
372         err = libcfs_ioctl_int(pfile, cmd, arg, data);
373
374 out:
375         LIBCFS_FREE(buf, 1024);
376         return err;
377 }
378
379
380 struct cfs_psdev_ops libcfs_psdev_ops = {
381         libcfs_psdev_open,
382         libcfs_psdev_release,
383         NULL,
384         NULL,
385         libcfs_ioctl
386 };
387
388 static int init_libcfs_module(void)
389 {
390         int rc;
391
392         libcfs_arch_init();
393         libcfs_init_nidstrings();
394
395         rc = libcfs_debug_init(5 * 1024 * 1024);
396         if (rc < 0) {
397                 pr_err("LustreError: libcfs_debug_init: %d\n", rc);
398                 return rc;
399         }
400
401         rc = cfs_cpu_init();
402         if (rc != 0)
403                 goto cleanup_debug;
404
405         rc = misc_register(&libcfs_dev);
406         if (rc) {
407                 CERROR("misc_register: error %d\n", rc);
408                 goto cleanup_cpu;
409         }
410
411         rc = cfs_wi_startup();
412         if (rc) {
413                 CERROR("initialize workitem: error %d\n", rc);
414                 goto cleanup_deregister;
415         }
416
417         /* max to 4 threads, should be enough for rehash */
418         rc = min(cfs_cpt_weight(cfs_cpt_table, CFS_CPT_ANY), 4);
419         rc = cfs_wi_sched_create("cfs_rh", cfs_cpt_table, CFS_CPT_ANY,
420                                  rc, &cfs_sched_rehash);
421         if (rc != 0) {
422                 CERROR("Startup workitem scheduler: error: %d\n", rc);
423                 goto cleanup_deregister;
424         }
425
426         rc = cfs_crypto_register();
427         if (rc) {
428                 CERROR("cfs_crypto_register: error %d\n", rc);
429                 goto cleanup_wi;
430         }
431
432         insert_debugfs();
433
434         CDEBUG (D_OTHER, "portals setup OK\n");
435         return 0;
436  cleanup_wi:
437         cfs_wi_shutdown();
438  cleanup_deregister:
439         misc_deregister(&libcfs_dev);
440 cleanup_cpu:
441         cfs_cpu_fini();
442  cleanup_debug:
443         libcfs_debug_cleanup();
444         return rc;
445 }
446
447 static void exit_libcfs_module(void)
448 {
449         int rc;
450
451         remove_debugfs();
452
453         CDEBUG(D_MALLOC, "before Portals cleanup: kmem %d\n",
454                atomic_read(&libcfs_kmemory));
455
456         if (cfs_sched_rehash != NULL) {
457                 cfs_wi_sched_destroy(cfs_sched_rehash);
458                 cfs_sched_rehash = NULL;
459         }
460
461         cfs_crypto_unregister();
462         cfs_wi_shutdown();
463
464         rc = misc_deregister(&libcfs_dev);
465         if (rc)
466                 CERROR("misc_deregister error %d\n", rc);
467
468         cfs_cpu_fini();
469
470         if (atomic_read(&libcfs_kmemory) != 0)
471                 CERROR("Portals memory leaked: %d bytes\n",
472                        atomic_read(&libcfs_kmemory));
473
474         rc = libcfs_debug_cleanup();
475         if (rc)
476                 pr_err("LustreError: libcfs_debug_cleanup: %d\n", rc);
477
478         libcfs_arch_cleanup();
479 }
480
481 static int proc_call_handler(void *data, int write, loff_t *ppos,
482                 void __user *buffer, size_t *lenp,
483                 int (*handler)(void *data, int write,
484                 loff_t pos, void __user *buffer, int len))
485 {
486         int rc = handler(data, write, *ppos, buffer, *lenp);
487
488         if (rc < 0)
489                 return rc;
490
491         if (write) {
492                 *ppos += *lenp;
493         } else {
494                 *lenp = rc;
495                 *ppos += rc;
496         }
497         return 0;
498 }
499
500 static int __proc_dobitmasks(void *data, int write,
501                              loff_t pos, void __user *buffer, int nob)
502 {
503         const int     tmpstrlen = 512;
504         char     *tmpstr;
505         int        rc;
506         unsigned int *mask = data;
507         int        is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0;
508         int        is_printk = (mask == &libcfs_printk) ? 1 : 0;
509
510         rc = cfs_trace_allocate_string_buffer(&tmpstr, tmpstrlen);
511         if (rc < 0)
512                 return rc;
513
514         if (!write) {
515                 libcfs_debug_mask2str(tmpstr, tmpstrlen, *mask, is_subsys);
516                 rc = strlen(tmpstr);
517
518                 if (pos >= rc) {
519                         rc = 0;
520                 } else {
521                         rc = cfs_trace_copyout_string(buffer, nob,
522                                                       tmpstr + pos, "\n");
523                 }
524         } else {
525                 rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob);
526                 if (rc < 0) {
527                         cfs_trace_free_string_buffer(tmpstr, tmpstrlen);
528                         return rc;
529                 }
530
531                 rc = libcfs_debug_str2mask(mask, tmpstr, is_subsys);
532                 /* Always print LBUG/LASSERT to console, so keep this mask */
533                 if (is_printk)
534                         *mask |= D_EMERG;
535         }
536
537         cfs_trace_free_string_buffer(tmpstr, tmpstrlen);
538         return rc;
539 }
540
541 static int proc_dobitmasks(struct ctl_table *table, int write,
542                            void __user *buffer, size_t *lenp, loff_t *ppos)
543 {
544         return proc_call_handler(table->data, write, ppos, buffer, lenp,
545                                  __proc_dobitmasks);
546 }
547
548 static int min_watchdog_ratelimit;        /* disable ratelimiting */
549 static int max_watchdog_ratelimit = (24*60*60); /* limit to once per day */
550
551 static int __proc_dump_kernel(void *data, int write,
552                               loff_t pos, void __user *buffer, int nob)
553 {
554         if (!write)
555                 return 0;
556
557         return cfs_trace_dump_debug_buffer_usrstr(buffer, nob);
558 }
559
560 static int proc_dump_kernel(struct ctl_table *table, int write,
561                             void __user *buffer, size_t *lenp, loff_t *ppos)
562 {
563         return proc_call_handler(table->data, write, ppos, buffer, lenp,
564                                  __proc_dump_kernel);
565 }
566
567 static int __proc_daemon_file(void *data, int write,
568                               loff_t pos, void __user *buffer, int nob)
569 {
570         if (!write) {
571                 int len = strlen(cfs_tracefile);
572
573                 if (pos >= len)
574                         return 0;
575
576                 return cfs_trace_copyout_string(buffer, nob,
577                                                 cfs_tracefile + pos, "\n");
578         }
579
580         return cfs_trace_daemon_command_usrstr(buffer, nob);
581 }
582
583 static int proc_daemon_file(struct ctl_table *table, int write,
584                             void __user *buffer, size_t *lenp, loff_t *ppos)
585 {
586         return proc_call_handler(table->data, write, ppos, buffer, lenp,
587                                  __proc_daemon_file);
588 }
589
590 static int __proc_debug_mb(void *data, int write,
591                            loff_t pos, void __user *buffer, int nob)
592 {
593         if (!write) {
594                 char tmpstr[32];
595                 int  len = snprintf(tmpstr, sizeof(tmpstr), "%d",
596                                     cfs_trace_get_debug_mb());
597
598                 if (pos >= len)
599                         return 0;
600
601                 return cfs_trace_copyout_string(buffer, nob, tmpstr + pos,
602                        "\n");
603         }
604
605         return cfs_trace_set_debug_mb_usrstr(buffer, nob);
606 }
607
608 static int proc_debug_mb(struct ctl_table *table, int write,
609                          void __user *buffer, size_t *lenp, loff_t *ppos)
610 {
611         return proc_call_handler(table->data, write, ppos, buffer, lenp,
612                                  __proc_debug_mb);
613 }
614
615 static int proc_console_max_delay_cs(struct ctl_table *table, int write,
616                                      void __user *buffer, size_t *lenp,
617                                      loff_t *ppos)
618 {
619         int rc, max_delay_cs;
620         struct ctl_table dummy = *table;
621         long d;
622
623         dummy.data = &max_delay_cs;
624         dummy.proc_handler = &proc_dointvec;
625
626         if (!write) { /* read */
627                 max_delay_cs = cfs_duration_sec(libcfs_console_max_delay * 100);
628                 rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
629                 return rc;
630         }
631
632         /* write */
633         max_delay_cs = 0;
634         rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
635         if (rc < 0)
636                 return rc;
637         if (max_delay_cs <= 0)
638                 return -EINVAL;
639
640         d = cfs_time_seconds(max_delay_cs) / 100;
641         if (d == 0 || d < libcfs_console_min_delay)
642                 return -EINVAL;
643         libcfs_console_max_delay = d;
644
645         return rc;
646 }
647
648 static int proc_console_min_delay_cs(struct ctl_table *table, int write,
649                                      void __user *buffer, size_t *lenp,
650                                      loff_t *ppos)
651 {
652         int rc, min_delay_cs;
653         struct ctl_table dummy = *table;
654         long d;
655
656         dummy.data = &min_delay_cs;
657         dummy.proc_handler = &proc_dointvec;
658
659         if (!write) { /* read */
660                 min_delay_cs = cfs_duration_sec(libcfs_console_min_delay * 100);
661                 rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
662                 return rc;
663         }
664
665         /* write */
666         min_delay_cs = 0;
667         rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
668         if (rc < 0)
669                 return rc;
670         if (min_delay_cs <= 0)
671                 return -EINVAL;
672
673         d = cfs_time_seconds(min_delay_cs) / 100;
674         if (d == 0 || d > libcfs_console_max_delay)
675                 return -EINVAL;
676         libcfs_console_min_delay = d;
677
678         return rc;
679 }
680
681 static int proc_console_backoff(struct ctl_table *table, int write,
682                                 void __user *buffer, size_t *lenp, loff_t *ppos)
683 {
684         int rc, backoff;
685         struct ctl_table dummy = *table;
686
687         dummy.data = &backoff;
688         dummy.proc_handler = &proc_dointvec;
689
690         if (!write) { /* read */
691                 backoff = libcfs_console_backoff;
692                 rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
693                 return rc;
694         }
695
696         /* write */
697         backoff = 0;
698         rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
699         if (rc < 0)
700                 return rc;
701         if (backoff <= 0)
702                 return -EINVAL;
703
704         libcfs_console_backoff = backoff;
705
706         return rc;
707 }
708
709 static int libcfs_force_lbug(struct ctl_table *table, int write,
710                              void __user *buffer,
711                              size_t *lenp, loff_t *ppos)
712 {
713         if (write)
714                 LBUG();
715         return 0;
716 }
717
718 static int proc_fail_loc(struct ctl_table *table, int write,
719                          void __user *buffer,
720                          size_t *lenp, loff_t *ppos)
721 {
722         int rc;
723         long old_fail_loc = cfs_fail_loc;
724
725         rc = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
726         if (old_fail_loc != cfs_fail_loc)
727                 wake_up(&cfs_race_waitq);
728         return rc;
729 }
730
731 static int __proc_cpt_table(void *data, int write,
732                             loff_t pos, void __user *buffer, int nob)
733 {
734         char *buf = NULL;
735         int   len = 4096;
736         int   rc  = 0;
737
738         if (write)
739                 return -EPERM;
740
741         LASSERT(cfs_cpt_table != NULL);
742
743         while (1) {
744                 LIBCFS_ALLOC(buf, len);
745                 if (buf == NULL)
746                         return -ENOMEM;
747
748                 rc = cfs_cpt_table_print(cfs_cpt_table, buf, len);
749                 if (rc >= 0)
750                         break;
751
752                 if (rc == -EFBIG) {
753                         LIBCFS_FREE(buf, len);
754                         len <<= 1;
755                         continue;
756                 }
757                 goto out;
758         }
759
760         if (pos >= rc) {
761                 rc = 0;
762                 goto out;
763         }
764
765         rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
766  out:
767         if (buf != NULL)
768                 LIBCFS_FREE(buf, len);
769         return rc;
770 }
771
772 static int proc_cpt_table(struct ctl_table *table, int write,
773                            void __user *buffer, size_t *lenp, loff_t *ppos)
774 {
775         return proc_call_handler(table->data, write, ppos, buffer, lenp,
776                                  __proc_cpt_table);
777 }
778
779 static struct ctl_table lnet_table[] = {
780         /*
781          * NB No .strategy entries have been provided since sysctl(8) prefers
782          * to go via /proc for portability.
783          */
784         {
785                 .procname = "debug",
786                 .data     = &libcfs_debug,
787                 .maxlen   = sizeof(int),
788                 .mode     = 0644,
789                 .proc_handler = &proc_dobitmasks,
790         },
791         {
792                 .procname = "subsystem_debug",
793                 .data     = &libcfs_subsystem_debug,
794                 .maxlen   = sizeof(int),
795                 .mode     = 0644,
796                 .proc_handler = &proc_dobitmasks,
797         },
798         {
799                 .procname = "printk",
800                 .data     = &libcfs_printk,
801                 .maxlen   = sizeof(int),
802                 .mode     = 0644,
803                 .proc_handler = &proc_dobitmasks,
804         },
805         {
806                 .procname = "console_max_delay_centisecs",
807                 .maxlen   = sizeof(int),
808                 .mode     = 0644,
809                 .proc_handler = &proc_console_max_delay_cs
810         },
811         {
812                 .procname = "console_min_delay_centisecs",
813                 .maxlen   = sizeof(int),
814                 .mode     = 0644,
815                 .proc_handler = &proc_console_min_delay_cs
816         },
817         {
818                 .procname = "console_backoff",
819                 .maxlen   = sizeof(int),
820                 .mode     = 0644,
821                 .proc_handler = &proc_console_backoff
822         },
823
824         {
825                 .procname = "cpu_partition_table",
826                 .maxlen   = 128,
827                 .mode     = 0444,
828                 .proc_handler = &proc_cpt_table,
829         },
830
831         {
832                 .procname = "upcall",
833                 .data     = lnet_upcall,
834                 .maxlen   = sizeof(lnet_upcall),
835                 .mode     = 0644,
836                 .proc_handler = &proc_dostring,
837         },
838         {
839                 .procname = "debug_log_upcall",
840                 .data     = lnet_debug_log_upcall,
841                 .maxlen   = sizeof(lnet_debug_log_upcall),
842                 .mode     = 0644,
843                 .proc_handler = &proc_dostring,
844         },
845         {
846                 .procname = "lnet_memused",
847                 .data     = (int *)&libcfs_kmemory.counter,
848                 .maxlen   = sizeof(int),
849                 .mode     = 0444,
850                 .proc_handler = &proc_dointvec,
851         },
852         {
853                 .procname = "catastrophe",
854                 .data     = &libcfs_catastrophe,
855                 .maxlen   = sizeof(int),
856                 .mode     = 0444,
857                 .proc_handler = &proc_dointvec,
858         },
859         {
860                 .procname = "dump_kernel",
861                 .maxlen   = 256,
862                 .mode     = 0200,
863                 .proc_handler = &proc_dump_kernel,
864         },
865         {
866                 .procname = "daemon_file",
867                 .mode     = 0644,
868                 .maxlen   = 256,
869                 .proc_handler = &proc_daemon_file,
870         },
871         {
872                 .procname = "debug_mb",
873                 .mode     = 0644,
874                 .proc_handler = &proc_debug_mb,
875         },
876         {
877                 .procname = "watchdog_ratelimit",
878                 .data     = &libcfs_watchdog_ratelimit,
879                 .maxlen   = sizeof(int),
880                 .mode     = 0644,
881                 .proc_handler = &proc_dointvec_minmax,
882                 .extra1   = &min_watchdog_ratelimit,
883                 .extra2   = &max_watchdog_ratelimit,
884         },
885         {
886                 .procname = "force_lbug",
887                 .data     = NULL,
888                 .maxlen   = 0,
889                 .mode     = 0200,
890                 .proc_handler = &libcfs_force_lbug
891         },
892         {
893                 .procname = "fail_loc",
894                 .data     = &cfs_fail_loc,
895                 .maxlen   = sizeof(cfs_fail_loc),
896                 .mode     = 0644,
897                 .proc_handler = &proc_fail_loc
898         },
899         {
900                 .procname = "fail_val",
901                 .data     = &cfs_fail_val,
902                 .maxlen   = sizeof(int),
903                 .mode     = 0644,
904                 .proc_handler = &proc_dointvec
905         },
906         {
907         }
908 };
909
910 static ssize_t lnet_debugfs_read(struct file *filp, char __user *buf,
911                                  size_t count, loff_t *ppos)
912 {
913         struct ctl_table *table = filp->private_data;
914         int error;
915
916         error = table->proc_handler(table, 0, (void __user *)buf, &count, ppos);
917         if (!error)
918                 error = count;
919
920         return error;
921 }
922
923 static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
924                                   size_t count, loff_t *ppos)
925 {
926         struct ctl_table *table = filp->private_data;
927         int error;
928
929         error = table->proc_handler(table, 1, (void __user *)buf, &count, ppos);
930         if (!error)
931                 error = count;
932
933         return error;
934 }
935
936 static const struct file_operations lnet_debugfs_file_operations = {
937         .open           = simple_open,
938         .read           = lnet_debugfs_read,
939         .write          = lnet_debugfs_write,
940         .llseek         = default_llseek,
941 };
942
943 static void insert_debugfs(void)
944 {
945         struct ctl_table *table;
946         struct dentry *entry;
947
948         if (lnet_debugfs_root == NULL)
949                 lnet_debugfs_root = debugfs_create_dir("lnet", NULL);
950
951         /* Even if we cannot create, just ignore it altogether) */
952         if (IS_ERR_OR_NULL(lnet_debugfs_root))
953                 return;
954
955         for (table = lnet_table; table->procname; table++)
956                 entry = debugfs_create_file(table->procname, table->mode,
957                                             lnet_debugfs_root, table,
958                                             &lnet_debugfs_file_operations);
959 }
960
961 static void remove_debugfs(void)
962 {
963         if (lnet_debugfs_root != NULL)
964                 debugfs_remove_recursive(lnet_debugfs_root);
965
966         lnet_debugfs_root = NULL;
967 }
968
969 MODULE_VERSION("1.0.0");
970
971 module_init(init_libcfs_module);
972 module_exit(exit_libcfs_module);