git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
powerpc/ps3: Printing fixups for l64 to ll64 conversion arch/powerpc
[safe/jmp/linux-2.6]
/
mm
/
slub.c
diff --git
a/mm/slub.c
b/mm/slub.c
index
8f4edac
..
6392ae5
100644
(file)
--- a/
mm/slub.c
+++ b/
mm/slub.c
@@
-24,6
+24,7
@@
#include <linux/kallsyms.h>
#include <linux/memory.h>
#include <linux/math64.h>
#include <linux/kallsyms.h>
#include <linux/memory.h>
#include <linux/math64.h>
+#include <linux/fault-inject.h>
/*
* Lock order:
/*
* Lock order:
@@
-696,7
+697,7
@@
static int check_object(struct kmem_cache *s, struct page *page,
if (!check_valid_pointer(s, page, get_freepointer(s, p))) {
object_err(s, page, p, "Freepointer corrupt");
/*
if (!check_valid_pointer(s, page, get_freepointer(s, p))) {
object_err(s, page, p, "Freepointer corrupt");
/*
- * No choice but to zap it and thus lo
o
se the remainder
+ * No choice but to zap it and thus lose the remainder
* of the free objects in this slab. May cause
* another error because the object count is now wrong.
*/
* of the free objects in this slab. May cause
* another error because the object count is now wrong.
*/
@@
-1595,6
+1596,11
@@
static __always_inline void *slab_alloc(struct kmem_cache *s,
unsigned long flags;
unsigned int objsize;
unsigned long flags;
unsigned int objsize;
+ might_sleep_if(gfpflags & __GFP_WAIT);
+
+ if (should_failslab(s->objsize, gfpflags))
+ return NULL;
+
local_irq_save(flags);
c = get_cpu_slab(s, smp_processor_id());
objsize = c->objsize;
local_irq_save(flags);
c = get_cpu_slab(s, smp_processor_id());
objsize = c->objsize;
@@
-1964,7
+1970,7
@@
static DEFINE_PER_CPU(struct kmem_cache_cpu,
kmem_cache_cpu)[NR_KMEM_CACHE_CPU];
static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
kmem_cache_cpu)[NR_KMEM_CACHE_CPU];
static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
-static
cpumask_t kmem_cach_cpu_free_init_once = CPU_MASK_NONE
;
+static
DECLARE_BITMAP(kmem_cach_cpu_free_init_once, CONFIG_NR_CPUS)
;
static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
int cpu, gfp_t flags)
static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
int cpu, gfp_t flags)
@@
-2039,13
+2045,13
@@
static void init_alloc_cpu_cpu(int cpu)
{
int i;
{
int i;
- if (cpu
_isset(cpu, kmem_cach_cpu_free_init_once
))
+ if (cpu
mask_test_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once)
))
return;
for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--)
free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu);
return;
for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--)
free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu);
- cpu
_set(cpu, kmem_cach_cpu_free_init_once
);
+ cpu
mask_set_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once)
);
}
static void __init init_alloc_cpu(void)
}
static void __init init_alloc_cpu(void)
@@
-2077,8
+2083,7
@@
static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
* when allocating for the kmalloc_node_cache. This is used for bootstrapping
* memory on a fresh node that has no slab structures yet.
*/
* when allocating for the kmalloc_node_cache. This is used for bootstrapping
* memory on a fresh node that has no slab structures yet.
*/
-static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags,
- int node)
+static void early_kmem_cache_node_alloc(gfp_t gfpflags, int node)
{
struct page *page;
struct kmem_cache_node *n;
{
struct page *page;
struct kmem_cache_node *n;
@@
-2116,7
+2121,6
@@
static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags,
local_irq_save(flags);
add_partial(n, page, 0);
local_irq_restore(flags);
local_irq_save(flags);
add_partial(n, page, 0);
local_irq_restore(flags);
- return n;
}
static void free_kmem_cache_nodes(struct kmem_cache *s)
}
static void free_kmem_cache_nodes(struct kmem_cache *s)
@@
-2148,8
+2152,7
@@
static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
n = &s->local_node;
else {
if (slab_state == DOWN) {
n = &s->local_node;
else {
if (slab_state == DOWN) {
- n = early_kmem_cache_node_alloc(gfpflags,
- node);
+ early_kmem_cache_node_alloc(gfpflags, node);
continue;
}
n = kmem_cache_alloc_node(kmalloc_caches,
continue;
}
n = kmem_cache_alloc_node(kmalloc_caches,
@@
-2251,7
+2254,7
@@
static int calculate_sizes(struct kmem_cache *s, int forced_order)
* Add some empty padding so that we can catch
* overwrites from earlier objects rather than let
* tracking information or the free pointer be
* Add some empty padding so that we can catch
* overwrites from earlier objects rather than let
* tracking information or the free pointer be
- * corrupted if a
n
user writes before the start
+ * corrupted if a user writes before the start
* of the object.
*/
size += sizeof(void *);
* of the object.
*/
size += sizeof(void *);
@@
-2935,8
+2938,10
@@
static int slab_memory_callback(struct notifier_block *self,
case MEM_CANCEL_OFFLINE:
break;
}
case MEM_CANCEL_OFFLINE:
break;
}
-
- ret = notifier_from_errno(ret);
+ if (ret)
+ ret = notifier_from_errno(ret);
+ else
+ ret = NOTIFY_OK;
return ret;
}
return ret;
}
@@
-3125,8
+3130,12
@@
struct kmem_cache *kmem_cache_create(const char *name, size_t size,
s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
up_write(&slub_lock);
s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
up_write(&slub_lock);
- if (sysfs_slab_alias(s, name))
+ if (sysfs_slab_alias(s, name)) {
+ down_write(&slub_lock);
+ s->refcount--;
+ up_write(&slub_lock);
goto err;
goto err;
+ }
return s;
}
return s;
}
@@
-3136,8
+3145,13
@@
struct kmem_cache *kmem_cache_create(const char *name, size_t size,
size, align, flags, ctor)) {
list_add(&s->list, &slab_caches);
up_write(&slub_lock);
size, align, flags, ctor)) {
list_add(&s->list, &slab_caches);
up_write(&slub_lock);
- if (sysfs_slab_add(s))
+ if (sysfs_slab_add(s)) {
+ down_write(&slub_lock);
+ list_del(&s->list);
+ up_write(&slub_lock);
+ kfree(s);
goto err;
goto err;
+ }
return s;
}
kfree(s);
return s;
}
kfree(s);
@@
-3437,7
+3451,7
@@
struct location {
long max_time;
long min_pid;
long max_pid;
long max_time;
long min_pid;
long max_pid;
-
cpumask_t cpus
;
+
DECLARE_BITMAP(cpus, NR_CPUS)
;
nodemask_t nodes;
};
nodemask_t nodes;
};
@@
-3512,7
+3526,8
@@
static int add_location(struct loc_track *t, struct kmem_cache *s,
if (track->pid > l->max_pid)
l->max_pid = track->pid;
if (track->pid > l->max_pid)
l->max_pid = track->pid;
- cpu_set(track->cpu, l->cpus);
+ cpumask_set_cpu(track->cpu,
+ to_cpumask(l->cpus));
}
node_set(page_to_nid(virt_to_page(track)), l->nodes);
return 1;
}
node_set(page_to_nid(virt_to_page(track)), l->nodes);
return 1;
@@
-3542,8
+3557,8
@@
static int add_location(struct loc_track *t, struct kmem_cache *s,
l->max_time = age;
l->min_pid = track->pid;
l->max_pid = track->pid;
l->max_time = age;
l->min_pid = track->pid;
l->max_pid = track->pid;
- cpu
s_clear(l->cpus
);
- cpu
_set(track->cpu, l->cpus
);
+ cpu
mask_clear(to_cpumask(l->cpus)
);
+ cpu
mask_set_cpu(track->cpu, to_cpumask(l->cpus)
);
nodes_clear(l->nodes);
node_set(page_to_nid(virt_to_page(track)), l->nodes);
return 1;
nodes_clear(l->nodes);
node_set(page_to_nid(virt_to_page(track)), l->nodes);
return 1;
@@
-3599,7
+3614,7
@@
static int list_locations(struct kmem_cache *s, char *buf,
for (i = 0; i < t.count; i++) {
struct location *l = &t.loc[i];
for (i = 0; i < t.count; i++) {
struct location *l = &t.loc[i];
- if (len > PAGE_SIZE - 100)
+ if (len > PAGE_SIZE -
KSYM_SYMBOL_LEN -
100)
break;
len += sprintf(buf + len, "%7ld ", l->count);
break;
len += sprintf(buf + len, "%7ld ", l->count);
@@
-3624,11
+3639,12
@@
static int list_locations(struct kmem_cache *s, char *buf,
len += sprintf(buf + len, " pid=%ld",
l->min_pid);
len += sprintf(buf + len, " pid=%ld",
l->min_pid);
- if (num_online_cpus() > 1 && !cpus_empty(l->cpus) &&
+ if (num_online_cpus() > 1 &&
+ !cpumask_empty(to_cpumask(l->cpus)) &&
len < PAGE_SIZE - 60) {
len += sprintf(buf + len, " cpus=");
len += cpulist_scnprintf(buf + len, PAGE_SIZE - len - 50,
len < PAGE_SIZE - 60) {
len += sprintf(buf + len, " cpus=");
len += cpulist_scnprintf(buf + len, PAGE_SIZE - len - 50,
-
l->cpus
);
+
to_cpumask(l->cpus)
);
}
if (num_online_nodes() > 1 && !nodes_empty(l->nodes) &&
}
if (num_online_nodes() > 1 && !nodes_empty(l->nodes) &&
@@
-4347,7
+4363,7
@@
static void sysfs_slab_remove(struct kmem_cache *s)
/*
* Need to buffer aliases during bootup until sysfs becomes
/*
* Need to buffer aliases during bootup until sysfs becomes
- * available lest we lo
o
se that information.
+ * available lest we lose that information.
*/
struct saved_alias {
struct kmem_cache *s;
*/
struct saved_alias {
struct kmem_cache *s;