This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
eth_drv_recv blocking DSR
- From: "Hook, James" <jhook at bloomberg dot com>
- To: <ecos-discuss at sources dot redhat dot com>
- Date: Thu, 23 Jun 2005 18:53:28 -0400
- Subject: [ECOS] eth_drv_recv blocking DSR
I am currently writing an Ethernet driver to interface with the FreeBSD
stack. In packages/io/eth/src/net/eth_drv.c, the eth_drv_recv()
function calls MGETHDR which invokes spl_any(). spl_any() has the
potential to block if the calling thread does not own the mutex. I am
calling eth_drv_recv() from my Ethernet driver in a DSR when I receive
an incoming packet as described in /io/eth/v2_0_21/doc/driver_doc. If
the spl_any() call blocks because another thread (the "Network support"
thread in this case) owns the mutex, ECOS crashes in spl_any() when the
DSR attempts to lock the mutex, blocks, and then invokes the scheduler.
I assume this is because the scheduler does not support a DSR blocking
to a thread. Is this true? Should eth_drv_recv have the potential to
block if it is DSR safe?
Stack Trace:
#0 0x000c9c98 in hal_thread_load_context_ARM ()
#1 0x00096e94 in Cyg_Scheduler::unlock_inner (new_lock=2)
#2 0x000e65de in Cyg_Scheduler::reschedule ()
#3 0x00097cd2 in Cyg_Mutex::lock (this=0x15fad0)
#4 0x00095640 in cyg_mutex_lock (mutex=0x15fad0)
#5 0x000a245a in spl_any (which=1)
#6 0x000a2066 in cyg_splimp ()
#7 0x0009faa2 in eth_drv_recv (sc=0x1051ec, total_len=42)
>From frame 4:
(gdb) print *(mutex->owner)
$5 = {stack_base = 1158004, stack_size = 3424, stack_limit = 1158004,
stack_ptr = 1160404, entry_point = 0xa1c69 <cyg_netint+1>,
entry_data = 0, saved_context = 0x0, next = 0x11b8f0, prev = 0x11b8f0,
priority = 6, queue = 0x1049e8, mutex_count = 1,
original_priority = 7, priority_inherited = 1, state = 1,
suspend_count = 0, wakeup_count = 0, wait_info = 1161316, unique_id = 4,
timer = {next = 0x11b920, prev = 0x11b920, counter = 0x161870, alarm =
0x95fd5 <Cyg_ThreadTimer::alarm(Cyg_Alarm*, unsigned int)+1>,
data = 1161504, trigger = 0, interval = 0, enabled = 0, thread =
0x11b8d4}, sleep_reason = CYG_REASON_WAIT,
wake_reason = CYG_REASON_NONE, thread_data = {0, 0, 0, 0, 0, 0}, name
= 0xf24d4 "Network support", list_next = 0x161fd4}
>From frame 5:
print *((cyg_thread*) splx_thread)
$6 = {stack_base = 1158004, stack_size = 3424, stack_limit = 1158004,
stack_ptr = 1160404, entry_point = 0xa1c69 <cyg_netint+1>,
entry_data = 0, saved_context = 0x0, next = 0x11b8f0, prev = 0x11b8f0,
priority = 6, queue = 0x1049e8, mutex_count = 1,
original_priority = 7, priority_inherited = 1, state = 1,
suspend_count = 0, wakeup_count = 0, wait_info = 1161316, unique_id = 4,
timer = {next = 0x11b920, prev = 0x11b920, counter = 0x161870, alarm =
0x95fd5 <Cyg_ThreadTimer::alarm(Cyg_Alarm*, unsigned int)+1>,
data = 1161504, trigger = 0, interval = 0, enabled = 0, thread =
0x11b8d4}, sleep_reason = CYG_REASON_WAIT,
wake_reason = CYG_REASON_NONE, thread_data = {0, 0, 0, 0, 0, 0}, name
= 0xf24d4 "Network support", list_next = 0x161fd4}
Thanks,
James Hook
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss