aboutsummaryrefslogtreecommitdiffstats
path: root/net/xdp
diff options
context:
space:
mode:
authorMagnus Karlsson <magnus.karlsson@intel.com>2018-05-02 07:01:35 -0400
committerAlexei Starovoitov <ast@kernel.org>2018-05-03 18:55:25 -0400
commitaf75d9e02d08dc55ce6a1e42e485465c630d7349 (patch)
tree7185c5ca061b68c48b239ae8d2df958ac19223a8 /net/xdp
parent35fcde7f8deb51b707b161bf19cbd22363aef2df (diff)
xsk: statistics support
In this commit, a new getsockopt is added: XDP_STATISTICS. This is used to obtain stats from the sockets. v2: getsockopt now returns size of stats structure. Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'net/xdp')
-rw-r--r--net/xdp/xsk.c45
-rw-r--r--net/xdp/xsk_queue.h5
2 files changed, 49 insertions, 1 deletions
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index b33c535c7996..009c5af5bba5 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -468,6 +468,49 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
468 return -ENOPROTOOPT; 468 return -ENOPROTOOPT;
469} 469}
470 470
471static int xsk_getsockopt(struct socket *sock, int level, int optname,
472 char __user *optval, int __user *optlen)
473{
474 struct sock *sk = sock->sk;
475 struct xdp_sock *xs = xdp_sk(sk);
476 int len;
477
478 if (level != SOL_XDP)
479 return -ENOPROTOOPT;
480
481 if (get_user(len, optlen))
482 return -EFAULT;
483 if (len < 0)
484 return -EINVAL;
485
486 switch (optname) {
487 case XDP_STATISTICS:
488 {
489 struct xdp_statistics stats;
490
491 if (len < sizeof(stats))
492 return -EINVAL;
493
494 mutex_lock(&xs->mutex);
495 stats.rx_dropped = xs->rx_dropped;
496 stats.rx_invalid_descs = xskq_nb_invalid_descs(xs->rx);
497 stats.tx_invalid_descs = xskq_nb_invalid_descs(xs->tx);
498 mutex_unlock(&xs->mutex);
499
500 if (copy_to_user(optval, &stats, sizeof(stats)))
501 return -EFAULT;
502 if (put_user(sizeof(stats), optlen))
503 return -EFAULT;
504
505 return 0;
506 }
507 default:
508 break;
509 }
510
511 return -EOPNOTSUPP;
512}
513
471static int xsk_mmap(struct file *file, struct socket *sock, 514static int xsk_mmap(struct file *file, struct socket *sock,
472 struct vm_area_struct *vma) 515 struct vm_area_struct *vma)
473{ 516{
@@ -524,7 +567,7 @@ static const struct proto_ops xsk_proto_ops = {
524 .listen = sock_no_listen, 567 .listen = sock_no_listen,
525 .shutdown = sock_no_shutdown, 568 .shutdown = sock_no_shutdown,
526 .setsockopt = xsk_setsockopt, 569 .setsockopt = xsk_setsockopt,
527 .getsockopt = sock_no_getsockopt, 570 .getsockopt = xsk_getsockopt,
528 .sendmsg = xsk_sendmsg, 571 .sendmsg = xsk_sendmsg,
529 .recvmsg = sock_no_recvmsg, 572 .recvmsg = sock_no_recvmsg,
530 .mmap = xsk_mmap, 573 .mmap = xsk_mmap,
diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
index 3497e8808608..7aa9a535db0e 100644
--- a/net/xdp/xsk_queue.h
+++ b/net/xdp/xsk_queue.h
@@ -36,6 +36,11 @@ struct xsk_queue {
36 36
37/* Common functions operating for both RXTX and umem queues */ 37/* Common functions operating for both RXTX and umem queues */
38 38
39static inline u64 xskq_nb_invalid_descs(struct xsk_queue *q)
40{
41 return q ? q->invalid_descs : 0;
42}
43
39static inline u32 xskq_nb_avail(struct xsk_queue *q, u32 dcnt) 44static inline u32 xskq_nb_avail(struct xsk_queue *q, u32 dcnt)
40{ 45{
41 u32 entries = q->prod_tail - q->cons_tail; 46 u32 entries = q->prod_tail - q->cons_tail;