aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-10 07:26:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-10 07:26:02 -0400
commitc798360cd1438090d51eeaa8e67985da11362eba (patch)
tree0107d3b9ee7476264c3357287787d393545bd2d9 /fs
parentb211e9d7c861bdb37b86d6384da9edfb80949ceb (diff)
parent6ae833c7fe0c6ef1f0ab13cc775da230d6f4c256 (diff)
Merge branch 'for-3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
Pull percpu updates from Tejun Heo: "A lot of activities on percpu front. Notable changes are... - percpu allocator now can take @gfp. If @gfp doesn't contain GFP_KERNEL, it tries to allocate from what's already available to the allocator and a work item tries to keep the reserve around certain level so that these atomic allocations usually succeed. This will replace the ad-hoc percpu memory pool used by blk-throttle and also be used by the planned blkcg support for writeback IOs. Please note that I noticed a bug in how @gfp is interpreted while preparing this pull request and applied the fix 6ae833c7fe0c ("percpu: fix how @gfp is interpreted by the percpu allocator") just now. - percpu_ref now uses longs for percpu and global counters instead of ints. It leads to more sparse packing of the percpu counters on 64bit machines but the overhead should be negligible and this allows using percpu_ref for refcnting pages and in-memory objects directly. - The switching between percpu and single counter modes of a percpu_ref is made independent of putting the base ref and a percpu_ref can now optionally be initialized in single or killed mode. This allows avoiding percpu shutdown latency for cases where the refcounted objects may be synchronously created and destroyed in rapid succession with only a fraction of them reaching fully operational status (SCSI probing does this when combined with blk-mq support). It's also planned to be used to implement forced single mode to detect underflow more timely for debugging. There's a separate branch percpu/for-3.18-consistent-ops which cleans up the duplicate percpu accessors. That branch causes a number of conflicts with s390 and other trees. I'll send a separate pull request w/ resolutions once other branches are merged" * 'for-3.18' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu: (33 commits) percpu: fix how @gfp is interpreted by the percpu allocator blk-mq, percpu_ref: start q->mq_usage_counter in atomic mode percpu_ref: make INIT_ATOMIC and switch_to_atomic() sticky percpu_ref: add PERCPU_REF_INIT_* flags percpu_ref: decouple switching to percpu mode and reinit percpu_ref: decouple switching to atomic mode and killing percpu_ref: add PCPU_REF_DEAD percpu_ref: rename things to prepare for decoupling percpu/atomic mode switch percpu_ref: replace pcpu_ prefix with percpu_ percpu_ref: minor code and comment updates percpu_ref: relocate percpu_ref_reinit() Revert "blk-mq, percpu_ref: implement a kludge for SCSI blk-mq stall during probe" Revert "percpu: free percpu allocation info for uniprocessor system" percpu-refcount: make percpu_ref based on longs instead of ints percpu-refcount: improve WARN messages percpu: fix locking regression in the failure path of pcpu_alloc() percpu-refcount: add @gfp to percpu_ref_init() proportions: add @gfp to init functions percpu_counter: add @gfp to percpu_counter_init() percpu_counter: make percpu_counters_lock irq-safe ...
Diffstat (limited to 'fs')
-rw-r--r--fs/aio.c4
-rw-r--r--fs/btrfs/disk-io.c8
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/ext2/super.c6
-rw-r--r--fs/ext3/super.c6
-rw-r--r--fs/ext4/super.c14
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/quota/dquot.c2
-rw-r--r--fs/super.c3
9 files changed, 26 insertions, 21 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 733750096b71..84a751005f5b 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -661,10 +661,10 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
661 661
662 INIT_LIST_HEAD(&ctx->active_reqs); 662 INIT_LIST_HEAD(&ctx->active_reqs);
663 663
664 if (percpu_ref_init(&ctx->users, free_ioctx_users)) 664 if (percpu_ref_init(&ctx->users, free_ioctx_users, 0, GFP_KERNEL))
665 goto err; 665 goto err;
666 666
667 if (percpu_ref_init(&ctx->reqs, free_ioctx_reqs)) 667 if (percpu_ref_init(&ctx->reqs, free_ioctx_reqs, 0, GFP_KERNEL))
668 goto err; 668 goto err;
669 669
670 ctx->cpu = alloc_percpu(struct kioctx_cpu); 670 ctx->cpu = alloc_percpu(struct kioctx_cpu);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a1d36e62179c..d0d78dc07792 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1183,7 +1183,7 @@ static struct btrfs_subvolume_writers *btrfs_alloc_subvolume_writers(void)
1183 if (!writers) 1183 if (!writers)
1184 return ERR_PTR(-ENOMEM); 1184 return ERR_PTR(-ENOMEM);
1185 1185
1186 ret = percpu_counter_init(&writers->counter, 0); 1186 ret = percpu_counter_init(&writers->counter, 0, GFP_KERNEL);
1187 if (ret < 0) { 1187 if (ret < 0) {
1188 kfree(writers); 1188 kfree(writers);
1189 return ERR_PTR(ret); 1189 return ERR_PTR(ret);
@@ -2188,7 +2188,7 @@ int open_ctree(struct super_block *sb,
2188 goto fail_srcu; 2188 goto fail_srcu;
2189 } 2189 }
2190 2190
2191 ret = percpu_counter_init(&fs_info->dirty_metadata_bytes, 0); 2191 ret = percpu_counter_init(&fs_info->dirty_metadata_bytes, 0, GFP_KERNEL);
2192 if (ret) { 2192 if (ret) {
2193 err = ret; 2193 err = ret;
2194 goto fail_bdi; 2194 goto fail_bdi;
@@ -2196,13 +2196,13 @@ int open_ctree(struct super_block *sb,
2196 fs_info->dirty_metadata_batch = PAGE_CACHE_SIZE * 2196 fs_info->dirty_metadata_batch = PAGE_CACHE_SIZE *
2197 (1 + ilog2(nr_cpu_ids)); 2197 (1 + ilog2(nr_cpu_ids));
2198 2198
2199 ret = percpu_counter_init(&fs_info->delalloc_bytes, 0); 2199 ret = percpu_counter_init(&fs_info->delalloc_bytes, 0, GFP_KERNEL);
2200 if (ret) { 2200 if (ret) {
2201 err = ret; 2201 err = ret;
2202 goto fail_dirty_metadata_bytes; 2202 goto fail_dirty_metadata_bytes;
2203 } 2203 }
2204 2204
2205 ret = percpu_counter_init(&fs_info->bio_counter, 0); 2205 ret = percpu_counter_init(&fs_info->bio_counter, 0, GFP_KERNEL);
2206 if (ret) { 2206 if (ret) {
2207 err = ret; 2207 err = ret;
2208 goto fail_delalloc_bytes; 2208 goto fail_delalloc_bytes;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3efe1c3877bf..caaf015d6e4b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3494,7 +3494,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
3494 if (!found) 3494 if (!found)
3495 return -ENOMEM; 3495 return -ENOMEM;
3496 3496
3497 ret = percpu_counter_init(&found->total_bytes_pinned, 0); 3497 ret = percpu_counter_init(&found->total_bytes_pinned, 0, GFP_KERNEL);
3498 if (ret) { 3498 if (ret) {
3499 kfree(found); 3499 kfree(found);
3500 return ret; 3500 return ret;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index b88edc05c230..170dc41e8bf4 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1067,14 +1067,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
1067 ext2_rsv_window_add(sb, &sbi->s_rsv_window_head); 1067 ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
1068 1068
1069 err = percpu_counter_init(&sbi->s_freeblocks_counter, 1069 err = percpu_counter_init(&sbi->s_freeblocks_counter,
1070 ext2_count_free_blocks(sb)); 1070 ext2_count_free_blocks(sb), GFP_KERNEL);
1071 if (!err) { 1071 if (!err) {
1072 err = percpu_counter_init(&sbi->s_freeinodes_counter, 1072 err = percpu_counter_init(&sbi->s_freeinodes_counter,
1073 ext2_count_free_inodes(sb)); 1073 ext2_count_free_inodes(sb), GFP_KERNEL);
1074 } 1074 }
1075 if (!err) { 1075 if (!err) {
1076 err = percpu_counter_init(&sbi->s_dirs_counter, 1076 err = percpu_counter_init(&sbi->s_dirs_counter,
1077 ext2_count_dirs(sb)); 1077 ext2_count_dirs(sb), GFP_KERNEL);
1078 } 1078 }
1079 if (err) { 1079 if (err) {
1080 ext2_msg(sb, KERN_ERR, "error: insufficient memory"); 1080 ext2_msg(sb, KERN_ERR, "error: insufficient memory");
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 622e88249024..bb0fdacad058 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2039,14 +2039,14 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
2039 goto failed_mount2; 2039 goto failed_mount2;
2040 } 2040 }
2041 err = percpu_counter_init(&sbi->s_freeblocks_counter, 2041 err = percpu_counter_init(&sbi->s_freeblocks_counter,
2042 ext3_count_free_blocks(sb)); 2042 ext3_count_free_blocks(sb), GFP_KERNEL);
2043 if (!err) { 2043 if (!err) {
2044 err = percpu_counter_init(&sbi->s_freeinodes_counter, 2044 err = percpu_counter_init(&sbi->s_freeinodes_counter,
2045 ext3_count_free_inodes(sb)); 2045 ext3_count_free_inodes(sb), GFP_KERNEL);
2046 } 2046 }
2047 if (!err) { 2047 if (!err) {
2048 err = percpu_counter_init(&sbi->s_dirs_counter, 2048 err = percpu_counter_init(&sbi->s_dirs_counter,
2049 ext3_count_dirs(sb)); 2049 ext3_count_dirs(sb), GFP_KERNEL);
2050 } 2050 }
2051 if (err) { 2051 if (err) {
2052 ext3_msg(sb, KERN_ERR, "error: insufficient memory"); 2052 ext3_msg(sb, KERN_ERR, "error: insufficient memory");
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0b28b36e7915..05c159218bc2 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3892,7 +3892,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3892 /* Register extent status tree shrinker */ 3892 /* Register extent status tree shrinker */
3893 ext4_es_register_shrinker(sbi); 3893 ext4_es_register_shrinker(sbi);
3894 3894
3895 if ((err = percpu_counter_init(&sbi->s_extent_cache_cnt, 0)) != 0) { 3895 err = percpu_counter_init(&sbi->s_extent_cache_cnt, 0, GFP_KERNEL);
3896 if (err) {
3896 ext4_msg(sb, KERN_ERR, "insufficient memory"); 3897 ext4_msg(sb, KERN_ERR, "insufficient memory");
3897 goto failed_mount3; 3898 goto failed_mount3;
3898 } 3899 }
@@ -4106,17 +4107,20 @@ no_journal:
4106 block = ext4_count_free_clusters(sb); 4107 block = ext4_count_free_clusters(sb);
4107 ext4_free_blocks_count_set(sbi->s_es, 4108 ext4_free_blocks_count_set(sbi->s_es,
4108 EXT4_C2B(sbi, block)); 4109 EXT4_C2B(sbi, block));
4109 err = percpu_counter_init(&sbi->s_freeclusters_counter, block); 4110 err = percpu_counter_init(&sbi->s_freeclusters_counter, block,
4111 GFP_KERNEL);
4110 if (!err) { 4112 if (!err) {
4111 unsigned long freei = ext4_count_free_inodes(sb); 4113 unsigned long freei = ext4_count_free_inodes(sb);
4112 sbi->s_es->s_free_inodes_count = cpu_to_le32(freei); 4114 sbi->s_es->s_free_inodes_count = cpu_to_le32(freei);
4113 err = percpu_counter_init(&sbi->s_freeinodes_counter, freei); 4115 err = percpu_counter_init(&sbi->s_freeinodes_counter, freei,
4116 GFP_KERNEL);
4114 } 4117 }
4115 if (!err) 4118 if (!err)
4116 err = percpu_counter_init(&sbi->s_dirs_counter, 4119 err = percpu_counter_init(&sbi->s_dirs_counter,
4117 ext4_count_dirs(sb)); 4120 ext4_count_dirs(sb), GFP_KERNEL);
4118 if (!err) 4121 if (!err)
4119 err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0); 4122 err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0,
4123 GFP_KERNEL);
4120 if (err) { 4124 if (err) {
4121 ext4_msg(sb, KERN_ERR, "insufficient memory"); 4125 ext4_msg(sb, KERN_ERR, "insufficient memory");
4122 goto failed_mount6; 4126 goto failed_mount6;
diff --git a/fs/file_table.c b/fs/file_table.c
index 385bfd31512a..0bab12b20460 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -331,5 +331,5 @@ void __init files_init(unsigned long mempages)
331 331
332 n = (mempages * (PAGE_SIZE / 1024)) / 10; 332 n = (mempages * (PAGE_SIZE / 1024)) / 10;
333 files_stat.max_files = max_t(unsigned long, n, NR_FILE); 333 files_stat.max_files = max_t(unsigned long, n, NR_FILE);
334 percpu_counter_init(&nr_files, 0); 334 percpu_counter_init(&nr_files, 0, GFP_KERNEL);
335} 335}
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index f2d0eee9d1f1..8b663b2d9562 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2725,7 +2725,7 @@ static int __init dquot_init(void)
2725 panic("Cannot create dquot hash table"); 2725 panic("Cannot create dquot hash table");
2726 2726
2727 for (i = 0; i < _DQST_DQSTAT_LAST; i++) { 2727 for (i = 0; i < _DQST_DQSTAT_LAST; i++) {
2728 ret = percpu_counter_init(&dqstats.counter[i], 0); 2728 ret = percpu_counter_init(&dqstats.counter[i], 0, GFP_KERNEL);
2729 if (ret) 2729 if (ret)
2730 panic("Cannot create dquot stat counters"); 2730 panic("Cannot create dquot stat counters");
2731 } 2731 }
diff --git a/fs/super.c b/fs/super.c
index b9a214d2fe98..1b836107acee 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -175,7 +175,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
175 goto fail; 175 goto fail;
176 176
177 for (i = 0; i < SB_FREEZE_LEVELS; i++) { 177 for (i = 0; i < SB_FREEZE_LEVELS; i++) {
178 if (percpu_counter_init(&s->s_writers.counter[i], 0) < 0) 178 if (percpu_counter_init(&s->s_writers.counter[i], 0,
179 GFP_KERNEL) < 0)
179 goto fail; 180 goto fail;
180 lockdep_init_map(&s->s_writers.lock_map[i], sb_writers_name[i], 181 lockdep_init_map(&s->s_writers.lock_map[i], sb_writers_name[i],
181 &type->s_writers_key[i], 0); 182 &type->s_writers_key[i], 0);