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 = KI 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