^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) Copyright IBM Corp. 2001, 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file is part of the SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Support for memory object debugging. This allows one to monitor the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * object allocations/deallocations for types instrumented for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * via the proc fs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Please send any bug reports or fixes you make to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * email address(es):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * lksctp developers <linux-sctp@vger.kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Written or modified by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Jon Grimm <jgrimm@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/sctp/sctp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Global counters to count raw object allocation counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * To add new counters, choose a unique suffix for the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * name as the helper macros key off this suffix to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * life easier for the programmer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) SCTP_DBG_OBJCNT(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) SCTP_DBG_OBJCNT(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) SCTP_DBG_OBJCNT(transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) SCTP_DBG_OBJCNT(assoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) SCTP_DBG_OBJCNT(bind_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) SCTP_DBG_OBJCNT(bind_bucket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) SCTP_DBG_OBJCNT(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) SCTP_DBG_OBJCNT(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) SCTP_DBG_OBJCNT(datamsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) SCTP_DBG_OBJCNT(keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* An array to make it easy to pretty print the debug information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * to the proc fs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static struct sctp_dbg_objcnt_entry sctp_dbg_objcnt[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) SCTP_DBG_OBJCNT_ENTRY(sock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) SCTP_DBG_OBJCNT_ENTRY(ep),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) SCTP_DBG_OBJCNT_ENTRY(assoc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) SCTP_DBG_OBJCNT_ENTRY(transport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) SCTP_DBG_OBJCNT_ENTRY(chunk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) SCTP_DBG_OBJCNT_ENTRY(bind_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) SCTP_DBG_OBJCNT_ENTRY(bind_bucket),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) SCTP_DBG_OBJCNT_ENTRY(addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) SCTP_DBG_OBJCNT_ENTRY(datamsg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) SCTP_DBG_OBJCNT_ENTRY(keys),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Callback from procfs to read out objcount information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Walk through the entries in the sctp_dbg_objcnt array, dumping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * the raw object counts for each monitored type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) i = (int)*(loff_t *)v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) seq_setwidth(seq, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) seq_printf(seq, "%s: %d", sctp_dbg_objcnt[i].label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) atomic_read(sctp_dbg_objcnt[i].counter));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) seq_pad(seq, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static void *sctp_objcnt_seq_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static void sctp_objcnt_seq_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static void *sctp_objcnt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const struct seq_operations sctp_objcnt_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .start = sctp_objcnt_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .next = sctp_objcnt_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .stop = sctp_objcnt_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .show = sctp_objcnt_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Initialize the objcount in the proc filesystem. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) void sctp_dbg_objcnt_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct proc_dir_entry *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ent = proc_create_seq("sctp_dbg_objcnt", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) net->sctp.proc_net_sctp, &sctp_objcnt_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }