Re: [PATCH net-next v10 1/2] net: af_packet: remove last_kactive_blk_num field

From: Xin Zhao <hidden>
Date: 2025-09-04 02:36:08
Also in: lkml

On Thu, Sep 4, 2025 at 10:09 +0800 Jason Xing [off-list ref] wrote:
quoted
Consider the following case:
(before applying this patch)
cpu0                                  cpu1
tpacket_rcv
  ...
    prb_dispatch_next_block
      prb_freeze_queue (R = 1)
                                      prb_retire_rx_blk_timer_expired
                                        L != K
                                          _prb_refresh_rx_retire_blk_timer
                                            refresh timer
                                            set L = K
I do not think the above can happen because:
1) tpacket_rcv() owns the sk_receive_queue.lock and then calls
packet_current_rx_frame()->__packet_lookup_frame_in_block()->prb_dispatch_next_block()
2) the timer prb_retire_rx_blk_timer_expired() also needs to acquire
the same lock first.
quoted
(after applying this patch)
cpu0                                  cpu1
tpacket_rcv
  ...
    prb_dispatch_next_block
      prb_freeze_queue (R = 1)
                                      prb_retire_rx_blk_timer_expired
                                        !forzen is 0
                                          check prb_curr_blk_in_use
                                            if true
                                              same as (before apply)
                                            if false
                                              prb_open_block
Before applying this patch, prb_retire_rx_blk_timer_expired will do nothing
but refresh timer and set L = K in the case above. After applying this
patch, it will check prb_curr_blk_in_use and call prb_open_block if
user-space caught up.
The major difference after this patch is that even if L != K we would
call prb_open_block(). So I think the key point is that this patch
provides another checkpoint to thaw the might-be-frozen block in any
case. It doesn't have any effect because
__packet_lookup_frame_in_block() has the same logic and does it again
without this patch when detecting the ring is frozen. The patch only
advances checking the status of the ring.

In the prb_dispatch_next_block function, after executing prb_freeze_queue, it
directly returns without executing prb_open_block. As a result, tpacket_rcv
completes and exits the lock, and then callback executes while (L != K).
Perhaps my diagram did not convey this clearly. I think it might be better to
use your description above to replace the flowchart representation.


Thanks
Xin Zhao
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help