]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/xdp/xsk.c
Merge tag 'hwlock-v5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson...
[linux.git] / net / xdp / xsk.c
index 9044073fbf2257b0eb7632f05bc3b109d78604d8..956793893c9dec2752b8e6a3140cc44c0e633df3 100644 (file)
@@ -196,7 +196,7 @@ static bool xsk_is_bound(struct xdp_sock *xs)
        return false;
 }
 
-int xsk_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
+static int xsk_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
 {
        u32 len;
 
@@ -212,7 +212,7 @@ int xsk_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
                __xsk_rcv_zc(xs, xdp, len) : __xsk_rcv(xs, xdp, len);
 }
 
-void xsk_flush(struct xdp_sock *xs)
+static void xsk_flush(struct xdp_sock *xs)
 {
        xskq_produce_flush_desc(xs->rx);
        xs->sk.sk_data_ready(&xs->sk);
@@ -264,6 +264,35 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
        return err;
 }
 
+int __xsk_map_redirect(struct bpf_map *map, struct xdp_buff *xdp,
+                      struct xdp_sock *xs)
+{
+       struct xsk_map *m = container_of(map, struct xsk_map, map);
+       struct list_head *flush_list = this_cpu_ptr(m->flush_list);
+       int err;
+
+       err = xsk_rcv(xs, xdp);
+       if (err)
+               return err;
+
+       if (!xs->flush_node.prev)
+               list_add(&xs->flush_node, flush_list);
+
+       return 0;
+}
+
+void __xsk_map_flush(struct bpf_map *map)
+{
+       struct xsk_map *m = container_of(map, struct xsk_map, map);
+       struct list_head *flush_list = this_cpu_ptr(m->flush_list);
+       struct xdp_sock *xs, *tmp;
+
+       list_for_each_entry_safe(xs, tmp, flush_list, flush_node) {
+               xsk_flush(xs);
+               __list_del_clearprev(&xs->flush_node);
+       }
+}
+
 void xsk_umem_complete_tx(struct xdp_umem *umem, u32 nb_entries)
 {
        xskq_produce_flush_addr_n(umem->cq, nb_entries);
@@ -418,10 +447,10 @@ static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
        return __xsk_sendmsg(sk);
 }
 
-static unsigned int xsk_poll(struct file *file, struct socket *sock,
+static __poll_t xsk_poll(struct file *file, struct socket *sock,
                             struct poll_table_struct *wait)
 {
-       unsigned int mask = datagram_poll(file, sock, wait);
+       __poll_t mask = datagram_poll(file, sock, wait);
        struct sock *sk = sock->sk;
        struct xdp_sock *xs = xdp_sk(sk);
        struct net_device *dev;
@@ -443,9 +472,9 @@ static unsigned int xsk_poll(struct file *file, struct socket *sock,
        }
 
        if (xs->rx && !xskq_empty_desc(xs->rx))
-               mask |= POLLIN | POLLRDNORM;
+               mask |= EPOLLIN | EPOLLRDNORM;
        if (xs->tx && !xskq_full_desc(xs->tx))
-               mask |= POLLOUT | POLLWRNORM;
+               mask |= EPOLLOUT | EPOLLWRNORM;
 
        return mask;
 }