objcnt.c 2.8 KB

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