Re: mbuf LOR

2003-04-04 Thread Nate Lawson
On Thu, 3 Apr 2003, Andrew Gallatin wrote:
 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.
 
 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.c26 Mar 2003 18:44:53 -  1.51
 +++ uma_core.c3 Apr 2003 18:22:14 -
 @@ -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);

You're right about where the problem is (top of stack trace and listing 
below).  However, your patch causes an immediate panic on boot due to a 
NULL deref.  I don't think you want it to always return NULL if called 
with M_NOWAIT set.  :)  Other ideas?

slab_zalloc + 0xdf
uma_zone_slab + 0xd8
uma_zalloc_bucket + 0x15d
uma_zalloc_arg + 0x307
malloc
...
m_getcl

(gdb) l *slab_zalloc+0xdf
0xc02f646f is in slab_zalloc (../../../vm/uma_core.c:707).
702 else
703 wait = ~M_ZERO;
704 
705 if (booted || (zone-uz_flags  UMA_ZFLAG_PRIVALLOC)) {
706 mtx_lock(Giant);
707 mem = zone-uz_allocf(zone, 
708 zone-uz_ppera * UMA_SLAB_SIZE, flags, wait);
709 mtx_unlock(Giant);
710 if (mem == NULL) {
711 ZONE_LOCK(zone);

-Nate

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]


Giant required by uma (was Re: mbuf LOR)

2003-04-04 Thread Andrew Gallatin

Nate Lawson writes:

  
  You're right about where the problem is (top of stack trace and listing 
  below).  However, your patch causes an immediate panic on boot due to a 
  NULL deref.  I don't think you want it to always return NULL if called 
  with M_NOWAIT set.  :)  Other ideas?
  


I suppose the only alternative is to do it right and remove Giant
from the uma zone alloc code.

From looking at the code for a little while this morning, it looks
like there are 3 allocators that could be called at this point in the
code: 


1) page_alloc():

Calls kmem_malloc().  Should be MPSAFE on NOWAIT allocations.  Needs
Giant on WAITOK allocations.

2) obj_alloc():

Calls vm_page_alloc() -- that's MPSAFE.

Calls pmap_qenter() -- I've got no freaking clue if that's MPSAFE on
all platforms.   I think it is, since kmem_malloc is MPSAFE  it
calls pmap_enter(), but I'm not sure.


uma_small_alloc():

i386 - no uma_small_alloc, no problem
alpha - uma_small_alloc is SMP safe
ia64 - uma_small_alloc should be SMP safe, as it seems to be
doing just the moral equivalent of PHYS_TO_K0SEG() to map the memory
into the kernel.
sparc64: I have no idea..


Drew


  slab_zalloc + 0xdf
  uma_zone_slab + 0xd8
  uma_zalloc_bucket + 0x15d
  uma_zalloc_arg + 0x307
  malloc
  ...
  m_getcl
  
  (gdb) l *slab_zalloc+0xdf
  0xc02f646f is in slab_zalloc (../../../vm/uma_core.c:707).
  702 else
  703 wait = ~M_ZERO;
  704 
  705 if (booted || (zone-uz_flags  UMA_ZFLAG_PRIVALLOC)) {
  706 mtx_lock(Giant);
  707 mem = zone-uz_allocf(zone, 
  708 zone-uz_ppera * UMA_SLAB_SIZE, flags, wait);
  709 mtx_unlock(Giant);
  710 if (mem == NULL) {
  711 ZONE_LOCK(zone);




___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: mbuf LOR

2003-04-04 Thread Andrew Gallatin

Nate Lawson writes:
  You're right about where the problem is (top of stack trace and listing 
  below).  However, your patch causes an immediate panic on boot due to a 
  NULL deref.  I don't think you want it to always return NULL if called 
  with M_NOWAIT set.  :)  Other ideas?

The following patch boots  passed the basic 'make -j16 buildworld'
test on x86 SMP.  As I outlined before, I'm not certain if it is safe
on all platforms.

I'm really eager to see your fxp locking diffs.  Even if you're not
comfortable sharing them with the world yet, I'd be interested in
helping out on this.

Drew


