162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* SCTP kernel implementation 362306a36Sopenharmony_ci * (C) Copyright IBM Corp. 2001, 2004 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * This file is part of the SCTP kernel implementation 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Support for memory object debugging. This allows one to monitor the 862306a36Sopenharmony_ci * object allocations/deallocations for types instrumented for this 962306a36Sopenharmony_ci * via the proc fs. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Please send any bug reports or fixes you make to the 1262306a36Sopenharmony_ci * email address(es): 1362306a36Sopenharmony_ci * lksctp developers <linux-sctp@vger.kernel.org> 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * Written or modified by: 1662306a36Sopenharmony_ci * Jon Grimm <jgrimm@us.ibm.com> 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/kernel.h> 2262306a36Sopenharmony_ci#include <net/sctp/sctp.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* 2562306a36Sopenharmony_ci * Global counters to count raw object allocation counts. 2662306a36Sopenharmony_ci * To add new counters, choose a unique suffix for the variable 2762306a36Sopenharmony_ci * name as the helper macros key off this suffix to make 2862306a36Sopenharmony_ci * life easier for the programmer. 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciSCTP_DBG_OBJCNT(sock); 3262306a36Sopenharmony_ciSCTP_DBG_OBJCNT(ep); 3362306a36Sopenharmony_ciSCTP_DBG_OBJCNT(transport); 3462306a36Sopenharmony_ciSCTP_DBG_OBJCNT(assoc); 3562306a36Sopenharmony_ciSCTP_DBG_OBJCNT(bind_addr); 3662306a36Sopenharmony_ciSCTP_DBG_OBJCNT(bind_bucket); 3762306a36Sopenharmony_ciSCTP_DBG_OBJCNT(chunk); 3862306a36Sopenharmony_ciSCTP_DBG_OBJCNT(addr); 3962306a36Sopenharmony_ciSCTP_DBG_OBJCNT(datamsg); 4062306a36Sopenharmony_ciSCTP_DBG_OBJCNT(keys); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* An array to make it easy to pretty print the debug information 4362306a36Sopenharmony_ci * to the proc fs. 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_cistatic struct sctp_dbg_objcnt_entry sctp_dbg_objcnt[] = { 4662306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(sock), 4762306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(ep), 4862306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(assoc), 4962306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(transport), 5062306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(chunk), 5162306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(bind_addr), 5262306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(bind_bucket), 5362306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(addr), 5462306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(datamsg), 5562306a36Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(keys), 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* Callback from procfs to read out objcount information. 5962306a36Sopenharmony_ci * Walk through the entries in the sctp_dbg_objcnt array, dumping 6062306a36Sopenharmony_ci * the raw object counts for each monitored type. 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_cistatic int sctp_objcnt_seq_show(struct seq_file *seq, void *v) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci int i; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci i = (int)*(loff_t *)v; 6762306a36Sopenharmony_ci seq_setwidth(seq, 127); 6862306a36Sopenharmony_ci seq_printf(seq, "%s: %d", sctp_dbg_objcnt[i].label, 6962306a36Sopenharmony_ci atomic_read(sctp_dbg_objcnt[i].counter)); 7062306a36Sopenharmony_ci seq_pad(seq, '\n'); 7162306a36Sopenharmony_ci return 0; 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic void *sctp_objcnt_seq_start(struct seq_file *seq, loff_t *pos) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos; 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic void sctp_objcnt_seq_stop(struct seq_file *seq, void *v) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci} 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistatic void *sctp_objcnt_seq_next(struct seq_file *seq, void *v, loff_t *pos) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci ++*pos; 8662306a36Sopenharmony_ci return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos; 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic const struct seq_operations sctp_objcnt_seq_ops = { 9062306a36Sopenharmony_ci .start = sctp_objcnt_seq_start, 9162306a36Sopenharmony_ci .next = sctp_objcnt_seq_next, 9262306a36Sopenharmony_ci .stop = sctp_objcnt_seq_stop, 9362306a36Sopenharmony_ci .show = sctp_objcnt_seq_show, 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* Initialize the objcount in the proc filesystem. */ 9762306a36Sopenharmony_civoid sctp_dbg_objcnt_init(struct net *net) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci struct proc_dir_entry *ent; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci ent = proc_create_seq("sctp_dbg_objcnt", 0, 10262306a36Sopenharmony_ci net->sctp.proc_net_sctp, &sctp_objcnt_seq_ops); 10362306a36Sopenharmony_ci if (!ent) 10462306a36Sopenharmony_ci pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n"); 10562306a36Sopenharmony_ci} 106