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>
This commit is contained in:
parent
35fcde7f8d
commit
af75d9e02d
|
@ -38,6 +38,7 @@ struct sockaddr_xdp {
|
||||||
#define XDP_UMEM_REG 3
|
#define XDP_UMEM_REG 3
|
||||||
#define XDP_UMEM_FILL_RING 4
|
#define XDP_UMEM_FILL_RING 4
|
||||||
#define XDP_UMEM_COMPLETION_RING 5
|
#define XDP_UMEM_COMPLETION_RING 5
|
||||||
|
#define XDP_STATISTICS 6
|
||||||
|
|
||||||
struct xdp_umem_reg {
|
struct xdp_umem_reg {
|
||||||
__u64 addr; /* Start of packet data area */
|
__u64 addr; /* Start of packet data area */
|
||||||
|
@ -46,6 +47,12 @@ struct xdp_umem_reg {
|
||||||
__u32 frame_headroom; /* Frame head room */
|
__u32 frame_headroom; /* Frame head room */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct xdp_statistics {
|
||||||
|
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
|
||||||
|
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||||
|
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||||
|
};
|
||||||
|
|
||||||
/* Pgoff for mmaping the rings */
|
/* Pgoff for mmaping the rings */
|
||||||
#define XDP_PGOFF_RX_RING 0
|
#define XDP_PGOFF_RX_RING 0
|
||||||
#define XDP_PGOFF_TX_RING 0x80000000
|
#define XDP_PGOFF_TX_RING 0x80000000
|
||||||
|
|
|
@ -468,6 +468,49 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xsk_getsockopt(struct socket *sock, int level, int optname,
|
||||||
|
char __user *optval, int __user *optlen)
|
||||||
|
{
|
||||||
|
struct sock *sk = sock->sk;
|
||||||
|
struct xdp_sock *xs = xdp_sk(sk);
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (level != SOL_XDP)
|
||||||
|
return -ENOPROTOOPT;
|
||||||
|
|
||||||
|
if (get_user(len, optlen))
|
||||||
|
return -EFAULT;
|
||||||
|
if (len < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
switch (optname) {
|
||||||
|
case XDP_STATISTICS:
|
||||||
|
{
|
||||||
|
struct xdp_statistics stats;
|
||||||
|
|
||||||
|
if (len < sizeof(stats))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&xs->mutex);
|
||||||
|
stats.rx_dropped = xs->rx_dropped;
|
||||||
|
stats.rx_invalid_descs = xskq_nb_invalid_descs(xs->rx);
|
||||||
|
stats.tx_invalid_descs = xskq_nb_invalid_descs(xs->tx);
|
||||||
|
mutex_unlock(&xs->mutex);
|
||||||
|
|
||||||
|
if (copy_to_user(optval, &stats, sizeof(stats)))
|
||||||
|
return -EFAULT;
|
||||||
|
if (put_user(sizeof(stats), optlen))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
static int xsk_mmap(struct file *file, struct socket *sock,
|
static int xsk_mmap(struct file *file, struct socket *sock,
|
||||||
struct vm_area_struct *vma)
|
struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
|
@ -524,7 +567,7 @@ static const struct proto_ops xsk_proto_ops = {
|
||||||
.listen = sock_no_listen,
|
.listen = sock_no_listen,
|
||||||
.shutdown = sock_no_shutdown,
|
.shutdown = sock_no_shutdown,
|
||||||
.setsockopt = xsk_setsockopt,
|
.setsockopt = xsk_setsockopt,
|
||||||
.getsockopt = sock_no_getsockopt,
|
.getsockopt = xsk_getsockopt,
|
||||||
.sendmsg = xsk_sendmsg,
|
.sendmsg = xsk_sendmsg,
|
||||||
.recvmsg = sock_no_recvmsg,
|
.recvmsg = sock_no_recvmsg,
|
||||||
.mmap = xsk_mmap,
|
.mmap = xsk_mmap,
|
||||||
|
|
|
@ -36,6 +36,11 @@ struct xsk_queue {
|
||||||
|
|
||||||
/* Common functions operating for both RXTX and umem queues */
|
/* Common functions operating for both RXTX and umem queues */
|
||||||
|
|
||||||
|
static inline u64 xskq_nb_invalid_descs(struct xsk_queue *q)
|
||||||
|
{
|
||||||
|
return q ? q->invalid_descs : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline u32 xskq_nb_avail(struct xsk_queue *q, u32 dcnt)
|
static inline u32 xskq_nb_avail(struct xsk_queue *q, u32 dcnt)
|
||||||
{
|
{
|
||||||
u32 entries = q->prod_tail - q->cons_tail;
|
u32 entries = q->prod_tail - q->cons_tail;
|
||||||
|
|
Loading…
Reference in New Issue