]> git.proxmox.com Git - mirror_spl.git/commitdiff
Fix CPU hotplug
authorBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 12 Oct 2015 19:31:05 +0000 (12:31 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 13 Oct 2015 16:50:40 +0000 (09:50 -0700)
Allocate a kmem cache magazine for every possible CPU which might
be added to the system.  This ensures that when one of these CPUs
is enabled it can be safely used immediately.

For many systems the number of online CPUs is identical to the
number of present CPUs so this does imply an increased memory
footprint.  In fact, dynamically allocating the array of magazine
pointers instead of using the worst case NR_CPUS can end up
decreasing our memory footprint.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ned Bass <bass6@llnl.gov>
Closes #482

include/sys/kmem_cache.h
module/spl/spl-kmem-cache.c

index 75a0a55b7d1f18bf6a8870b1a5b17f4a98df405a..e971c2b0d9522679b5aff50223f5c188cd044fbb 100644 (file)
@@ -170,7 +170,7 @@ typedef struct spl_kmem_cache {
        uint32_t                skc_magic;      /* Sanity magic */
        uint32_t                skc_name_size;  /* Name length */
        char                    *skc_name;      /* Name string */
-       spl_kmem_magazine_t     *skc_mag[NR_CPUS]; /* Per-CPU warm cache */
+       spl_kmem_magazine_t     **skc_mag;      /* Per-CPU warm cache */
        uint32_t                skc_mag_size;   /* Magazine size */
        uint32_t                skc_mag_refill; /* Magazine refill count */
        spl_kmem_ctor_t         skc_ctor;       /* Constructor */
index a7f9ca3a5d9931f171a440783dde9c441c4c1d20..5a8493fe4c3c73515d0af77a2e6a06d48523a66c 100644 (file)
@@ -805,15 +805,18 @@ spl_magazine_create(spl_kmem_cache_t *skc)
        if (skc->skc_flags & KMC_NOMAGAZINE)
                return (0);
 
+       skc->skc_mag = kzalloc(sizeof (spl_kmem_magazine_t *) *
+           num_possible_cpus(), kmem_flags_convert(KM_SLEEP));
        skc->skc_mag_size = spl_magazine_size(skc);
        skc->skc_mag_refill = (skc->skc_mag_size + 1) / 2;
 
-       for_each_online_cpu(i) {
+       for_each_possible_cpu(i) {
                skc->skc_mag[i] = spl_magazine_alloc(skc, i);
                if (!skc->skc_mag[i]) {
                        for (i--; i >= 0; i--)
                                spl_magazine_free(skc->skc_mag[i]);
 
+                       kfree(skc->skc_mag);
                        return (-ENOMEM);
                }
        }
@@ -833,11 +836,13 @@ spl_magazine_destroy(spl_kmem_cache_t *skc)
        if (skc->skc_flags & KMC_NOMAGAZINE)
                return;
 
-       for_each_online_cpu(i) {
+       for_each_possible_cpu(i) {
                skm = skc->skc_mag[i];
                spl_cache_flush(skc, skm, skm->skm_avail);
                spl_magazine_free(skm);
        }
+
+       kfree(skc->skc_mag);
 }
 
 /*
@@ -880,12 +885,6 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
 
        might_sleep();
 
-       /*
-        * Allocate memory for a new cache and initialize it.  Unfortunately,
-        * this usually ends up being a large allocation of ~32k because
-        * we need to allocate enough memory for the worst case number of
-        * cpus in the magazine, skc_mag[NR_CPUS].
-        */
        skc = kzalloc(sizeof (*skc), lflags);
        if (skc == NULL)
                return (NULL);