xref: /openbmc/linux/net/sctp/objcnt.c (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
1*47505b8bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
260c778b2SVlad Yasevich /* SCTP kernel implementation
31da177e4SLinus Torvalds  * (C) Copyright IBM Corp. 2001, 2004
41da177e4SLinus Torvalds  *
560c778b2SVlad Yasevich  * This file is part of the SCTP kernel implementation
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * Support for memory object debugging.  This allows one to monitor the
81da177e4SLinus Torvalds  * object allocations/deallocations for types instrumented for this
91da177e4SLinus Torvalds  * via the proc fs.
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  * Please send any bug reports or fixes you make to the
121da177e4SLinus Torvalds  * email address(es):
1391705c61SDaniel Borkmann  *    lksctp developers <linux-sctp@vger.kernel.org>
141da177e4SLinus Torvalds  *
151da177e4SLinus Torvalds  * Written or modified by:
161da177e4SLinus Torvalds  *    Jon Grimm             <jgrimm@us.ibm.com>
171da177e4SLinus Torvalds  */
181da177e4SLinus Torvalds 
19145ce502SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20145ce502SJoe Perches 
211da177e4SLinus Torvalds #include <linux/kernel.h>
221da177e4SLinus Torvalds #include <net/sctp/sctp.h>
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds /*
251da177e4SLinus Torvalds  * Global counters to count raw object allocation counts.
261da177e4SLinus Torvalds  * To add new counters, choose a unique suffix for the variable
271da177e4SLinus Torvalds  * name as the helper macros key off this suffix to make
281da177e4SLinus Torvalds  * life easier for the programmer.
291da177e4SLinus Torvalds  */
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds SCTP_DBG_OBJCNT(sock);
321da177e4SLinus Torvalds SCTP_DBG_OBJCNT(ep);
331da177e4SLinus Torvalds SCTP_DBG_OBJCNT(transport);
341da177e4SLinus Torvalds SCTP_DBG_OBJCNT(assoc);
351da177e4SLinus Torvalds SCTP_DBG_OBJCNT(bind_addr);
361da177e4SLinus Torvalds SCTP_DBG_OBJCNT(bind_bucket);
371da177e4SLinus Torvalds SCTP_DBG_OBJCNT(chunk);
381da177e4SLinus Torvalds SCTP_DBG_OBJCNT(addr);
391da177e4SLinus Torvalds SCTP_DBG_OBJCNT(datamsg);
401f485649SVlad Yasevich SCTP_DBG_OBJCNT(keys);
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds /* An array to make it easy to pretty print the debug information
431da177e4SLinus Torvalds  * to the proc fs.
441da177e4SLinus Torvalds  */
45d38ef5aeSXin Long static struct sctp_dbg_objcnt_entry sctp_dbg_objcnt[] = {
461da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(sock),
471da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(ep),
481da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(assoc),
491da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(transport),
501da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(chunk),
511da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(bind_addr),
521da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(bind_bucket),
531da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(addr),
541da177e4SLinus Torvalds 	SCTP_DBG_OBJCNT_ENTRY(datamsg),
551f485649SVlad Yasevich 	SCTP_DBG_OBJCNT_ENTRY(keys),
561da177e4SLinus Torvalds };
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds /* Callback from procfs to read out objcount information.
591da177e4SLinus Torvalds  * Walk through the entries in the sctp_dbg_objcnt array, dumping
601da177e4SLinus Torvalds  * the raw object counts for each monitored type.
611da177e4SLinus Torvalds  */
sctp_objcnt_seq_show(struct seq_file * seq,void * v)628ff65b46SPavel Emelyanov static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
631da177e4SLinus Torvalds {
64652586dfSTetsuo Handa 	int i;
651da177e4SLinus Torvalds 
668ff65b46SPavel Emelyanov 	i = (int)*(loff_t *)v;
67652586dfSTetsuo Handa 	seq_setwidth(seq, 127);
68652586dfSTetsuo Handa 	seq_printf(seq, "%s: %d", sctp_dbg_objcnt[i].label,
69652586dfSTetsuo Handa 				atomic_read(sctp_dbg_objcnt[i].counter));
70652586dfSTetsuo Handa 	seq_pad(seq, '\n');
718ff65b46SPavel Emelyanov 	return 0;
721da177e4SLinus Torvalds }
731da177e4SLinus Torvalds 
sctp_objcnt_seq_start(struct seq_file * seq,loff_t * pos)748ff65b46SPavel Emelyanov static void *sctp_objcnt_seq_start(struct seq_file *seq, loff_t *pos)
758ff65b46SPavel Emelyanov {
768ff65b46SPavel Emelyanov 	return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos;
771da177e4SLinus Torvalds }
781da177e4SLinus Torvalds 
sctp_objcnt_seq_stop(struct seq_file * seq,void * v)798ff65b46SPavel Emelyanov static void sctp_objcnt_seq_stop(struct seq_file *seq, void *v)
808ff65b46SPavel Emelyanov {
818ff65b46SPavel Emelyanov }
828ff65b46SPavel Emelyanov 
sctp_objcnt_seq_next(struct seq_file * seq,void * v,loff_t * pos)838ff65b46SPavel Emelyanov static void *sctp_objcnt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
848ff65b46SPavel Emelyanov {
858ff65b46SPavel Emelyanov 	++*pos;
868ff65b46SPavel Emelyanov 	return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos;
878ff65b46SPavel Emelyanov }
888ff65b46SPavel Emelyanov 
898ff65b46SPavel Emelyanov static const struct seq_operations sctp_objcnt_seq_ops = {
908ff65b46SPavel Emelyanov 	.start = sctp_objcnt_seq_start,
918ff65b46SPavel Emelyanov 	.next  = sctp_objcnt_seq_next,
928ff65b46SPavel Emelyanov 	.stop  = sctp_objcnt_seq_stop,
938ff65b46SPavel Emelyanov 	.show  = sctp_objcnt_seq_show,
948ff65b46SPavel Emelyanov };
958ff65b46SPavel Emelyanov 
961da177e4SLinus Torvalds /* Initialize the objcount in the proc filesystem.  */
sctp_dbg_objcnt_init(struct net * net)9713d782f6SEric W. Biederman void sctp_dbg_objcnt_init(struct net *net)
981da177e4SLinus Torvalds {
99ee71a29eSChristophe Lucas 	struct proc_dir_entry *ent;
1008ff65b46SPavel Emelyanov 
101fddda2b7SChristoph Hellwig 	ent = proc_create_seq("sctp_dbg_objcnt", 0,
102fddda2b7SChristoph Hellwig 			  net->sctp.proc_net_sctp, &sctp_objcnt_seq_ops);
103ee71a29eSChristophe Lucas 	if (!ent)
104145ce502SJoe Perches 		pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n");
1051da177e4SLinus Torvalds }
106