Merge tag 'writeback_for_v5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / net / core / xdp.c
index 4c7ea85..48aba93 100644 (file)
 #include <linux/slab.h>
 #include <linux/idr.h>
 #include <linux/rhashtable.h>
+#include <linux/bug.h>
 #include <net/page_pool.h>
 
 #include <net/xdp.h>
 #include <net/xdp_priv.h> /* struct xdp_mem_allocator */
 #include <trace/events/xdp.h>
+#include <net/xdp_sock_drv.h>
 
 #define REG_STATE_NEW          0x0
 #define REG_STATE_REGISTERED   0x1
@@ -108,27 +110,6 @@ static void mem_allocator_disconnect(void *allocator)
        mutex_unlock(&mem_id_lock);
 }
 
-static void mem_id_disconnect(int id)
-{
-       struct xdp_mem_allocator *xa;
-
-       mutex_lock(&mem_id_lock);
-
-       xa = rhashtable_lookup_fast(mem_id_ht, &id, mem_id_rht_params);
-       if (!xa) {
-               mutex_unlock(&mem_id_lock);
-               WARN(1, "Request remove non-existing id(%d), driver bug?", id);
-               return;
-       }
-
-       trace_mem_disconnect(xa);
-
-       if (!rhashtable_remove_fast(mem_id_ht, &xa->node, mem_id_rht_params))
-               call_rcu(&xa->rcu, __xdp_mem_allocator_rcu_free);
-
-       mutex_unlock(&mem_id_lock);
-}
-
 void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq)
 {
        struct xdp_mem_allocator *xa;
@@ -142,9 +123,6 @@ void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq)
        if (id == 0)
                return;
 
-       if (xdp_rxq->mem.type == MEM_TYPE_ZERO_COPY)
-               return mem_id_disconnect(id);
-
        if (xdp_rxq->mem.type == MEM_TYPE_PAGE_POOL) {
                rcu_read_lock();
                xa = rhashtable_lookup(mem_id_ht, &id, mem_id_rht_params);
@@ -300,7 +278,7 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq,
        xdp_rxq->mem.type = type;
 
        if (!allocator) {
-               if (type == MEM_TYPE_PAGE_POOL || type == MEM_TYPE_ZERO_COPY)
+               if (type == MEM_TYPE_PAGE_POOL)
                        return -EINVAL; /* Setup time check page_pool req */
                return 0;
        }
@@ -357,10 +335,11 @@ EXPORT_SYMBOL_GPL(xdp_rxq_info_reg_mem_model);
  * scenarios (e.g. queue full), it is possible to return the xdp_frame
  * while still leveraging this protection.  The @napi_direct boolean
  * is used for those calls sites.  Thus, allowing for faster recycling
- * of xdp_frames/pages in those cases.
+ * of xdp_frames/pages in those cases. This path is never used by the
+ * MEM_TYPE_XSK_BUFF_POOL memory type, so it's explicitly not part of
+ * the switch-statement.
  */
-static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
-                        unsigned long handle)
+static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct)
 {
        struct xdp_mem_allocator *xa;
        struct page *page;
@@ -382,36 +361,29 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
                page = virt_to_page(data); /* Assumes order0 page*/
                put_page(page);
                break;
-       case MEM_TYPE_ZERO_COPY:
-               /* NB! Only valid from an xdp_buff! */
-               rcu_read_lock();
-               /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */
-               xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
-               xa->zc_alloc->free(xa->zc_alloc, handle);
-               rcu_read_unlock();
        default:
                /* Not possible, checked in xdp_rxq_info_reg_mem_model() */
+               WARN(1, "Incorrect XDP memory type (%d) usage", mem->type);
                break;
        }
 }
 
 void xdp_return_frame(struct xdp_frame *xdpf)
 {
-       __xdp_return(xdpf->data, &xdpf->mem, false, 0);
+       __xdp_return(xdpf->data, &xdpf->mem, false);
 }
 EXPORT_SYMBOL_GPL(xdp_return_frame);
 
 void xdp_return_frame_rx_napi(struct xdp_frame *xdpf)
 {
-       __xdp_return(xdpf->data, &xdpf->mem, true, 0);
+       __xdp_return(xdpf->data, &xdpf->mem, true);
 }
 EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi);
 
 void xdp_return_buff(struct xdp_buff *xdp)
 {
-       __xdp_return(xdp->data, &xdp->rxq->mem, true, xdp->handle);
+       __xdp_return(xdp->data, &xdp->rxq->mem, true);
 }
-EXPORT_SYMBOL_GPL(xdp_return_buff);
 
 /* Only called for MEM_TYPE_PAGE_POOL see xdp.h */
 void __xdp_release_frame(void *data, struct xdp_mem_info *mem)
@@ -428,15 +400,6 @@ void __xdp_release_frame(void *data, struct xdp_mem_info *mem)
 }
 EXPORT_SYMBOL_GPL(__xdp_release_frame);
 
-int xdp_attachment_query(struct xdp_attachment_info *info,
-                        struct netdev_bpf *bpf)
-{
-       bpf->prog_id = info->prog ? info->prog->aux->id : 0;
-       bpf->prog_flags = info->prog ? info->flags : 0;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(xdp_attachment_query);
-
 bool xdp_attachment_flags_ok(struct xdp_attachment_info *info,
                             struct netdev_bpf *bpf)
 {
@@ -490,9 +453,17 @@ struct xdp_frame *xdp_convert_zc_to_xdp_frame(struct xdp_buff *xdp)
        xdpf->len = totsize - metasize;
        xdpf->headroom = 0;
        xdpf->metasize = metasize;
+       xdpf->frame_sz = PAGE_SIZE;
        xdpf->mem.type = MEM_TYPE_PAGE_ORDER0;
 
-       xdp_return_buff(xdp);
+       xsk_buff_free(xdp);
        return xdpf;
 }
 EXPORT_SYMBOL_GPL(xdp_convert_zc_to_xdp_frame);
+
+/* Used by XDP_WARN macro, to avoid inlining WARN() in fast-path */
+void xdp_warn(const char *msg, const char *func, const int line)
+{
+       WARN(1, "XDP_WARN: %s(line:%d): %s\n", func, line, msg);
+};
+EXPORT_SYMBOL_GPL(xdp_warn);