]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - drivers/net/ethernet/marvell/mvneta.c
net: ethernet: mvneta: fix MVNETA_SKB_HEADROOM alignment
[mirror_ubuntu-hirsute-kernel.git] / drivers / net / ethernet / marvell / mvneta.c
index 5be61f73b6abb79268e6b5e85a2f8f3c5c382831..4cc9abd61c43585f2d26f59af978c7ea17bc39d0 100644 (file)
              ETH_HLEN + ETH_FCS_LEN,                        \
              cache_line_size())
 
-#define MVNETA_SKB_HEADROOM    max(XDP_PACKET_HEADROOM, NET_SKB_PAD)
+/* Driver assumes that the last 3 bits are 0 */
+#define MVNETA_SKB_HEADROOM    ALIGN(max(NET_SKB_PAD, XDP_PACKET_HEADROOM), 8)
 #define MVNETA_SKB_PAD (SKB_DATA_ALIGN(sizeof(struct skb_shared_info) + \
                         MVNETA_SKB_HEADROOM))
 #define MVNETA_SKB_SIZE(len)   (SKB_DATA_ALIGN(len) + MVNETA_SKB_PAD)
@@ -2072,7 +2073,7 @@ mvneta_xdp_xmit_back(struct mvneta_port *pp, struct xdp_buff *xdp)
        int cpu;
        u32 ret;
 
-       xdpf = convert_to_xdp_frame(xdp);
+       xdpf = xdp_convert_buff_to_frame(xdp);
        if (unlikely(!xdpf))
                return MVNETA_XDP_DROPPED;
 
@@ -2148,12 +2149,17 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
               struct bpf_prog *prog, struct xdp_buff *xdp,
               struct mvneta_stats *stats)
 {
-       unsigned int len;
+       unsigned int len, sync;
+       struct page *page;
        u32 ret, act;
 
        len = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction;
        act = bpf_prog_run_xdp(prog, xdp);
 
+       /* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
+       sync = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction;
+       sync = max(sync, len);
+
        switch (act) {
        case XDP_PASS:
                stats->xdp_pass++;
@@ -2164,9 +2170,8 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
                err = xdp_do_redirect(pp->dev, xdp, prog);
                if (unlikely(err)) {
                        ret = MVNETA_XDP_DROPPED;
-                       page_pool_put_page(rxq->page_pool,
-                                          virt_to_head_page(xdp->data), len,
-                                          true);
+                       page = virt_to_head_page(xdp->data);
+                       page_pool_put_page(rxq->page_pool, page, sync, true);
                } else {
                        ret = MVNETA_XDP_REDIR;
                        stats->xdp_redirect++;
@@ -2175,10 +2180,10 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
        }
        case XDP_TX:
                ret = mvneta_xdp_xmit_back(pp, xdp);
-               if (ret != MVNETA_XDP_TX)
-                       page_pool_put_page(rxq->page_pool,
-                                          virt_to_head_page(xdp->data), len,
-                                          true);
+               if (ret != MVNETA_XDP_TX) {
+                       page = virt_to_head_page(xdp->data);
+                       page_pool_put_page(rxq->page_pool, page, sync, true);
+               }
                break;
        default:
                bpf_warn_invalid_xdp_action(act);
@@ -2187,8 +2192,8 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
                trace_xdp_exception(pp->dev, prog, act);
                /* fall through */
        case XDP_DROP:
-               page_pool_put_page(rxq->page_pool,
-                                  virt_to_head_page(xdp->data), len, true);
+               page = virt_to_head_page(xdp->data);
+               page_pool_put_page(rxq->page_pool, page, sync, true);
                ret = MVNETA_XDP_DROPPED;
                stats->xdp_drop++;
                break;
@@ -2320,6 +2325,7 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
        rcu_read_lock();
        xdp_prog = READ_ONCE(pp->xdp_prog);
        xdp_buf.rxq = &rxq->xdp_rxq;
+       xdp_buf.frame_sz = PAGE_SIZE;
 
        /* Fairness NAPI loop */
        while (rx_proc < budget && rx_proc < rx_todo) {
@@ -5383,7 +5389,7 @@ static int __init mvneta_driver_init(void)
 {
        int ret;
 
-       ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "net/mvmeta:online",
+       ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "net/mvneta:online",
                                      mvneta_cpu_online,
                                      mvneta_cpu_down_prepare);
        if (ret < 0)