Hi,
Recently during testing the application regarding network connectivity (very frequent incoming and outgoing UDP frames) on K64F with mbed-5.13.4, I encountered the NETBUF number limitation (8 by default) which was noticeable with NSAPI_ERROR_PARAMETER returned by UDPSock::sendto(). After brief analysis it turned out that netbuf_new() used inside returns NULL and it is caused by lack of free NETBUFs. It seemed that increasing the default value should solve the issue but it didn't.
Even with higher number of NETBUFs (16, 32, ...) set in lwIP config file (MEMP_NUM_NETBUF), I was still encountering the behaviour that even if there were some netbufs free (only 4 of 16 used), netbuf_new() was returning NULL. Placing the diagnostic printfs in memp_alloc() and memp_free() showed that during runtime *memp->next value used by (de)allocator to point the next free netbuf to be used in next allocation suddenly points to somewhere in lwip_ram_heap. Such netbuf element taken from lwip_ram_heap during allocation, has its next pointer set to NULL and this way during next netbuf_new() call the NULL is returned.
I wonder if such behaviour of (unexpected in my opinion) *memp->next pointer change to the memory outside the memp_netbufs list of available elements is correct ?
After another brief debug with focus on memp_alloc() and memp_free(), it looks like none of these functions make this unexpected change - this wrong value is simply already there while these functions are called. It looks like some other code wrote it there. Unfortunately conditional hardware watchpoints do not work and software ones are too slow to spot the culprit in reasonable time, thus I thought about other approach. Use of MPU comes to my mind and making the memp->next read-only on netbufs list on exit on these functions. I haven't had time, however to check it yet. If you have other idea or think that using MPU in this case is an overkill or not feasible, please share it with me. Many thanks !
Here is the brief log I collected during testing :
memp_init_pool() for MEMP_NETBUF with 16 netbufs set :
MEMP_NETBUF[0] 0x2001caa0 (next 0x0)
MEMP_NETBUF[1] 0x2001cab0 (next 0x2001caa0)
MEMP_NETBUF[2] 0x2001cac0 (next 0x2001cab0)
MEMP_NETBUF[3] 0x2001cad0 (next 0x2001cac0)
MEMP_NETBUF[4] 0x2001cae0 (next 0x2001cad0)
MEMP_NETBUF[5] 0x2001caf0 (next 0x2001cae0)
MEMP_NETBUF[6] 0x2001cb00 (next 0x2001caf0)
MEMP_NETBUF[7] 0x2001cb10 (next 0x2001cb00)
MEMP_NETBUF[8] 0x2001cb20 (next 0x2001cb10)
MEMP_NETBUF[9] 0x2001cb30 (next 0x2001cb20)
MEMP_NETBUF[10] 0x2001cb40 (next 0x2001cb30)
MEMP_NETBUF[11] 0x2001cb50 (next 0x2001cb40)
MEMP_NETBUF[12] 0x2001cb60 (next 0x2001cb50)
MEMP_NETBUF[13] 0x2001cb70 (next 0x2001cb60)
MEMP_NETBUF[14] 0x2001cb80 (next 0x2001cb70)
MEMP_NETBUF[15] 0x2001cb90 (next 0x2001cb80)
and during receiving and sending UDP frames (750 bytes in size with rate up to 10 frames/sec in total incoming/outgoing), the next pointer suddenly points to lwip_ram_heap (notice lines 1 and 4) :
NETBUF allocated 0x2001cb00 (next 0x20015d54)
NETBUF deallocate 0x2001cb00 (next 0x20015d54)
NETBUF allocated 0x2001cb00 (next 0x20015d54)
NETBUF allocated 0x20015d54 (next 0x0)
MEMP_NETBUF 4 of 16 used
ERROR: Socket send error: -3003
Hi,
Recently during testing the application regarding network connectivity (very frequent incoming and outgoing UDP frames) on K64F with mbed-5.13.4, I encountered the NETBUF number limitation (8 by default) which was noticeable with NSAPI_ERROR_PARAMETER returned by UDPSock::sendto(). After brief analysis it turned out that netbuf_new() used inside returns NULL and it is caused by lack of free NETBUFs. It seemed that increasing the default value should solve the issue but it didn't.
Even with higher number of NETBUFs (16, 32, ...) set in lwIP config file (MEMP_NUM_NETBUF), I was still encountering the behaviour that even if there were some netbufs free (only 4 of 16 used), netbuf_new() was returning NULL. Placing the diagnostic printfs in memp_alloc() and memp_free() showed that during runtime *memp->next value used by (de)allocator to point the next free netbuf to be used in next allocation suddenly points to somewhere in lwip_ram_heap. Such netbuf element taken from lwip_ram_heap during allocation, has its next pointer set to NULL and this way during next netbuf_new() call the NULL is returned.
I wonder if such behaviour of (unexpected in my opinion) *memp->next pointer change to the memory outside the memp_netbufs list of available elements is correct ?
After another brief debug with focus on memp_alloc() and memp_free(), it looks like none of these functions make this unexpected change - this wrong value is simply already there while these functions are called. It looks like some other code wrote it there. Unfortunately conditional hardware watchpoints do not work and software ones are too slow to spot the culprit in reasonable time, thus I thought about other approach. Use of MPU comes to my mind and making the memp->next read-only on netbufs list on exit on these functions. I haven't had time, however to check it yet. If you have other idea or think that using MPU in this case is an overkill or not feasible, please share it with me. Many thanks !
Here is the brief log I collected during testing :
memp_init_pool() for MEMP_NETBUF with 16 netbufs set :
and during receiving and sending UDP frames (750 bytes in size with rate up to 10 frames/sec in total incoming/outgoing), the next pointer suddenly points to lwip_ram_heap (notice lines 1 and 4) :