@@ -857,6 +857,7 @@ static inline void complete_tx_only(struct
xsk_socket_info *xsk,
}
}
+int payload = 100000 /*10Kpps*/;
static void rx_drop(struct xsk_socket_info *xsk, struct pollfd *fds)
{
unsigned int rcvd, i;
@@ -888,6 +889,21 @@ static void rx_drop(struct xsk_socket_info *xsk,
struct pollfd *fds)
char *pkt = xsk_umem__get_data(xsk->umem->buffer, addr);
hex_dump(pkt, len, addr);
+
+ unsigned long now = get_nsecs();
+ unsigned long prev = now;
+ int j;
+ for (;;){
+ j=0;
+ do {
+ j++;
+ }while(j<1000);
+
+ now = get_nsecs();
+ if (now - prev >= payload)
+ break;
+ }
+
*xsk_ring_prod__fill_addr(&xsk->umem->fq, idx_fq++) = orig;
}
```
Then, run the xdpsock with cmd `./xdpsock -r -z -i p6p1 -m`. And check
the CPU usage with `top`.
Unexpectedly the si(soft interrupt) of p6p1's ring 0 is 99.x%, almost
100%. However, if I didn't
modify xdpsock code, the si was about 20% and xdpsock can rx_drop all
the packages. Fewer packages
are processed but more cpu are consumed, this is not correct.
Nic's driver is ixgbe. This unexpected situation means ixgbe_poll
doesn't deal with rx traffic
congestion well. A feasible solution is to make ixgbe realize rx
congestion and drop the packets
by hardware.
```
# git diff
b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -430,6 +430,7 @@ struct ixgbe_ring_container {
u16 work_limit; /* total work allowed per interrupt */
u8 count; /* total number of rings in vector */
u8 itr; /* current ITR setting for ring */
+ int congestion; /* traffic congestion flag */
};
/* iterator for handling rings in ring container */
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -2542,6 +2542,12 @@ static void ixgbe_update_itr(struct
ixgbe_q_vector *q_vector,
if (time_after(next_update, ring_container->next_update))
goto clear_counts;
+ if (ring_container->congestion){
+ itr = ring_container->itr << 1;
+ ring_container->congestion = 0;
+ goto clear_counts;
+ }
+
packets = ring_container->total_packets;
/* We have no packets to actually measure against. This means
b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
@@ -235,6 +235,7 @@ int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector,
struct ixgbe_adapter *adapter = q_vector->adapter;
u16 cleaned_count = ixgbe_desc_unused(rx_ring);
unsigned int xdp_res, xdp_xmit = 0;
+ int fail_times = 0;
bool failure = false;
struct sk_buff *skb;
@@ -249,6 +250,8 @@ int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector,