i40e_finalize_xdp_rx(rx_ring, xdp_xmit);
        i40e_update_rx_stats(rx_ring, total_rx_bytes, total_rx_packets);
+
+       if (xsk_umem_uses_need_wakeup(rx_ring->xsk_umem)) {
+               if (failure || rx_ring->next_to_clean == rx_ring->next_to_use)
+                       xsk_set_rx_need_wakeup(rx_ring->xsk_umem);
+               else
+                       xsk_clear_rx_need_wakeup(rx_ring->xsk_umem);
+
+               return (int)total_rx_packets;
+       }
        return failure ? budget : (int)total_rx_packets;
 }
 
                i40e_xdp_ring_update_tail(xdp_ring);
 
                xsk_umem_consume_tx_done(xdp_ring->xsk_umem);
+               if (xsk_umem_uses_need_wakeup(xdp_ring->xsk_umem))
+                       xsk_clear_tx_need_wakeup(xdp_ring->xsk_umem);
        }
 
        return !!budget && work_done;
        i40e_update_tx_stats(tx_ring, completed_frames, total_bytes);
 
 out_xmit:
+       if (xsk_umem_uses_need_wakeup(tx_ring->xsk_umem)) {
+               if (tx_ring->next_to_clean == tx_ring->next_to_use)
+                       xsk_set_tx_need_wakeup(tx_ring->xsk_umem);
+               else
+                       xsk_clear_tx_need_wakeup(tx_ring->xsk_umem);
+       }
+
        xmit_done = i40e_xmit_zc(tx_ring, budget);
 
        return work_done && xmit_done;