root/net/kcm/kcmproc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kcm_get_first
  2. kcm_get_next
  3. kcm_get_idx
  4. kcm_seq_next
  5. kcm_seq_start
  6. kcm_seq_stop
  7. kcm_format_mux_header
  8. kcm_format_sock
  9. kcm_format_psock
  10. kcm_format_mux
  11. kcm_seq_show
  12. kcm_stats_seq_show
  13. kcm_proc_init_net
  14. kcm_proc_exit_net
  15. kcm_proc_init
  16. kcm_proc_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/in.h>
   3 #include <linux/inet.h>
   4 #include <linux/list.h>
   5 #include <linux/module.h>
   6 #include <linux/net.h>
   7 #include <linux/proc_fs.h>
   8 #include <linux/rculist.h>
   9 #include <linux/seq_file.h>
  10 #include <linux/socket.h>
  11 #include <net/inet_sock.h>
  12 #include <net/kcm.h>
  13 #include <net/net_namespace.h>
  14 #include <net/netns/generic.h>
  15 #include <net/tcp.h>
  16 
  17 #ifdef CONFIG_PROC_FS
  18 static struct kcm_mux *kcm_get_first(struct seq_file *seq)
  19 {
  20         struct net *net = seq_file_net(seq);
  21         struct kcm_net *knet = net_generic(net, kcm_net_id);
  22 
  23         return list_first_or_null_rcu(&knet->mux_list,
  24                                       struct kcm_mux, kcm_mux_list);
  25 }
  26 
  27 static struct kcm_mux *kcm_get_next(struct kcm_mux *mux)
  28 {
  29         struct kcm_net *knet = mux->knet;
  30 
  31         return list_next_or_null_rcu(&knet->mux_list, &mux->kcm_mux_list,
  32                                      struct kcm_mux, kcm_mux_list);
  33 }
  34 
  35 static struct kcm_mux *kcm_get_idx(struct seq_file *seq, loff_t pos)
  36 {
  37         struct net *net = seq_file_net(seq);
  38         struct kcm_net *knet = net_generic(net, kcm_net_id);
  39         struct kcm_mux *m;
  40 
  41         list_for_each_entry_rcu(m, &knet->mux_list, kcm_mux_list) {
  42                 if (!pos)
  43                         return m;
  44                 --pos;
  45         }
  46         return NULL;
  47 }
  48 
  49 static void *kcm_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  50 {
  51         void *p;
  52 
  53         if (v == SEQ_START_TOKEN)
  54                 p = kcm_get_first(seq);
  55         else
  56                 p = kcm_get_next(v);
  57         ++*pos;
  58         return p;
  59 }
  60 
  61 static void *kcm_seq_start(struct seq_file *seq, loff_t *pos)
  62         __acquires(rcu)
  63 {
  64         rcu_read_lock();
  65 
  66         if (!*pos)
  67                 return SEQ_START_TOKEN;
  68         else
  69                 return kcm_get_idx(seq, *pos - 1);
  70 }
  71 
  72 static void kcm_seq_stop(struct seq_file *seq, void *v)
  73         __releases(rcu)
  74 {
  75         rcu_read_unlock();
  76 }
  77 
  78 struct kcm_proc_mux_state {
  79         struct seq_net_private p;
  80         int idx;
  81 };
  82 
  83 static void kcm_format_mux_header(struct seq_file *seq)
  84 {
  85         struct net *net = seq_file_net(seq);
  86         struct kcm_net *knet = net_generic(net, kcm_net_id);
  87 
  88         seq_printf(seq,
  89                    "*** KCM statistics (%d MUX) ****\n",
  90                    knet->count);
  91 
  92         seq_printf(seq,
  93                    "%-14s %-10s %-16s %-10s %-16s %-8s %-8s %-8s %-8s %s",
  94                    "Object",
  95                    "RX-Msgs",
  96                    "RX-Bytes",
  97                    "TX-Msgs",
  98                    "TX-Bytes",
  99                    "Recv-Q",
 100                    "Rmem",
 101                    "Send-Q",
 102                    "Smem",
 103                    "Status");
 104 
 105         /* XXX: pdsts header stuff here */
 106         seq_puts(seq, "\n");
 107 }
 108 
 109 static void kcm_format_sock(struct kcm_sock *kcm, struct seq_file *seq,
 110                             int i, int *len)
 111 {
 112         seq_printf(seq,
 113                    "   kcm-%-7u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8s ",
 114                    kcm->index,
 115                    kcm->stats.rx_msgs,
 116                    kcm->stats.rx_bytes,
 117                    kcm->stats.tx_msgs,
 118                    kcm->stats.tx_bytes,
 119                    kcm->sk.sk_receive_queue.qlen,
 120                    sk_rmem_alloc_get(&kcm->sk),
 121                    kcm->sk.sk_write_queue.qlen,
 122                    "-");
 123 
 124         if (kcm->tx_psock)
 125                 seq_printf(seq, "Psck-%u ", kcm->tx_psock->index);
 126 
 127         if (kcm->tx_wait)
 128                 seq_puts(seq, "TxWait ");
 129 
 130         if (kcm->tx_wait_more)
 131                 seq_puts(seq, "WMore ");
 132 
 133         if (kcm->rx_wait)
 134                 seq_puts(seq, "RxWait ");
 135 
 136         seq_puts(seq, "\n");
 137 }
 138 
 139 static void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq,
 140                              int i, int *len)
 141 {
 142         seq_printf(seq,
 143                    "   psock-%-5u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8d ",
 144                    psock->index,
 145                    psock->strp.stats.msgs,
 146                    psock->strp.stats.bytes,
 147                    psock->stats.tx_msgs,
 148                    psock->stats.tx_bytes,
 149                    psock->sk->sk_receive_queue.qlen,
 150                    atomic_read(&psock->sk->sk_rmem_alloc),
 151                    psock->sk->sk_write_queue.qlen,
 152                    refcount_read(&psock->sk->sk_wmem_alloc));
 153 
 154         if (psock->done)
 155                 seq_puts(seq, "Done ");
 156 
 157         if (psock->tx_stopped)
 158                 seq_puts(seq, "TxStop ");
 159 
 160         if (psock->strp.stopped)
 161                 seq_puts(seq, "RxStop ");
 162 
 163         if (psock->tx_kcm)
 164                 seq_printf(seq, "Rsvd-%d ", psock->tx_kcm->index);
 165 
 166         if (!psock->strp.paused && !psock->ready_rx_msg) {
 167                 if (psock->sk->sk_receive_queue.qlen) {
 168                         if (psock->strp.need_bytes)
 169                                 seq_printf(seq, "RxWait=%u ",
 170                                            psock->strp.need_bytes);
 171                         else
 172                                 seq_printf(seq, "RxWait ");
 173                 }
 174         } else  {
 175                 if (psock->strp.paused)
 176                         seq_puts(seq, "RxPause ");
 177 
 178                 if (psock->ready_rx_msg)
 179                         seq_puts(seq, "RdyRx ");
 180         }
 181 
 182         seq_puts(seq, "\n");
 183 }
 184 
 185 static void
 186 kcm_format_mux(struct kcm_mux *mux, loff_t idx, struct seq_file *seq)
 187 {
 188         int i, len;
 189         struct kcm_sock *kcm;
 190         struct kcm_psock *psock;
 191 
 192         /* mux information */
 193         seq_printf(seq,
 194                    "%-6s%-8s %-10llu %-16llu %-10llu %-16llu %-8s %-8s %-8s %-8s ",
 195                    "mux", "",
 196                    mux->stats.rx_msgs,
 197                    mux->stats.rx_bytes,
 198                    mux->stats.tx_msgs,
 199                    mux->stats.tx_bytes,
 200                    "-", "-", "-", "-");
 201 
 202         seq_printf(seq, "KCMs: %d, Psocks %d\n",
 203                    mux->kcm_socks_cnt, mux->psocks_cnt);
 204 
 205         /* kcm sock information */
 206         i = 0;
 207         spin_lock_bh(&mux->lock);
 208         list_for_each_entry(kcm, &mux->kcm_socks, kcm_sock_list) {
 209                 kcm_format_sock(kcm, seq, i, &len);
 210                 i++;
 211         }
 212         i = 0;
 213         list_for_each_entry(psock, &mux->psocks, psock_list) {
 214                 kcm_format_psock(psock, seq, i, &len);
 215                 i++;
 216         }
 217         spin_unlock_bh(&mux->lock);
 218 }
 219 
 220 static int kcm_seq_show(struct seq_file *seq, void *v)
 221 {
 222         struct kcm_proc_mux_state *mux_state;
 223 
 224         mux_state = seq->private;
 225         if (v == SEQ_START_TOKEN) {
 226                 mux_state->idx = 0;
 227                 kcm_format_mux_header(seq);
 228         } else {
 229                 kcm_format_mux(v, mux_state->idx, seq);
 230                 mux_state->idx++;
 231         }
 232         return 0;
 233 }
 234 
 235 static const struct seq_operations kcm_seq_ops = {
 236         .show   = kcm_seq_show,
 237         .start  = kcm_seq_start,
 238         .next   = kcm_seq_next,
 239         .stop   = kcm_seq_stop,
 240 };
 241 
 242 static int kcm_stats_seq_show(struct seq_file *seq, void *v)
 243 {
 244         struct kcm_psock_stats psock_stats;
 245         struct kcm_mux_stats mux_stats;
 246         struct strp_aggr_stats strp_stats;
 247         struct kcm_mux *mux;
 248         struct kcm_psock *psock;
 249         struct net *net = seq->private;
 250         struct kcm_net *knet = net_generic(net, kcm_net_id);
 251 
 252         memset(&mux_stats, 0, sizeof(mux_stats));
 253         memset(&psock_stats, 0, sizeof(psock_stats));
 254         memset(&strp_stats, 0, sizeof(strp_stats));
 255 
 256         mutex_lock(&knet->mutex);
 257 
 258         aggregate_mux_stats(&knet->aggregate_mux_stats, &mux_stats);
 259         aggregate_psock_stats(&knet->aggregate_psock_stats,
 260                               &psock_stats);
 261         aggregate_strp_stats(&knet->aggregate_strp_stats,
 262                              &strp_stats);
 263 
 264         list_for_each_entry_rcu(mux, &knet->mux_list, kcm_mux_list) {
 265                 spin_lock_bh(&mux->lock);
 266                 aggregate_mux_stats(&mux->stats, &mux_stats);
 267                 aggregate_psock_stats(&mux->aggregate_psock_stats,
 268                                       &psock_stats);
 269                 aggregate_strp_stats(&mux->aggregate_strp_stats,
 270                                      &strp_stats);
 271                 list_for_each_entry(psock, &mux->psocks, psock_list) {
 272                         aggregate_psock_stats(&psock->stats, &psock_stats);
 273                         save_strp_stats(&psock->strp, &strp_stats);
 274                 }
 275 
 276                 spin_unlock_bh(&mux->lock);
 277         }
 278 
 279         mutex_unlock(&knet->mutex);
 280 
 281         seq_printf(seq,
 282                    "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s\n",
 283                    "MUX",
 284                    "RX-Msgs",
 285                    "RX-Bytes",
 286                    "TX-Msgs",
 287                    "TX-Bytes",
 288                    "TX-Retries",
 289                    "Attach",
 290                    "Unattach",
 291                    "UnattchRsvd",
 292                    "RX-RdyDrops");
 293 
 294         seq_printf(seq,
 295                    "%-8s %-10llu %-16llu %-10llu %-16llu %-10u %-10u %-10u %-10u %-10u\n",
 296                    "",
 297                    mux_stats.rx_msgs,
 298                    mux_stats.rx_bytes,
 299                    mux_stats.tx_msgs,
 300                    mux_stats.tx_bytes,
 301                    mux_stats.tx_retries,
 302                    mux_stats.psock_attach,
 303                    mux_stats.psock_unattach_rsvd,
 304                    mux_stats.psock_unattach,
 305                    mux_stats.rx_ready_drops);
 306 
 307         seq_printf(seq,
 308                    "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s\n",
 309                    "Psock",
 310                    "RX-Msgs",
 311                    "RX-Bytes",
 312                    "TX-Msgs",
 313                    "TX-Bytes",
 314                    "Reserved",
 315                    "Unreserved",
 316                    "RX-Aborts",
 317                    "RX-Intr",
 318                    "RX-Unrecov",
 319                    "RX-MemFail",
 320                    "RX-NeedMor",
 321                    "RX-BadLen",
 322                    "RX-TooBig",
 323                    "RX-Timeout",
 324                    "TX-Aborts");
 325 
 326         seq_printf(seq,
 327                    "%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u\n",
 328                    "",
 329                    strp_stats.msgs,
 330                    strp_stats.bytes,
 331                    psock_stats.tx_msgs,
 332                    psock_stats.tx_bytes,
 333                    psock_stats.reserved,
 334                    psock_stats.unreserved,
 335                    strp_stats.aborts,
 336                    strp_stats.interrupted,
 337                    strp_stats.unrecov_intr,
 338                    strp_stats.mem_fail,
 339                    strp_stats.need_more_hdr,
 340                    strp_stats.bad_hdr_len,
 341                    strp_stats.msg_too_big,
 342                    strp_stats.msg_timeouts,
 343                    psock_stats.tx_aborts);
 344 
 345         return 0;
 346 }
 347 
 348 static int kcm_proc_init_net(struct net *net)
 349 {
 350         if (!proc_create_net_single("kcm_stats", 0444, net->proc_net,
 351                          kcm_stats_seq_show, NULL))
 352                 goto out_kcm_stats;
 353 
 354         if (!proc_create_net("kcm", 0444, net->proc_net, &kcm_seq_ops,
 355                         sizeof(struct kcm_proc_mux_state)))
 356                 goto out_kcm;
 357 
 358         return 0;
 359 
 360 out_kcm:
 361         remove_proc_entry("kcm_stats", net->proc_net);
 362 out_kcm_stats:
 363         return -ENOMEM;
 364 }
 365 
 366 static void kcm_proc_exit_net(struct net *net)
 367 {
 368         remove_proc_entry("kcm", net->proc_net);
 369         remove_proc_entry("kcm_stats", net->proc_net);
 370 }
 371 
 372 static struct pernet_operations kcm_net_ops = {
 373         .init = kcm_proc_init_net,
 374         .exit = kcm_proc_exit_net,
 375 };
 376 
 377 int __init kcm_proc_init(void)
 378 {
 379         return register_pernet_subsys(&kcm_net_ops);
 380 }
 381 
 382 void __exit kcm_proc_exit(void)
 383 {
 384         unregister_pernet_subsys(&kcm_net_ops);
 385 }
 386 
 387 #endif /* CONFIG_PROC_FS */

/* [<][>][^][v][top][bottom][index][help] */