aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/erofs/utils.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-06 16:29:27 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-06 16:29:27 -0800
commite266ca36da7de45b64b05698e98e04b578a88888 (patch)
treefc9ab60b687a41aedb69c713e239354444259167 /drivers/staging/erofs/utils.c
parentiio: adc: fix warning in Qualcomm PM8xxx HK/XOADC driver (diff)
parentstaging: mt7621-dma: remove license boilerplate text (diff)
downloadlinux-dev-e266ca36da7de45b64b05698e98e04b578a88888.tar.xz
linux-dev-e266ca36da7de45b64b05698e98e04b578a88888.zip
Merge tag 'staging-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging/IIO updates from Greg KH: "Here is the big staging/iio driver pull request for 5.1-rc1. Lots of good IIO driver updates and cleanups in here as always. Combined with the removal of the xgifb driver, we have a net "loss" of over 9000 lines in the pull request, always a nice thing. As the outreachy application process is currently happening, there are loads of tiny checkpatch cleanup fixes all over the staging tree, which accounts for the majority of the fixups" * tag 'staging-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (341 commits) staging: mt7621-dma: remove license boilerplate text staging: mt7621-dma: add SPDX GPL-2.0+ license identifier Staging: ks7010: Replace typecast to int Staging: vt6655: Align a static function declaration staging: speakup: fix line over 80 characters. staging: mt7621-eth: Remove license boilerplate text staging: mt7621-eth: Add SPDX license identifier staging: ks7010: removed custom Michael MIC implementation. staging: rtl8192e: Fix space and suspect issue Staging: vt6655: Modify comment style of SPDX License Identifier Staging: vt6655: Modify comment style for SPDX-License-Identifier Staging: vt6655: Align a function declaration Staging: vt6655: Alignment of function declaration staging: rtl8712: Fix indentation issue staging: wilc1000: fix incorrent type in initializer staging: rtl8188eu: remove unused P2P_PRIVATE_IOCTL_SET_LEN staging: rtl8188eu: remove unused enum P2P_PROTO_WK_ID staging: rtl8723bs: Remove duplicated include from drv_types.h Staging: vt6655: Alignment should match open parenthesis staging: erofs: fix mis-acted TAIL merging behavior ...
Diffstat (limited to 'drivers/staging/erofs/utils.c')
-rw-r--r--drivers/staging/erofs/utils.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/staging/erofs/utils.c b/drivers/staging/erofs/utils.c
index b535898ca753..5f61f99f4c10 100644
--- a/drivers/staging/erofs/utils.c
+++ b/drivers/staging/erofs/utils.c
@@ -31,13 +31,32 @@ struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp)
static atomic_long_t erofs_global_shrink_cnt;
#ifdef CONFIG_EROFS_FS_ZIP
+#define __erofs_workgroup_get(grp) atomic_inc(&(grp)->refcount)
+#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount)
-struct erofs_workgroup *erofs_find_workgroup(
- struct super_block *sb, pgoff_t index, bool *tag)
+static int erofs_workgroup_get(struct erofs_workgroup *grp)
+{
+ int o;
+
+repeat:
+ o = erofs_wait_on_workgroup_freezed(grp);
+ if (unlikely(o <= 0))
+ return -1;
+
+ if (unlikely(atomic_cmpxchg(&grp->refcount, o, o + 1) != o))
+ goto repeat;
+
+ /* decrease refcount paired by erofs_workgroup_put */
+ if (unlikely(o == 1))
+ atomic_long_dec(&erofs_global_shrink_cnt);
+ return 0;
+}
+
+struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb,
+ pgoff_t index, bool *tag)
{
struct erofs_sb_info *sbi = EROFS_SB(sb);
struct erofs_workgroup *grp;
- int oldcount;
repeat:
rcu_read_lock();
@@ -46,15 +65,12 @@ repeat:
*tag = xa_pointer_tag(grp);
grp = xa_untag_pointer(grp);
- if (erofs_workgroup_get(grp, &oldcount)) {
+ if (erofs_workgroup_get(grp)) {
/* prefer to relax rcu read side */
rcu_read_unlock();
goto repeat;
}
- /* decrease refcount added by erofs_workgroup_put */
- if (unlikely(oldcount == 1))
- atomic_long_dec(&erofs_global_shrink_cnt);
DBG_BUGON(index != grp->index);
}
rcu_read_unlock();
@@ -104,8 +120,6 @@ int erofs_register_workgroup(struct super_block *sb,
return err;
}
-extern void erofs_workgroup_free_rcu(struct erofs_workgroup *grp);
-
static void __erofs_workgroup_free(struct erofs_workgroup *grp)
{
atomic_long_dec(&erofs_global_shrink_cnt);
@@ -131,9 +145,9 @@ static void erofs_workgroup_unfreeze_final(struct erofs_workgroup *grp)
__erofs_workgroup_free(grp);
}
-bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
- struct erofs_workgroup *grp,
- bool cleanup)
+static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
+ struct erofs_workgroup *grp,
+ bool cleanup)
{
/*
* for managed cache enabled, the refcount of workgroups
@@ -172,9 +186,9 @@ bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
#else
/* for nocache case, no customized reclaim path at all */
-bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
- struct erofs_workgroup *grp,
- bool cleanup)
+static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
+ struct erofs_workgroup *grp,
+ bool cleanup)
{
int cnt = atomic_read(&grp->refcount);
@@ -256,14 +270,14 @@ void erofs_unregister_super(struct super_block *sb)
spin_unlock(&erofs_sb_list_lock);
}
-unsigned long erofs_shrink_count(struct shrinker *shrink,
- struct shrink_control *sc)
+static unsigned long erofs_shrink_count(struct shrinker *shrink,
+ struct shrink_control *sc)
{
return atomic_long_read(&erofs_global_shrink_cnt);
}
-unsigned long erofs_shrink_scan(struct shrinker *shrink,
- struct shrink_control *sc)
+static unsigned long erofs_shrink_scan(struct shrinker *shrink,
+ struct shrink_control *sc)
{
struct erofs_sb_info *sbi;
struct list_head *p;
@@ -319,3 +333,9 @@ unsigned long erofs_shrink_scan(struct shrinker *shrink,
return freed;
}
+struct shrinker erofs_shrinker_info = {
+ .scan_objects = erofs_shrink_scan,
+ .count_objects = erofs_shrink_count,
+ .seeks = DEFAULT_SEEKS,
+};
+