Xilinx / embeddedsw

Xilinx Embedded Software (embeddedsw) Development

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

lwIP: calling pbuf_free in interrupt context without protection in RAW API mode

yzhang0231 opened this issue · comments

In bare-metal application derived from a hello world template when default configuration is used, emacps_send_handler will be called in interrupt context, in which xemacps_process_sent_bds calls pbuf_free.

void emacps_send_handler(void *arg)
{
struct xemac_s *xemac;
xemacpsif_s *xemacpsif;
XEmacPs_BdRing *txringptr;
u32_t regval;
#if !NO_SYS
xInsideISR++;
#endif
xemac = (struct xemac_s *)(arg);
xemacpsif = (xemacpsif_s *)(xemac->state);
txringptr = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,XEMACPS_TXSR_OFFSET, regval);
/* If Transmit done interrupt is asserted, process completed BD's */
xemacps_process_sent_bds(xemacpsif, txringptr);

However, the protection macro for calling mem_free/pbuf_free, LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT, will only be emit to lwipopts.h in SOCKET API mode:

if {$api_mode == "SOCKET_API"} {
set sw_proc_handle [hsi::get_sw_processor]
set os_handle [hsi::get_os]
set os_name [common::get_property NAME $os_handle]
if { [string compare -nocase "freertos10_xilinx" $os_name] == 0} {
# mbox options
set lwip_tcpip_core_locking_input [common::get_property CONFIG.lwip_tcpip_core_locking_input $libhandle]
set tcpip_mbox_size [common::get_property CONFIG.tcpip_mbox_size $libhandle]
set default_tcp_recvmbox_size [common::get_property CONFIG.default_tcp_recvmbox_size $libhandle]
set default_udp_recvmbox_size [common::get_property CONFIG.default_udp_recvmbox_size $libhandle]
puts $lwipopts_fd "\#define DEFAULT_THREAD_PRIO $thread_prio"
if {$processor_type == "psu_cortexa53" || $processor_type == "psv_cortexa72" } {
puts $lwipopts_fd "\#define TCPIP_THREAD_PRIO ($thread_prio)"
} else {
puts $lwipopts_fd "\#define TCPIP_THREAD_PRIO ($thread_prio + 1)"
}
puts $lwipopts_fd "\#define TCPIP_THREAD_STACKSIZE 1024"
puts $lwipopts_fd "\#define DEFAULT_TCP_RECVMBOX_SIZE $default_tcp_recvmbox_size"
puts $lwipopts_fd "\#define DEFAULT_ACCEPTMBOX_SIZE 5"
puts $lwipopts_fd "\#define TCPIP_MBOX_SIZE $tcpip_mbox_size"
puts $lwipopts_fd "\#define DEFAULT_UDP_RECVMBOX_SIZE $default_udp_recvmbox_size"
puts $lwipopts_fd "\#define DEFAULT_RAW_RECVMBOX_SIZE 30"
puts $lwipopts_fd "\#define LWIP_COMPAT_MUTEX 0"
puts $lwipopts_fd "\#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 1"
if {$lwip_tcpip_core_locking_input == true} {
puts $lwipopts_fd "\#define LWIP_TCPIP_CORE_LOCKING_INPUT 1"
}
puts $lwipopts_fd ""
}
}

The user manual from lwIP can be found below:

2008-06-30 Simon Goldschmidt
* mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from
interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows
mem_free to run between mem_malloc iterations. Added illegal counter for
mem stats.