From: Jan Kiszka <[email protected]> An rtsbk that successfully went through rtdev_map_rtskb is either on rtskb_mapped_list or rtskb_mapwait_list. On rtdev_unmap_rtskb, we therefore have to remove the rtskb unconditionally from a list, otherwise we corrupt its state.
This bug was easily triggerable via running smokey tests against the loopback device. Signed-off-by: Jan Kiszka <[email protected]> --- kernel/drivers/net/stack/rtdev.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/drivers/net/stack/rtdev.c b/kernel/drivers/net/stack/rtdev.c index b2d0687daf..93a8e212bf 100644 --- a/kernel/drivers/net/stack/rtdev.c +++ b/kernel/drivers/net/stack/rtdev.c @@ -510,17 +510,16 @@ void rtdev_unmap_rtskb(struct rtskb *skb) struct rtnet_device *rtdev; int i; - if (skb->buf_dma_addr == RTSKB_UNMAPPED) - return; - mutex_lock(&rtnet_devices_nrt_lock); list_del(&skb->entry); - for (i = 0; i < MAX_RT_DEVICES; i++) { - rtdev = rtnet_devices[i]; - if (rtdev && rtdev->unmap_rtskb) { - rtdev->unmap_rtskb(rtdev, skb); + if (skb->buf_dma_addr != RTSKB_UNMAPPED) { + for (i = 0; i < MAX_RT_DEVICES; i++) { + rtdev = rtnet_devices[i]; + if (rtdev && rtdev->unmap_rtskb) { + rtdev->unmap_rtskb(rtdev, skb); + } } } -- 2.16.4
