Date: Thu, 3 Apr 2003 13:36:06 -0500 (EST) From: Andrew Gallatin <gallatin@cs.duke.edu> To: Nate Lawson <nate@root.org> Cc: current@freebsd.org Subject: Re: mbuf LOR Message-ID: <16012.32534.331966.216694@grasshopper.cs.duke.edu> In-Reply-To: <Pine.BSF.4.21.0304021235150.12236-100000@root.org> References: <Pine.BSF.4.21.0304021235150.12236-100000@root.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Nate Lawson writes:
> I was testing some changes to make fxp MPSAFE and got a LOR in allocating
> the mbuf cluster and then finally a panic when trying to dereference the
> cluster header. Is the mbuf system MPSAFE? Is it ok to call m_getcl
> with a device lock held (but not Giant)?
>
> The lock reversal was: 1. fxp softc lock, 2. Giant.
>
> Traceback:
> zalloc...
> malloc()
> mb_pop_cont()
> mb_alloc()
> m_getcl()
> fxp_add_rfabuf()
> fxp_intr_body()
> fxp_intr() -- locks fxp softc
>
> -Nate
I think the only place it can be coming from is slab_zalloc().
Does the appended (untested) patch help?
BTW, I don't think that there is any need to get Giant for the zone
allocators in the M_NOWAIT case, but I'm not really familar with the
code, and I don't know if the sparc64 uma_small_alloc needs Giant.
BTW, my MPSAFE driver never sees this, but then again, I never
allocate clusters. I use jumbo frames, and carve out my own recv
buffers, so I'm only allocating mbufs, not clusters.
Drew
Index: uma_core.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/uma_core.c,v
retrieving revision 1.51
diff -u -r1.51 uma_core.c
--- uma_core.c 26 Mar 2003 18:44:53 -0000 1.51
+++ uma_core.c 3 Apr 2003 18:22:14 -0000
@@ -703,10 +703,14 @@
wait &= ~M_ZERO;
if (booted || (zone->uz_flags & UMA_ZFLAG_PRIVALLOC)) {
- mtx_lock(&Giant);
- mem = zone->uz_allocf(zone,
- zone->uz_ppera * UMA_SLAB_SIZE, &flags, wait);
- mtx_unlock(&Giant);
+ if ((wait & M_NOWAIT) == 0) {
+ mtx_lock(&Giant);
+ mem = zone->uz_allocf(zone,
+ zone->uz_ppera * UMA_SLAB_SIZE, &flags, wait);
+ mtx_unlock(&Giant);
+ } else {
+ mem = NULL;
+ }
if (mem == NULL) {
ZONE_LOCK(zone);
return (NULL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?16012.32534.331966.216694>
