Date: Wed, 29 Jul 2009 15:02:29 -0400 From: John Baldwin <jhb@freebsd.org> To: "Chris Harrer" <cjharrer@comcast.net> Cc: freebsd-drivers@freebsd.org Subject: Re: Driver development question Message-ID: <200907291502.30250.jhb@freebsd.org> In-Reply-To: <000e01ca107d$87a6ea60$96f4bf20$@net> References: <002801ca06f0$b1d42af0$157c80d0$@net> <200907291356.51702.jhb@freebsd.org> <000e01ca107d$87a6ea60$96f4bf20$@net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday 29 July 2009 2:51:06 pm Chris Harrer wrote: > >The problem is that kernel threads do not have a valid file descriptor > table, > >hence fd_cdir is NULL. You could work around this if you create a > dedicated > >kproc and set fd_cdir to rootvnode (but vref() rootvnode when you do this). > > >You should also set fd_rdir and fd_jdir to rootvnode as well (also doing > >appropriate vref() of rootvnode for each reference). Something like this: > > > > struct filedesc *fdp; > > > > fdp = curthread->td_proc->p_fd; > > FILEDESC_XLOCK(fdp); > > fd->fd_rdir = rootvnode; > > vref(rootvnode); > > fd->fd_jdir = rootvnode; > > vref(rootvnode); > > fd->fd_cdir = rootvnode; > > vref(rootvnode); > > FILEDESC_XUNLOCK(fdp); > > > >You should not do this from a callout routine or interrupt handler however. > > >You could do this via a TASK to a private taskqueue with a dedicated kernel > > >process however. (i.e. queue a task that does the above during after > >creating the taskqueue and then queue a task to create the file later). > > > >-- > >John Baldwin > > Hi John, > > I tried this and rootvnode = 0x0, so I am still getting a SIGSEGV. I create > a thread in my "attach" routine via: > > status = kproc_create(sxg_dump_thread, adapter, &adapter->dumpproc, > RFNOWAIT , 0, "sxgdump"); > if (status) { > SXG_DBG_MSG(adapter->dev, "%s[%p], Cannot create dump > thread, status: %d\n", > __func__, adapter, status); > return (status); > } > > Then my thread does: > > static void > sxg_dump_thread(void * arg) > { > adapter_t *adapter = (adapter_t *)arg; > struct filedesc *fdp; > ulong32 index = 0; > > // Set up some file descriptor stuff so we can > // actually open/create a dump file. Kernel > // threads, by design, do not have a valid > // file descriptor table. So, we're gonna > // make this thread point to one! > fdp = curthread->td_proc->p_fd; > FILEDESC_XLOCK(fdp); > fdp->fd_rdir = rootvnode; > vref(rootvnode); <----- SIGSEGV on this line, rootvnode = 0x0 > fdp->fd_jdir = rootvnode; > vref(rootvnode); > fdp->fd_cdir = rootvnode; > vref(rootvnode); > FILEDESC_XUNLOCK(fdp); > for (;;){ > ... > > Sorry if I'm doing something obviously wrong, I'm trying to come up to speed > as quickly as I can. Ah, this could happen if you do this during boot. You can work around that by using an EVENTHANDLER() to hook into the 'mountroot' event and not start your kproc until then. To support loading your driver as a module post-boot, you can instead just start the kproc directly if rootvnode != NULL instead of hooking into 'mountroot'. -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907291502.30250.jhb>