Index: vm/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
--- vm/uma_core.c   26 Mar 2003 18:44:53 -  1.51
+++ vm/uma_core.c   4 Apr 2003 15:11:34 -
@@ -703,10 +703,15 @@
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 = zone-uz_allocf(zone, 
+   zone-uz_ppera * UMA_SLAB_SIZE, flags, wait);
+   }
if (mem == NULL) {
ZONE_LOCK(zone);
return (NULL);


___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: mbuf LOR

2003-04-03 Thread Harti Brandt
On Wed, 2 Apr 2003, Bosko Milekic wrote:

BM  For what concerns DONTWAIT, you should theoretically be allowed to
BM  hold a driver lock.  But again, there may be a problem.  Specifically,
BM  I see that UMA code has some explicit Giant acquires/frees in certain
BM  places.  When the UMA code gets called from the malloc() code while
BM  the bucket is being internally allocated in mb_alloc, you may be
BM  hitting one of those paths.  In fact, unless you have a specific Giant
BM  acquire in the fxp_* routines you list in your trace below, that is
BM  undoubtedly what is happening because there are no explicit Giant
BM  acquires in the code path from m_getcl() to malloc(), so they must be
BM  happening higher up in the call stack.

Well, that's interesting.

A month ago or so I sent a patch to smp@ with an update to the malloc page
documenting the locking requirements. I got only one response. I wonder,
how people are expected to correctly use an API, when that API is poorly
documented (malloc(9) in this case, but mbuf(9)  does not mention 'lock'
either). I would ask people knowing the topic to comment on this. As soon
as this EC proposal nightmare is over, I may try to write a corresponding
section for mbuf(9).

Regards,
harti

Index: malloc.9
===
RCS file: /home/ncvs/src/share/man/man9/malloc.9,v
retrieving revision 1.30
diff -u -r1.30 malloc.9
--- malloc.924 Feb 2003 05:53:27 -  1.30
+++ malloc.917 Mar 2003 15:06:14 -
@@ -147,44 +147,22 @@
 to return
 .Dv NULL
 if the request cannot be immediately fulfilled due to resource shortage.
-Otherwise, the current process may be put to sleep to wait for
-resources to be released by other processes.
-If this flag is set,
-.Fn malloc
-will return
-.Dv NULL
-rather than block.
 Note that
 .Dv M_NOWAIT
-is defined to be 0, meaning that blocking operation is the default.
-Also note that
-.Dv M_NOWAIT
 is required when running in an interrupt context.
-.Pp
-Programmers should be careful not to confuse
-.Dv M_NOWAIT ,
-the
-.Fn malloc
-flag, with
-.Dv M_DONTWAIT ,
-an
-.Xr mbuf 9
-allocation flag, which is not a valid argument to
-.Fn malloc .
 .It Dv M_WAITOK
-Indicates that it is Ok to wait for resources.  It is unconveniently
-defined as 0 so care should be taken never to compare against this value
-directly or try to AND it as a flag.  The default operation is to block
-until the memory allocation succeeds.
+Indicates that it is ok to wait for resources.
+If the request cannot be immediately fulfilled the current process is put
+to sleep to wait for resources to be released by other processes.
 The
 .Fn malloc ,
 .Fn realloc ,
 and
 .Fn reallocf
-functions can only return
+functions cannot return
 .Dv NULL
 if
-.Dv M_NOWAIT
+.Dv M_WAITOK
 is specified.
 .It Dv M_USE_RESERVE
 Indicates that the system can dig into its reserve in order to obtain the
@@ -194,6 +172,12 @@
 programming.
 .El
 .Pp
+Exactly one of either
+.Dv M_WAITOK
+or
+.Dv M_NOWAIT
+must be specified.
+.Pp
 The
 .Fa type
 argument is used to perform statistics on memory usage, and for
@@ -244,11 +228,37 @@
 While it should not be relied upon, this information may be useful for
 optimizing the efficiency of memory use.
 .Pp
-Malloc flags documented above should
-.Em NOT
-be used with
+Programmers should be careful not to confuse the malloc flags
+.Dv M_NOWAIT
+and
+.Dv M_WAITOK
+with the
 .Xr mbuf 9
-routines as it will cause undesired results.
+flags
+.Dv M_DONTWAIT
+and
+.Dv M_TRYWAIT .
+.Sh LOCKING CONSIDERATIONS
+.Fn malloc ,
+.Fn realloc
+and
+.Fn reallocf
+may not be called from fast interrupts handlers.
+When called from threaded interrupts
+.Ar flag
+must contain
+.Dv M_NOWAIT .
+.Pp
+.Fn malloc ,
+.Fn realloc
+and
+.Fn reallocf
+must not be called with
+.Dv M_WAITOK
+while a mutex other than Giant is held.
+Giant may or may not be held when
+.Fn free
+is called.
 .Pp
 Any calls to
 .Fn malloc
--
harti brandt,
http://www.fokus.fraunhofer.de/research/cc/cats/employees/hartmut.brandt/private
[EMAIL PROTECTED], [EMAIL PROTECTED]
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: mbuf LOR

2003-04-03 Thread Andrew Gallatin

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 -  1.51
+++ uma_core.c  3 Apr 2003 18:22:14 -
@@ -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);
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]


mbuf LOR

2003-04-02 Thread Nate Lawson
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

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: mbuf LOR

2003-04-02 Thread Andrew Gallatin

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

I thought that this had been fixed.  Which zalloc() exactly?


Drew
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: mbuf LOR

2003-04-02 Thread Bosko Milekic

On Wed, Apr 02, 2003 at 12:39:30PM -0800, Nate Lawson wrote:
 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)?

  Not necessarily if you're doing a TRYWAIT mbuf allocation.  Notably,
  the TRYWAIT allocation may end up in a call to the reclaim routine
  which calls the protocol drain routines which may end up in an LOR if
  you're holding some lock that can also be touched from the drain
  routines.  So, in other words, if you do do that you'd have to be very
  careful.  But there is another problem.  kmem_malloc() still requires
  Giant for blockable allocations (TRYWAIT in this case) and so Giant
  must be held going in there if you're doing a TRYWAIT allocation.

  For what concerns DONTWAIT, you should theoretically be allowed to
  hold a driver lock.  But again, there may be a problem.  Specifically,
  I see that UMA code has some explicit Giant acquires/frees in certain
  places.  When the UMA code gets called from the malloc() code while
  the bucket is being internally allocated in mb_alloc, you may be
  hitting one of those paths.  In fact, unless you have a specific Giant
  acquire in the fxp_* routines you list in your trace below, that is
  undoubtedly what is happening because there are no explicit Giant
  acquires in the code path from m_getcl() to malloc(), so they must be
  happening higher up in the call stack.

 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

-- 
Bosko Milekic
[EMAIL PROTECTED]
[EMAIL PROTECTED]

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to [EMAIL PROTECTED]