Project Home
Project Home
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - QNET module crashes when my .SO driver is already unloaded: (2 Items)
   
QNET module crashes when my .SO driver is already unloaded  
To test my newly created TAP driver I made a few scripts, and I have a problem with this one:

---
#!/bin/sh
for a in 1 2 3 4 5 6 7 8 9 10 ... 100
do 
    ifconfig tap0 destroy
    ifconfig || { echo "list interfaces failed"; exit 1; }
    mount -T io-pkt -o mac=aaaaaaaaaaaa,verbose=7 devnp-rtap.so || { echo "mount failed"; exit 1; }
    ifconfig tap0 10.0.0.1 netmask 255.255.255.0 || { echo "ifconfig failed"; exit 1; }
    route add -host 10.0.0.2 10.0.0.1
done
---

It seems that sometimes after the .so file is unloaded, QNET is making segmentation fault (signal 11).
Even stranger is the fact that when I remove creation of a special thread I made for Resource Manager, this script seems
 to work fine.
I've tried using both nw_thread and standard pthread; I also tried making 1s delay before my .so is unloaded (in detach 
function), and using various functions from io-pkt (like quiesce_all() or nw_thread_untracked_add()). But nothing seems 
to help - the library terminates,
usually on listing interfaces, after several tenths of iterations.

Here's a typical backtrace.
I don't have compilable source of io-pkt, so this is standard io-pkt-v4-hc from QNX 6.4.1:
---
#0  segv_handler (signo=11) at /home/builder/hudson/641/svn/lib/io-pkt/sys/main.c:498
498		*(int *)NULL = 0; /* segv for real now */
(gdb) #0  segv_handler (signo=11) at /home/builder/hudson/641/svn/lib/io-pkt/sys/main.c:498
No locals.
#1  <signal handler called>
No symbol table info available.
#2  0xb8220892 in try_ifp (ifp=0x81931c0)
    at /home/builder/hudson/641/svn/lib/io-pkt/sys/lsm/qnet/l4_lite/l4_driver_en_iopkt.c:310
	dp = <value optimized out>
	ndb_if = <value optimized out>
	nret = <value optimized out>
	empty_slot = <value optimized out>
	I = <value optimized out>
	__FUNCTION__ = "try_ifp"
#3  0xb82298f4 in scavenger (ctp=0x8194778, code=0, flags=0, hdl=0x0)
    at /home/builder/hudson/641/svn/lib/io-pkt/sys/lsm/qnet/ndb/ndb.c:268
	chstate = 0
	next = {it_value = {tv_sec = 2956070192, tv_nsec = 135521472}, it_interval = {tv_sec = 135874424, 
    tv_nsec = -1338782302}}
	ifep = (struct ndb_ifent *) 0x813d620
	ifepp = (struct ndb_ifent **) 0x813d740
	iflist_tmp = (struct ndb_ifent *) 0x813d770
#4  0xb03349af in _message_handler (dctp=0x8194778)
    at /home/builder/hudson/641/svn/lib/c/dispatch/message.c:329
	i = 3
	vec = (message_vec_t *) 0x813e490
	def_vec = (message_vec_t *) 0x0
	code = 0
	mutex = (pthread_mutex_t *) 0x8140150
#5  0xb0333768 in dispatch_handler (ctp=0x81931c0)
    at /home/builder/hudson/641/svn/lib/c/dispatch/dispatch.c:328
No locals.
#6  0xb8219188 in qdpp_handle_thread (arg=0x813f1d0)
    at /home/builder/hudson/641/svn/lib/io-pkt/sys/lsm/qnet/l4_lite/iopkt.c:111
	ctp0 = (dispatch_context_t *) 0x8194778
	ctp = (dispatch_context_t *) 0x8194778
	__FUNCTION__ = "qdpp_handle_thread"
#7  0x080c9d8b in thread_init (arg=0x813f1d0)
    at /home/builder/hudson/641/svn/lib/io-pkt/sys/nw_thread.c:765
	wtp = (struct nw_work_thread *) 0x8194e80
	funcp = (void *(*)(void *)) 0xb82190b6 <qdpp_handle_thread>
	err = <value optimized out>
#8  0xb031fa20 in ?? () from /usr/qnx641/target/qnx6/x86/lib/libc.so.3
---

How should I force qnet to leave my interface alone?
This is simplified code of my tap_detach() function:

---
    tap_stop(ifp, 1);
    if_down(ifp);
    ether_ifdetach(ifp);
    if_detach(ifp);
    nw_pthread_reap(sc->rm.restid,sc);
    interrupt_entry_remove(&sc->sc_inter, NULL);
    shutdownhook_disestablish(sc->sc_sdhook);
---

And here's simplified cleanup function of the thread:
---
    pulse_detach(sc->rm.dpp, sc->rm.quiesce_code, 0);
    if (resmgr_detach(sc->rm.dpp, sc->rm.rid, 0) == -1) {
            LOGE("%s: resmgr_detach failed: %s", DEV_NAME_TAP, strerror(errno));
    }
    sc->rm.rid = -1;
---
Re: QNET module crashes when my .SO driver is already unloaded  
Ok, I found a workaround for this.

The problem may occur always - not only when multiple threads are used.

IFP pointer is given to QNET, and then used with time delay. If in a meantime the driver is detached and its memory 
freed (dev_free() is called from dev_detach()) then QNET produces segmentation fault. It is only a matter of luck that 
the problem isn't occurring with most drivers.

My workaround is to make memleak - put:
    dev->dv_alloc = NULL;
at the end of drivers detach() function. This prevents dev_detach() from freeing memory which may be still queued by 
QNET. Memory is leaked only when an interface is detached, so it usually isn't big problem.

I don't think there's another solution for this problem in io-pkt from QNX 6.4.1.