xdp_ring->xsk_pool = ice_tx_xsk_pool(xdp_ring);
        }
 
+       ice_for_each_rxq(vsi, i)
+               vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i];
+
        return 0;
 
 free_xdp_rings:
 
  * @rx_ring: Rx ring
  * @xdp: xdp_buff used as input to the XDP program
  * @xdp_prog: XDP program to run
+ * @xdp_ring: ring to be used for XDP_TX action
  *
  * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
  */
 static int
 ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
-           struct bpf_prog *xdp_prog)
+           struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring)
 {
-       struct ice_tx_ring *xdp_ring;
-       int err, result;
+       int err;
        u32 act;
 
        act = bpf_prog_run_xdp(xdp_prog, xdp);
        case XDP_PASS:
                return ICE_XDP_PASS;
        case XDP_TX:
-               xdp_ring = rx_ring->vsi->xdp_rings[smp_processor_id()];
-               result = ice_xmit_xdp_ring(xdp->data, xdp->data_end - xdp->data, xdp_ring);
-               if (result == ICE_XDP_CONSUMED)
+               err = ice_xmit_xdp_ring(xdp->data, xdp->data_end - xdp->data, xdp_ring);
+               if (err == ICE_XDP_CONSUMED)
                        goto out_failure;
-               return result;
+               return err;
        case XDP_REDIRECT:
                err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
                if (err)
        unsigned int total_rx_bytes = 0, total_rx_pkts = 0, frame_sz = 0;
        u16 cleaned_count = ICE_DESC_UNUSED(rx_ring);
        unsigned int offset = rx_ring->rx_offset;
+       struct ice_tx_ring *xdp_ring = NULL;
        unsigned int xdp_res, xdp_xmit = 0;
        struct sk_buff *skb = rx_ring->skb;
        struct bpf_prog *xdp_prog = NULL;
 #endif
        xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq);
 
