hammer-inodes: malloc limit exceeded

YONETANI Tomokazu qhwt+dfly at les.ath.cx
Sat Dec 27 20:00:22 PST 2008


On Sat, Dec 27, 2008 at 06:43:06PM +0900, YONETANI Tomokazu wrote:
> >     Once you get a crash dump over to leaf then please lower the limit
> >     and see if you can panic the machine.
> 
> Sure.  Oh, BTW, although this machine has two HAMMER partitions mounted
> (/HAMMER and /var/vkernel), I was only using the former for blogbench,
> the latter was mounted but totally idle.

I don't know exactly how desiredvnodes limits the amount of kmalloc's,
but I did notice that there are two places where it's used to compute
HAMMER-related values:
  - hammer_vfs_init(): vfs.hammer.limit_iqueued is computed at the first
    call and set to desiredvnodes / 5; after that, you need to set it
    manually
  - hammer_vfs_mount(): if I understand the code correctly, malloc limit
    is only updated when the HAMMER volume is unmounted then mounted.

So I went into single-user mode, set these parameters, unmounted and
re-mounted the HAMMER filesystems.  It seems that with kern.maxvnodes=100000
it can still panic the machine.

BTW, I have a few questions WRT kmalloc():

kern_slaballoc.c:478
  while (type->ks_loosememuse >= type->ks_limit) {
      int i;
      long ttl;

      for (i = ttl = 0; i < ncpus; ++i)
          ttl += type->ks_memuse[i];
      type->ks_loosememuse = ttl;     /* not MP synchronized */
      if (ttl >= type->ks_limit) {
          if (flags & M_NULLOK) {
              logmemory(malloc, NULL, type, size, flags);
              return(NULL);
          }
          panic("%s: malloc limit exceeded", type->ks_shortdesc);
      }
  }

1. don't we need M_LOOPOK flag, which tells kmalloc() to wait until
   the sum of ks_memuse[] becomes lower than ks_limit?  of course
   only when !M_NULLOK && M_WAITOK.
   struct hammer_inode is fairly small in size, so there could be
   a good chance that a couple of them gets reclaimed after a while.

2. I know ks_loosememuse is not MP synchronized, but ks_memuse[] is
   summed up without any locks, either.  couldn't there be a race?

3. shouldn't the conditionals be
   while (type->ks_loosememuse + size >= type->ks_limit) {
      ...
      if (ttl + size >= type->ks_limit) ...

   to catch the situation earlier?

Thanks in advance.





More information about the Bugs mailing list