18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* SCTP kernel implementation 38c2ecf20Sopenharmony_ci * (C) Copyright IBM Corp. 2001, 2004 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This file is part of the SCTP kernel implementation 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Support for memory object debugging. This allows one to monitor the 88c2ecf20Sopenharmony_ci * object allocations/deallocations for types instrumented for this 98c2ecf20Sopenharmony_ci * via the proc fs. 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Please send any bug reports or fixes you make to the 128c2ecf20Sopenharmony_ci * email address(es): 138c2ecf20Sopenharmony_ci * lksctp developers <linux-sctp@vger.kernel.org> 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * Written or modified by: 168c2ecf20Sopenharmony_ci * Jon Grimm <jgrimm@us.ibm.com> 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <linux/kernel.h> 228c2ecf20Sopenharmony_ci#include <net/sctp/sctp.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* 258c2ecf20Sopenharmony_ci * Global counters to count raw object allocation counts. 268c2ecf20Sopenharmony_ci * To add new counters, choose a unique suffix for the variable 278c2ecf20Sopenharmony_ci * name as the helper macros key off this suffix to make 288c2ecf20Sopenharmony_ci * life easier for the programmer. 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(sock); 328c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(ep); 338c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(transport); 348c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(assoc); 358c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(bind_addr); 368c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(bind_bucket); 378c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(chunk); 388c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(addr); 398c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(datamsg); 408c2ecf20Sopenharmony_ciSCTP_DBG_OBJCNT(keys); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* An array to make it easy to pretty print the debug information 438c2ecf20Sopenharmony_ci * to the proc fs. 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_cistatic struct sctp_dbg_objcnt_entry sctp_dbg_objcnt[] = { 468c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(sock), 478c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(ep), 488c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(assoc), 498c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(transport), 508c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(chunk), 518c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(bind_addr), 528c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(bind_bucket), 538c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(addr), 548c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(datamsg), 558c2ecf20Sopenharmony_ci SCTP_DBG_OBJCNT_ENTRY(keys), 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/* Callback from procfs to read out objcount information. 598c2ecf20Sopenharmony_ci * Walk through the entries in the sctp_dbg_objcnt array, dumping 608c2ecf20Sopenharmony_ci * the raw object counts for each monitored type. 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_cistatic int sctp_objcnt_seq_show(struct seq_file *seq, void *v) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci int i; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci i = (int)*(loff_t *)v; 678c2ecf20Sopenharmony_ci seq_setwidth(seq, 127); 688c2ecf20Sopenharmony_ci seq_printf(seq, "%s: %d", sctp_dbg_objcnt[i].label, 698c2ecf20Sopenharmony_ci atomic_read(sctp_dbg_objcnt[i].counter)); 708c2ecf20Sopenharmony_ci seq_pad(seq, '\n'); 718c2ecf20Sopenharmony_ci return 0; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic void *sctp_objcnt_seq_start(struct seq_file *seq, loff_t *pos) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos; 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic void sctp_objcnt_seq_stop(struct seq_file *seq, void *v) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic void *sctp_objcnt_seq_next(struct seq_file *seq, void *v, loff_t *pos) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci ++*pos; 868c2ecf20Sopenharmony_ci return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos; 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic const struct seq_operations sctp_objcnt_seq_ops = { 908c2ecf20Sopenharmony_ci .start = sctp_objcnt_seq_start, 918c2ecf20Sopenharmony_ci .next = sctp_objcnt_seq_next, 928c2ecf20Sopenharmony_ci .stop = sctp_objcnt_seq_stop, 938c2ecf20Sopenharmony_ci .show = sctp_objcnt_seq_show, 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* Initialize the objcount in the proc filesystem. */ 978c2ecf20Sopenharmony_civoid sctp_dbg_objcnt_init(struct net *net) 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci struct proc_dir_entry *ent; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci ent = proc_create_seq("sctp_dbg_objcnt", 0, 1028c2ecf20Sopenharmony_ci net->sctp.proc_net_sctp, &sctp_objcnt_seq_ops); 1038c2ecf20Sopenharmony_ci if (!ent) 1048c2ecf20Sopenharmony_ci pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n"); 1058c2ecf20Sopenharmony_ci} 106