+       xdp_prog = READ_ONCE(rx_ring->xdp_prog);
+       if (xdp_prog)
+               xdp_ring = rx_ring->xdp_ring;
+
        /* start the loop to process Rx packets bounded by 'budget' */
        while (likely(total_rx_pkts < (unsigned int)budget)) {
                union ice_32b_rx_flex_desc *rx_desc;
                xdp.frame_sz = ice_rx_frame_truesize(rx_ring, size);
 #endif
 
-               xdp_prog = READ_ONCE(rx_ring->xdp_prog);
                if (!xdp_prog)
                        goto construct_skb;
 
-               xdp_res = ice_run_xdp(rx_ring, &xdp, xdp_prog);
+               xdp_res = ice_run_xdp(rx_ring, &xdp, xdp_prog, xdp_ring);
                if (!xdp_res)
                        goto construct_skb;
                if (xdp_res & (ICE_XDP_TX | ICE_XDP_REDIR)) {
        failure = ice_alloc_rx_bufs(rx_ring, cleaned_count);
 
        if (xdp_prog)
-               ice_finalize_xdp_rx(rx_ring, xdp_xmit);
+               ice_finalize_xdp_rx(xdp_ring, xdp_xmit);
        rx_ring->skb = skb;
 
        ice_update_rx_ring_stats(rx_ring, total_rx_pkts, total_rx_bytes);
 
        struct rcu_head rcu;            /* to avoid race on free */
        /* CL4 - 3rd cacheline starts here */
        struct bpf_prog *xdp_prog;
+       struct ice_tx_ring *xdp_ring;
        struct xsk_buff_pool *xsk_pool;
        struct sk_buff *skb;
        dma_addr_t dma;                 /* physical address of ring */
 
 
 /**
  * ice_finalize_xdp_rx - Bump XDP Tx tail and/or flush redirect map
- * @rx_ring: Rx ring
+ * @xdp_ring: XDP ring
  * @xdp_res: Result of the receive batch
  *
  * This function bumps XDP Tx tail and/or flush redirect map, and
  * should be called when a batch of packets has been processed in the
  * napi loop.
  */
-void ice_finalize_xdp_rx(struct ice_rx_ring *rx_ring, unsigned int xdp_res)
+void ice_finalize_xdp_rx(struct ice_tx_ring *xdp_ring, unsigned int xdp_res)
 {
        if (xdp_res & ICE_XDP_REDIR)
                xdp_do_flush_map();
 
-       if (xdp_res & ICE_XDP_TX) {
-               struct ice_tx_ring *xdp_ring =
-                       rx_ring->vsi->xdp_rings[smp_processor_id()];
-
+       if (xdp_res & ICE_XDP_TX)
                ice_xdp_ring_update_tail(xdp_ring);
-       }
 }
 
        writel_relaxed(xdp_ring->next_to_use, xdp_ring->tail);
 }
 
-void ice_finalize_xdp_rx(struct ice_rx_ring *xdp_ring, unsigned int xdp_res);
+void ice_finalize_xdp_rx(struct ice_tx_ring *xdp_ring, unsigned int xdp_res);
 int ice_xmit_xdp_buff(struct xdp_buff *xdp, struct ice_tx_ring *xdp_ring);
 int ice_xmit_xdp_ring(void *data, u16 size, struct ice_tx_ring *xdp_ring);
 void ice_release_rx_desc(struct ice_rx_ring *rx_ring, u16 val);
 
  * ice_run_xdp_zc - Executes an XDP program in zero-copy path
  * @rx_ring: Rx ring
  * @xdp: xdp_buff used as input to the XDP program
+ * @xdp_prog: XDP program to run
+ * @xdp_ring: ring to be used for XDP_TX action
  *
  * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
  */
 static int
-ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
+ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+              struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring)
 {
        int err, result = ICE_XDP_PASS;
-       struct ice_tx_ring *xdp_ring;
-       struct bpf_prog *xdp_prog;
        u32 act;
 
-       /* ZC patch is enabled only when XDP program is set,
-        * so here it can not be NULL
-        */
-       xdp_prog = READ_ONCE(rx_ring->xdp_prog);
-
        act = bpf_prog_run_xdp(xdp_prog, xdp);
 
        if (likely(act == XDP_REDIRECT)) {
        case XDP_PASS:
                break;
        case XDP_TX:
-               xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->q_index];
                result = ice_xmit_xdp_buff(xdp, xdp_ring);
                if (result == ICE_XDP_CONSUMED)
                        goto out_failure;
 {
        unsigned int total_rx_bytes = 0, total_rx_packets = 0;
        u16 cleaned_count = ICE_DESC_UNUSED(rx_ring);
+       struct ice_tx_ring *xdp_ring;
        unsigned int xdp_xmit = 0;
+       struct bpf_prog *xdp_prog;
        bool failure = false;
 
+       /* ZC patch is enabled only when XDP program is set,
+        * so here it can not be NULL
+        */
+       xdp_prog = READ_ONCE(rx_ring->xdp_prog);
+       xdp_ring = rx_ring->xdp_ring;
+
        while (likely(total_rx_packets < (unsigned int)budget)) {
                union ice_32b_rx_flex_desc *rx_desc;
                unsigned int size, xdp_res = 0;
                xsk_buff_set_size(*xdp, size);
                xsk_buff_dma_sync_for_cpu(*xdp, rx_ring->xsk_pool);
 
-               xdp_res = ice_run_xdp_zc(rx_ring, *xdp);
+               xdp_res = ice_run_xdp_zc(rx_ring, *xdp, xdp_prog, xdp_ring);
                if (xdp_res) {
                        if (xdp_res & (ICE_XDP_TX | ICE_XDP_REDIR))
                                xdp_xmit |= xdp_res;
        if (cleaned_count >= ICE_RX_BUF_WRITE)
                failure = !ice_alloc_rx_bufs_zc(rx_ring, cleaned_count);
 
-       ice_finalize_xdp_rx(rx_ring, xdp_xmit);
+       ice_finalize_xdp_rx(xdp_ring, xdp_xmit);
        ice_update_rx_ring_stats(rx_ring, total_rx_packets, total_rx_bytes);
 
        if (xsk_uses_need_wakeup(rx_ring->xsk_pool)) {