> On Jan 23, 2017, at 5:45 PM, Cong Wang <xiyou.wangc...@gmail.com> wrote:
> 
> On Mon, Jan 23, 2017 at 2:37 PM, Joel Cunningham <joel.cunning...@me.com> 
> wrote:
>> Hi,
>> 
>> I’m working on a research effort to understand the synchronization 
>> mechanisms for accessing and modifying a struct net_device object.  One area 
>> that isn’t clear is the net device pointer (dev) stored in a struct sk_buff. 
>>  From my investigation, the pointer appears to be assigned without 
>> increasing the struct net_device’s reference count (example 
>> __netdev_alloc_skb doesn’t call dev_hold) and also when the sk_buff is freed 
>> (kfree_skb) no call to dev_put() is made.  This seems to leave a possibility 
>> of an skb referencing a stale net device unless something is cleaning up all 
>> the skbs during unregister_netdevice() (which waits for all outstanding 
>> references to be released).  Any insight in understanding how this is 
>> working would be appreciated!
>> 
> 
> This is a very common question.
> 
> synchronize_net() is supposed to wait for on-flying packets, since
> both for TX and RX paths we acquire RCU read lock.

Thanks for the insight on in-flight packets!  I continued my research effort on 
how queued/outstanding sk_buffs with dev pointer set are cleaned up during an 
unregister.  Do my findings sound correct?

1. RX packets queued in the link-layer backlog are freed via flush_backlog 
(called from netdev_run_todo)
2. RX packets that have been processed and queued in an upper layer buffer have 
already had their sk_buff->dev pointer NULLed out (I saw this in tcp_v4_rcv() 
and sock_queue_rcv_skb() for UDP pathway)
3. TX packets waiting in a queue discipline are freed via 
device_deactive_many()/dev_deactivate_queue()
4. TX packets that have been accepted by the driver in ndo_start_xmit() but are 
queued for asynchronous transmit will be freed during ndo_stop()

Thanks,

Joel

Reply via email to