summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrakash Surya <[email protected]>2012-08-23 14:00:58 -0700
committerBrian Behlendorf <[email protected]>2012-08-24 09:43:22 -0700
commit08850eddcb128cbdca584255324d71dfee2ccba9 (patch)
tree000c6cd4d1c90648a02593cca4d786146f6ceb59
parent15d0411297113cb2681f5522ed373d4d37fcf132 (diff)
Avoid calling smp_processor_id in spl_magazine_age
The spl_magazine_age function had the implied assumption that it will remain on its current cpu through its execution. In order to support preempt enabled kernels, this assumption had to be removed. The spl_kmem_magazine structure now holds the cpu id of the cpu it is local to. This allows spl_magazine_age to use this field when scheduling work to be done by the magazine's local cpu. Signed-off-by: Brian Behlendorf <[email protected]> Issue #98
-rw-r--r--include/sys/kmem.h1
-rw-r--r--module/spl/spl-kmem.c12
2 files changed, 7 insertions, 6 deletions
diff --git a/include/sys/kmem.h b/include/sys/kmem.h
index 4383efb7c..344e2716b 100644
--- a/include/sys/kmem.h
+++ b/include/sys/kmem.h
@@ -353,6 +353,7 @@ typedef struct spl_kmem_magazine {
struct spl_kmem_cache *skm_cache; /* Owned by cache */
struct delayed_work skm_work; /* Magazine reclaim work */
unsigned long skm_age; /* Last cache access */
+ unsigned int skm_cpu; /* Owned by cpu */
void *skm_objs[0]; /* Object pointers */
} spl_kmem_magazine_t;
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
index 28afc6024..258d61478 100644
--- a/module/spl/spl-kmem.c
+++ b/module/spl/spl-kmem.c
@@ -1156,18 +1156,17 @@ spl_magazine_age(void *data)
spl_kmem_magazine_t *skm =
spl_get_work_data(data, spl_kmem_magazine_t, skm_work.work);
spl_kmem_cache_t *skc = skm->skm_cache;
- int i = smp_processor_id();
ASSERT(skm->skm_magic == SKM_MAGIC);
ASSERT(skc->skc_magic == SKC_MAGIC);
- ASSERT(skc->skc_mag[i] == skm);
+ ASSERT(skc->skc_mag[skm->skm_cpu] == skm);
if (skm->skm_avail > 0 &&
time_after(jiffies, skm->skm_age + skc->skc_delay * HZ))
(void)spl_cache_flush(skc, skm, skm->skm_refill);
if (!test_bit(KMC_BIT_DESTROY, &skc->skc_flags))
- schedule_delayed_work_on(i, &skm->skm_work,
+ schedule_delayed_work_on(skm->skm_cpu, &skm->skm_work,
skc->skc_delay / 3 * HZ);
}
@@ -1267,14 +1266,14 @@ spl_magazine_size(spl_kmem_cache_t *skc)
* Allocate a per-cpu magazine to associate with a specific core.
*/
static spl_kmem_magazine_t *
-spl_magazine_alloc(spl_kmem_cache_t *skc, int node)
+spl_magazine_alloc(spl_kmem_cache_t *skc, int cpu)
{
spl_kmem_magazine_t *skm;
int size = sizeof(spl_kmem_magazine_t) +
sizeof(void *) * skc->skc_mag_size;
SENTRY;
- skm = kmem_alloc_node(size, KM_SLEEP, node);
+ skm = kmem_alloc_node(size, KM_SLEEP, cpu_to_node(cpu));
if (skm) {
skm->skm_magic = SKM_MAGIC;
skm->skm_avail = 0;
@@ -1283,6 +1282,7 @@ spl_magazine_alloc(spl_kmem_cache_t *skc, int node)
skm->skm_cache = skc;
spl_init_delayed_work(&skm->skm_work, spl_magazine_age, skm);
skm->skm_age = jiffies;
+ skm->skm_cpu = cpu;
}
SRETURN(skm);
@@ -1318,7 +1318,7 @@ spl_magazine_create(spl_kmem_cache_t *skc)
skc->skc_mag_refill = (skc->skc_mag_size + 1) / 2;
for_each_online_cpu(i) {
- skc->skc_mag[i] = spl_magazine_alloc(skc, cpu_to_node(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]);