https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=283903

--- Comment #29 from Guillaume Outters <guillaume-free...@outters.eu> ---
More manual traces, with:

A. In lkpi_80211_txq_tx_one, after dev_alloc_skb()

B. In __skb_queue_tail(), just after the call to __skb_queue_before(), with a
filter to only trace c2h_queue:
print the qlen compared to the effective count of elements
skb_queue_walk_safe() could walk through.

C. In rtw_c2h_work, before calling skb_queue_walk_safe(): same counter as A.
(count by walkthrough versus qlen)
Note that it corresponds to the "D1" of my previous trace points naming.

D. In linuxkpi_ieee80211_free_txskb, between calling
_lkpi_ieee80211_free_txskb() and kfree_skb().

----
Flat cycles

A typical (working) trace will give:
  A
  A
  A
  A
  A
  B 1/1 (1 count by skb_queue_walk_safe / 1 in qlen)
  C 1/1
  D
  B 1/1
  C 1/1
  D
  B 1/1
  B 2/2
  B 3/3
  C 3/3
  D
  D
  D

So:
5 SKBs are allocated (A);
then we have 2 "simple" cycles where an SKB gets queued (B), rtw_c2h_work
starts (C) with 1 SKB in queue, thus it triggers the freeing of 1 SKB (D).
Then the 3 remaining SKB get in queue at once, before rtw_c2h_work starts and
frees those 3 SKB by 3 calls to D.

Note that series of many Bs are really, really rare, the queue is usually
filled and emptied 1 by 1 (as with the first B and C of the above timeline).

----
Interleaved (but working) enqueues with dequeues

Sometimes I get this king of cycles:

  A * 4
  B 1/1
  B 2/2
  B 3/3
  C 3/3 <- start of dequeue…
  D     <- 1st of the 3 gets freed (now the queue should have only qlen = 2
items left)
  B 3/3 <---- But then a new SKB gets enqueued in the same time! ++qlen == 3 
  D     <- 2nd of 3
  D     <- 3rd of 3
  D     <- so this must be the inbetween-inserted one, that C 3/3 frees too.
  C 0/0 <---- triggered by B 3/3, but correctly detects there's no more work

----
Whoops

Now when my machine started to get lost, I found this sequence:

A * 4
B 1/1
C 1/1  <- prepare to clean 1 SKB
B 2/2  <---- … no, 1 more in the queue
D      <-- free the 1st
C 0/2  <------ WHAT??? qlen = 2 but the linked list looks empty!
B 0/3
C 0/3
B 0/4
C 0/4
…

No more call to free (D), qlen continues to grow but the linked list is broken,
no more SKB succeeds to get inserted.

----------------------------------------
Could there be a missing lock somewhere?
Or did the free accidentally release an initial intercalary buffer, whose sole
goal was to avoid c2h_queue pointing to itself (which is the condition that
skb_queue_walk_safe() will abort on)?
----------------------------------------

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to