[PATCH] rtnet: Fix lifecycle management of mapped rtskbs

Philippe Gerum rpm at xenomai.org
Thu Jan 17 13:56:42 CET 2019


On 12/18/18 7:46 AM, Jan Kiszka via Xenomai wrote:
> On 14.12.18 12:22, Jan Kiszka via Xenomai wrote:
>> Do not add rtskbs to the rtskb_list which are not mappend because
>> rtdev_unmap_rtskb will not remove such rtskbs again (buf_dma_addr ==
>> RTSKB_UNMAPPED). In fact, rtskb_list should be called rtskb_mapped_list,
>> so refactor this while at it.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
>> ---
>>   kernel/drivers/net/stack/rtdev.c | 10 +++++-----
>>   1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/kernel/drivers/net/stack/rtdev.c
>> b/kernel/drivers/net/stack/rtdev.c
>> index 5eb73ce1a4..7b267f2a7c 100644
>> --- a/kernel/drivers/net/stack/rtdev.c
>> +++ b/kernel/drivers/net/stack/rtdev.c
>> @@ -44,9 +44,9 @@ MODULE_PARM_DESC(device_rtskbs, "Number of
>> additional global realtime socket "
>>   struct rtnet_device         *rtnet_devices[MAX_RT_DEVICES];
>>   static struct rtnet_device  *loopback_device;
>>   static DEFINE_RTDM_LOCK(rtnet_devices_rt_lock);
>> +static LIST_HEAD(rtskb_mapped_list);
>>     LIST_HEAD(event_hook_list);
>> -LIST_HEAD(rtskb_list);
>>   DEFINE_MUTEX(rtnet_devices_nrt_lock);
>>     static int rtdev_locked_xmit(struct rtskb *skb, struct
>> rtnet_device *rtdev);
>> @@ -412,8 +412,8 @@ int rtdev_map_rtskb(struct rtskb *skb)
>>       }
>>       }
>>   -    if (!err)
>> -    list_add(&skb->entry, &rtskb_list);
>> +    if (!err && skb->buf_dma_addr != RTSKB_UNMAPPED)
>> +    list_add(&skb->entry, &rtskb_mapped_list);
>>         mutex_unlock(&rtnet_devices_nrt_lock);
>>   @@ -430,7 +430,7 @@ static int rtdev_map_all_rtskbs(struct
>> rtnet_device *rtdev)
>>       if (!rtdev->map_rtskb)
>>       return 0;
>>   -    list_for_each_entry(skb, &rtskb_list, entry) {
>> +    list_for_each_entry(skb, &rtskb_mapped_list, entry) {
>>       err = rtskb_map(rtdev, skb);
>>       if (err)
>>          break;
>> @@ -474,7 +474,7 @@ static void rtdev_unmap_all_rtskbs(struct
>> rtnet_device *rtdev)
>>       if (!rtdev->unmap_rtskb)
>>       return;
>>   -    list_for_each_entry(skb, &rtskb_list, entry) {
>> +    list_for_each_entry(skb, &rtskb_mapped_list, entry) {
>>       rtdev->unmap_rtskb(rtdev, skb);
>>       }
>>   }
>>
> 
> Applied to master and stable.
> 
> Jan
> 

Unfortunately, this breaks RTnet for any driver using DMA, apparently
uncovering a pre-existing issue in the device init->registration logic
wrt mapping skb from per-device pools.

In short, filtering skbs we can't immediately map out of the rtskb list
in rtdev_map_rtskb() prevents rt_register_rtnetdev(dev) from finding
@dev's skbs in rtskb_mapped_list when running rtdev_map_all_skbs().
In turn this prevents the driver from setting up the hw's RX/TX rings
with proper DMA mapping addresses, as none of its skbs has valid bus
addresses for DMA.

There may be a simple fix, but the rtdev init logic is a bit too
convoluted for my after lunch. I'll try to come up with a fix later.

-- 
Philippe.



More information about the Xenomai mailing list