[ECOS] eth_drv_recv blocking DSR

Hook, James jhook@bloomberg.com
Thu Jun 23 23:06:00 GMT 2005


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



More information about the Ecos-discuss mailing list