4c8ad36ec7378b3a38142c95bc1aec49e6985533

RmNet would previously update the page offset and page length values contained within each skb_frag_t in the SKB received from the physical driver during deaggregation. This ensured that the next data to be deaggregated was always at the "start" of the SKB. This approach is problematic as it creates a race between the RmNet deaggregation logic and any usespace application listening on a standard packet socket (i.e. PACKET_RX/TX_RING socket options were not set, so packet_rcv() is used by the kernel for handling the socket). Since packet_rcv() creates a clone of the incoming SKB and queues it until the point where userspace can read it, the cloned SKB in the queue and the original SKB being processed by RmNet will refer to the same skb_shared_info struct lying at the end of the buffer pointed to by skb->head. This means that when RmNet updates these values inside of the skb_frag_t struct in the SKB as it processes them, the same changes will be reflected in the cloned SKB waiting in the queue for the packet socket. When userspace calls recv() to listen for data, this SKB will then be copied into the user provided buffer via skb_copy_datagram_iter(). This copy will result in -EFAULT being returned to the user since each page in the SKB will have length 0. This updates the deaggregation logic to maintain the current position in the SKB being deaggregated via different means to avoid this race with userspace. Instead of receiving the current fragment to start checking, rmnet_frag_deaggregate_one() recieves the offset into the SKB to start at and now returns the number of bytes that it has placed into a descriptor struct to the calling function. Change-Id: I9d0f5d8be6d47a69d6b0260fd20907ad69e377ff Signed-off-by: Sean Tranchetti <stranche@codeaurora.org>
Опис
Немає опису
Мови
C
98.7%
C++
0.9%
Makefile
0.3%
Starlark
0.1%