Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 833f4077 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Linus Torvalds
Browse files

lib: percpu_counter_init error handling



alloc_percpu can fail, propagate that error.

Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent bf1d89c8
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -653,6 +653,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
	int db_count;
	int i, j;
	__le32 features;
	int err;

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi)
@@ -906,12 +907,20 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
	spin_lock_init(&sbi->s_next_gen_lock);

	percpu_counter_init(&sbi->s_freeblocks_counter,
	err = percpu_counter_init(&sbi->s_freeblocks_counter,
				ext2_count_free_blocks(sb));
	percpu_counter_init(&sbi->s_freeinodes_counter,
	if (!err) {
		err = percpu_counter_init(&sbi->s_freeinodes_counter,
				ext2_count_free_inodes(sb));
	percpu_counter_init(&sbi->s_dirs_counter,
	}
	if (!err) {
		err = percpu_counter_init(&sbi->s_dirs_counter,
				ext2_count_dirs(sb));
	}
	if (err) {
		printk(KERN_ERR "EXT2-fs: insufficient memory\n");
		goto failed_mount3;
	}
	/*
	 * set up enough so that it can read an inode
	 */
+15 −6
Original line number Diff line number Diff line
@@ -1416,6 +1416,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
	int i;
	int needs_recovery;
	__le32 features;
	int err;

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi)
@@ -1675,12 +1676,20 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
	spin_lock_init(&sbi->s_next_gen_lock);

	percpu_counter_init(&sbi->s_freeblocks_counter,
	err = percpu_counter_init(&sbi->s_freeblocks_counter,
			ext3_count_free_blocks(sb));
	percpu_counter_init(&sbi->s_freeinodes_counter,
	if (!err) {
		err = percpu_counter_init(&sbi->s_freeinodes_counter,
				ext3_count_free_inodes(sb));
	percpu_counter_init(&sbi->s_dirs_counter,
	}
	if (!err) {
		err = percpu_counter_init(&sbi->s_dirs_counter,
				ext3_count_dirs(sb));
	}
	if (err) {
		printk(KERN_ERR "EXT3-fs: insufficient memory\n");
		goto failed_mount3;
	}

	/* per fileystem reservation list head & lock */
	spin_lock_init(&sbi->s_rsv_window_lock);
+15 −6
Original line number Diff line number Diff line
@@ -1479,6 +1479,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
	int needs_recovery;
	__le32 features;
	__u64 blocks_count;
	int err;

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi)
@@ -1759,12 +1760,20 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
	spin_lock_init(&sbi->s_next_gen_lock);

	percpu_counter_init(&sbi->s_freeblocks_counter,
	err = percpu_counter_init(&sbi->s_freeblocks_counter,
			ext4_count_free_blocks(sb));
	percpu_counter_init(&sbi->s_freeinodes_counter,
	if (!err) {
		err = percpu_counter_init(&sbi->s_freeinodes_counter,
				ext4_count_free_inodes(sb));
	percpu_counter_init(&sbi->s_dirs_counter,
	}
	if (!err) {
		err = percpu_counter_init(&sbi->s_dirs_counter,
				ext4_count_dirs(sb));
	}
	if (err) {
		printk(KERN_ERR "EXT4-fs: insufficient memory\n");
		goto failed_mount3;
	}

	/* per fileystem reservation list head & lock */
	spin_lock_init(&sbi->s_rsv_window_lock);
+3 −2
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ struct percpu_counter {
#define FBC_BATCH	(NR_CPUS*4)
#endif

void percpu_counter_init(struct percpu_counter *fbc, s64 amount);
int percpu_counter_init(struct percpu_counter *fbc, s64 amount);
void percpu_counter_destroy(struct percpu_counter *fbc);
void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
@@ -78,9 +78,10 @@ struct percpu_counter {
	s64 count;
};

static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
{
	fbc->count = amount;
	return 0;
}

static inline void percpu_counter_destroy(struct percpu_counter *fbc)
+7 −1
Original line number Diff line number Diff line
@@ -68,21 +68,27 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc)
}
EXPORT_SYMBOL(__percpu_counter_sum);

void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
{
	spin_lock_init(&fbc->lock);
	fbc->count = amount;
	fbc->counters = alloc_percpu(s32);
	if (!fbc->counters)
		return -ENOMEM;
#ifdef CONFIG_HOTPLUG_CPU
	mutex_lock(&percpu_counters_lock);
	list_add(&fbc->list, &percpu_counters);
	mutex_unlock(&percpu_counters_lock);
#endif
	return 0;
}
EXPORT_SYMBOL(percpu_counter_init);

void percpu_counter_destroy(struct percpu_counter *fbc)
{
	if (!fbc->counters)
		return;

	free_percpu(fbc->counters);
#ifdef CONFIG_HOTPLUG_CPU
	mutex_lock(&percpu_counters_lock);