Author: glebius
Date: Mon Apr  2 05:11:59 2018
New Revision: 331871
URL: https://svnweb.freebsd.org/changeset/base/331871

Log:
  Handle a special case when a slab can fit only one allocation,
  and zone has a large alignment. With alignment taken into
  account uk_rsize will be greater than space in a slab. However,
  since we have only one item per slab, it is always naturally
  aligned.
  
  Code that will panic before this change with 4k page:
  
        z = uma_zcreate("test", 3984, NULL, NULL, NULL, NULL, 31, 0);
        uma_zalloc(z, M_WAITOK);
  
  A practical scenario to hit the panic is a machine with 56 CPUs
  and 2 NUMA domains, which yields in zone size of 3984.
  
  PR:           227116
  MFC after:    2 weeks

Modified:
  head/sys/vm/uma_core.c

Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c      Sun Apr  1 22:59:53 2018        (r331870)
+++ head/sys/vm/uma_core.c      Mon Apr  2 05:11:59 2018        (r331871)
@@ -1290,7 +1290,15 @@ keg_small_init(uma_keg_t keg)
        else 
                shsize = sizeof(struct uma_slab);
 
-       keg->uk_ipers = (slabsize - shsize) / rsize;
+       if (rsize <= slabsize - shsize)
+               keg->uk_ipers = (slabsize - shsize) / rsize;
+       else {
+               /* Handle special case when we have 1 item per slab, so
+                * alignment requirement can be relaxed. */
+               KASSERT(keg->uk_size <= slabsize - shsize,
+                   ("%s: size %u greater than slab", __func__, keg->uk_size));
+               keg->uk_ipers = 1;
+       }
        KASSERT(keg->uk_ipers > 0 && keg->uk_ipers <= SLAB_SETSIZE,
            ("%s: keg->uk_ipers %u", __func__, keg->uk_ipers));
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to