mirror of
https://github.com/versity/scoutfs.git
synced 2026-02-07 03:00:44 +00:00
Shrinker API v4.
Yet another major shrinker API evolution in v6.6-rc4-53-gc42d50aefd17. The struct shrinker now has to be dynamically allocated. This is purposely a backwards incompatible break. We add another KC_ wrapper around the new shrinker_alloc() and move some initialization around to make this as much as possible low impact, but compatible with the old APIs through substitution. Signed-off-by: Auke Kok <auke.kok@versity.com>
This commit is contained in:
@@ -484,3 +484,12 @@ ifneq (,$(shell grep -s 'define __assign_str.dst, src' \
|
||||
include/trace/stages/stage6_event_callback.h))
|
||||
ccflags-y += -DKC_HAVE_ASSIGN_STR_PARMS
|
||||
endif
|
||||
|
||||
#
|
||||
# v6.6-rc4-53-gc42d50aefd17
|
||||
#
|
||||
# el10 yet again modifies the shrinker API significantly, breaking our current
|
||||
# implementation.
|
||||
ifneq (,$(shell grep 'struct shrinker .shrinker_alloc' include/linux/shrinker.h))
|
||||
ccflags-y += -DKC_SHRINKER_ALLOC
|
||||
endif
|
||||
|
||||
@@ -1300,9 +1300,9 @@ int scoutfs_block_setup(struct super_block *sb)
|
||||
atomic_set(&binf->total_inserted, 0);
|
||||
atomic64_set(&binf->access_counter, 0);
|
||||
init_waitqueue_head(&binf->waitq);
|
||||
KC_INIT_SHRINKER_FUNCS(&binf->shrinker, block_count_objects,
|
||||
block_scan_objects);
|
||||
KC_REGISTER_SHRINKER(&binf->shrinker, "scoutfs-block:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_ALLOC_SHRINKER(binf->shrinker, binf, 0, "scoutfs-block:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_INIT_SHRINKER_FUNCS(binf->shrinker, block_count_objects, block_scan_objects);
|
||||
KC_REGISTER_SHRINKER(binf->shrinker);
|
||||
INIT_WORK(&binf->free_work, block_free_work);
|
||||
init_llist_head(&binf->free_llist);
|
||||
|
||||
@@ -1322,7 +1322,7 @@ void scoutfs_block_destroy(struct super_block *sb)
|
||||
struct block_info *binf = SCOUTFS_SB(sb)->block_info;
|
||||
|
||||
if (binf) {
|
||||
KC_UNREGISTER_SHRINKER(&binf->shrinker);
|
||||
KC_UNREGISTER_SHRINKER(binf->shrinker);
|
||||
block_remove_all(sb);
|
||||
flush_work(&binf->free_work);
|
||||
rhashtable_destroy(&binf->ht);
|
||||
|
||||
@@ -2690,10 +2690,9 @@ int scoutfs_item_setup(struct super_block *sb)
|
||||
|
||||
for_each_possible_cpu(cpu)
|
||||
init_pcpu_pages(cinf, cpu);
|
||||
|
||||
KC_INIT_SHRINKER_FUNCS(&cinf->shrinker, item_cache_count_objects,
|
||||
item_cache_scan_objects);
|
||||
KC_REGISTER_SHRINKER(&cinf->shrinker, "scoutfs-item:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_ALLOC_SHRINKER(cinf->shrinker, cinf, 0, "scoutfs-item:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_INIT_SHRINKER_FUNCS(cinf->shrinker, item_cache_count_objects, item_cache_scan_objects);
|
||||
KC_REGISTER_SHRINKER(cinf->shrinker);
|
||||
#ifdef KC_CPU_NOTIFIER
|
||||
cinf->notifier.notifier_call = item_cpu_callback;
|
||||
register_hotcpu_notifier(&cinf->notifier);
|
||||
@@ -2720,7 +2719,7 @@ void scoutfs_item_destroy(struct super_block *sb)
|
||||
#ifdef KC_CPU_NOTIFIER
|
||||
unregister_hotcpu_notifier(&cinf->notifier);
|
||||
#endif
|
||||
KC_UNREGISTER_SHRINKER(&cinf->shrinker);
|
||||
KC_UNREGISTER_SHRINKER(cinf->shrinker);
|
||||
|
||||
for_each_possible_cpu(cpu)
|
||||
drop_pcpu_pages(sb, cinf, cpu);
|
||||
|
||||
@@ -142,25 +142,53 @@ struct timespec64 kc_current_time(struct inode *inode);
|
||||
#define kc_timespec timespec64
|
||||
#endif
|
||||
|
||||
#ifndef KC_SHRINKER_SHRINK
|
||||
#ifdef KC_SHRINKER_ALLOC
|
||||
// el10+
|
||||
|
||||
#define KC_DEFINE_SHRINKER(name) struct shrinker name
|
||||
#define KC_DEFINE_SHRINKER(name) struct shrinker *(name)
|
||||
#define KC_SHRINKER_CONTAINER_OF(ptr, type) ptr->private_data
|
||||
#define KC_ALLOC_SHRINKER(ptr, priv, flags, fmt, args) \
|
||||
do { \
|
||||
ptr = shrinker_alloc(flags, fmt, args); \
|
||||
if (ptr) { \
|
||||
ptr->private_data = (priv); \
|
||||
ptr->seeks = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
#define KC_INIT_SHRINKER_FUNCS(ptr, countfn, scanfn) \
|
||||
do { \
|
||||
(ptr)->count_objects = countfn; \
|
||||
(ptr)->scan_objects = scanfn; \
|
||||
} while (0)
|
||||
#define KC_REGISTER_SHRINKER(ptr) shrinker_register(ptr)
|
||||
#define KC_UNREGISTER_SHRINKER(ptr) shrinker_free(ptr);
|
||||
#define KC_SHRINKER_FN(ptr) (ptr)
|
||||
|
||||
#else /* KC_SHRINKER_ALLOC */
|
||||
#ifndef KC_SHRINKER_SHRINK
|
||||
// el9, el8
|
||||
|
||||
#define KC_DEFINE_SHRINKER(name) struct shrinker (name)
|
||||
#define KC_INIT_SHRINKER_FUNCS(name, countfn, scanfn) do { \
|
||||
__typeof__(name) _shrink = (name); \
|
||||
__typeof__(name) *_shrink = &(name); \
|
||||
_shrink->count_objects = (countfn); \
|
||||
_shrink->scan_objects = (scanfn); \
|
||||
_shrink->seeks = DEFAULT_SEEKS; \
|
||||
_shrink->seeks = DEFAULT_SEEKS; \
|
||||
} while (0)
|
||||
|
||||
#define KC_SHRINKER_CONTAINER_OF(ptr, type) container_of(ptr, type, shrinker)
|
||||
#ifdef KC_SHRINKER_NAME
|
||||
#define KC_REGISTER_SHRINKER register_shrinker
|
||||
#define KC_ALLOC_SHRINKER(ptr, priv, flags, fmt, args) register_shrinker(&ptr, fmt, args)
|
||||
#define KC_REGISTER_SHRINKER(ptr) do {} while(0)
|
||||
#else
|
||||
#define KC_REGISTER_SHRINKER(ptr, fmt, ...) (register_shrinker(ptr))
|
||||
#define KC_ALLOC_SHRINKER(ptr, priv, flags, fmt, args) do {} while(0)
|
||||
#define KC_REGISTER_SHRINKER(ptr) (register_shrinker(&ptr))
|
||||
#endif /* KC_SHRINKER_NAME */
|
||||
#define KC_UNREGISTER_SHRINKER(ptr) (unregister_shrinker(ptr))
|
||||
#define KC_SHRINKER_FN(ptr) (ptr)
|
||||
#else
|
||||
#define KC_UNREGISTER_SHRINKER(ptr) (unregister_shrinker(&(ptr)))
|
||||
#define KC_SHRINKER_FN(ptr) (&ptr)
|
||||
|
||||
#else /* KC_SHRINKER_SHRINK */
|
||||
// el7
|
||||
|
||||
#include <linux/shrinker.h>
|
||||
#ifndef SHRINK_STOP
|
||||
@@ -177,18 +205,20 @@ struct kc_shrinker_wrapper {
|
||||
|
||||
#define KC_DEFINE_SHRINKER(name) struct kc_shrinker_wrapper name;
|
||||
#define KC_INIT_SHRINKER_FUNCS(name, countfn, scanfn) do { \
|
||||
struct kc_shrinker_wrapper *_wrap = (name); \
|
||||
struct kc_shrinker_wrapper *_wrap = &(name); \
|
||||
_wrap->count_objects = (countfn); \
|
||||
_wrap->scan_objects = (scanfn); \
|
||||
_wrap->shrink.shrink = kc_shrink_wrapper_fn; \
|
||||
_wrap->shrink.seeks = DEFAULT_SEEKS; \
|
||||
} while (0)
|
||||
#define KC_SHRINKER_CONTAINER_OF(ptr, type) container_of(container_of(ptr, struct kc_shrinker_wrapper, shrink), type, shrinker)
|
||||
#define KC_REGISTER_SHRINKER(ptr, fmt, ...) (register_shrinker(ptr.shrink))
|
||||
#define KC_UNREGISTER_SHRINKER(ptr) (unregister_shrinker(ptr.shrink))
|
||||
#define KC_SHRINKER_FN(ptr) (ptr.shrink)
|
||||
#define KC_ALLOC_SHRINKER(ptr, priv, flags, fmt, args) do {} while(0)
|
||||
#define KC_REGISTER_SHRINKER(ptr) (register_shrinker(&(ptr).shrink))
|
||||
#define KC_UNREGISTER_SHRINKER(ptr) (unregister_shrinker(&(ptr).shrink))
|
||||
#define KC_SHRINKER_FN(ptr) (&(ptr).shrink)
|
||||
|
||||
#endif /* KC_SHRINKER_SHRINK */
|
||||
#endif /* KC_SHRINKER_ALLOC */
|
||||
|
||||
#ifdef KC_KERNEL_GETSOCKNAME_ADDRLEN
|
||||
#include <linux/net.h>
|
||||
|
||||
@@ -1505,7 +1505,7 @@ void scoutfs_free_unused_locks(struct super_block *sb)
|
||||
.nr_to_scan = INT_MAX,
|
||||
};
|
||||
|
||||
lock_scan_objects(KC_SHRINKER_FN(&linfo->shrinker), &sc);
|
||||
lock_scan_objects(KC_SHRINKER_FN(linfo->shrinker), &sc);
|
||||
}
|
||||
|
||||
static void lock_tseq_show(struct seq_file *m, struct scoutfs_tseq_entry *ent)
|
||||
@@ -1612,7 +1612,7 @@ void scoutfs_lock_shutdown(struct super_block *sb)
|
||||
trace_scoutfs_lock_shutdown(sb, linfo);
|
||||
|
||||
/* stop the shrinker from queueing work */
|
||||
KC_UNREGISTER_SHRINKER(&linfo->shrinker);
|
||||
KC_UNREGISTER_SHRINKER(linfo->shrinker);
|
||||
flush_work(&linfo->shrink_work);
|
||||
|
||||
/* cause current and future lock calls to return errors */
|
||||
@@ -1731,9 +1731,9 @@ int scoutfs_lock_setup(struct super_block *sb)
|
||||
spin_lock_init(&linfo->lock);
|
||||
linfo->lock_tree = RB_ROOT;
|
||||
linfo->lock_range_tree = RB_ROOT;
|
||||
KC_INIT_SHRINKER_FUNCS(&linfo->shrinker, lock_count_objects,
|
||||
lock_scan_objects);
|
||||
KC_REGISTER_SHRINKER(&linfo->shrinker, "scoutfs-lock:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_ALLOC_SHRINKER(linfo->shrinker, linfo, 0, "scoutfs-lock:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_INIT_SHRINKER_FUNCS(linfo->shrinker, lock_count_objects, lock_scan_objects);
|
||||
KC_REGISTER_SHRINKER(linfo->shrinker);
|
||||
INIT_LIST_HEAD(&linfo->lru_list);
|
||||
INIT_WORK(&linfo->inv_work, lock_invalidate_worker);
|
||||
INIT_LIST_HEAD(&linfo->inv_list);
|
||||
|
||||
@@ -269,7 +269,7 @@ static void shrink_all_cached_checks(struct squota_info *qtinf)
|
||||
{
|
||||
struct shrink_control sc = { .nr_to_scan = LONG_MAX, };
|
||||
|
||||
scan_cached_checks(KC_SHRINKER_FN(&qtinf->shrinker), &sc);
|
||||
scan_cached_checks(KC_SHRINKER_FN(qtinf->shrinker), &sc);
|
||||
}
|
||||
|
||||
static u8 ns_is_attr(u8 ns)
|
||||
@@ -1225,8 +1225,9 @@ int scoutfs_quota_setup(struct super_block *sb)
|
||||
spin_lock_init(&qtinf->lock);
|
||||
init_waitqueue_head(&qtinf->waitq);
|
||||
|
||||
KC_INIT_SHRINKER_FUNCS(&qtinf->shrinker, count_cached_checks, scan_cached_checks);
|
||||
KC_REGISTER_SHRINKER(&qtinf->shrinker, "scoutfs-quota:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_ALLOC_SHRINKER(qtinf->shrinker, qtinf, 0, "scoutfs-quota:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_INIT_SHRINKER_FUNCS(qtinf->shrinker, count_cached_checks, scan_cached_checks);
|
||||
KC_REGISTER_SHRINKER(qtinf->shrinker);
|
||||
|
||||
sbi->squota_info = qtinf;
|
||||
|
||||
@@ -1250,7 +1251,7 @@ void scoutfs_quota_destroy(struct super_block *sb)
|
||||
|
||||
if (qtinf) {
|
||||
debugfs_remove(qtinf->drop_dentry);
|
||||
KC_UNREGISTER_SHRINKER(&qtinf->shrinker);
|
||||
KC_UNREGISTER_SHRINKER(qtinf->shrinker);
|
||||
|
||||
spin_lock(&qtinf->lock);
|
||||
rs = rcu_dereference_protected(qtinf->ruleset, lockdep_is_held(&qtinf->lock));
|
||||
|
||||
@@ -1112,8 +1112,9 @@ int scoutfs_wkic_setup(struct super_block *sb)
|
||||
}
|
||||
|
||||
winf->sb = sb;
|
||||
KC_INIT_SHRINKER_FUNCS(&winf->shrinker, wkic_shrink_count, wkic_shrink_scan);
|
||||
KC_REGISTER_SHRINKER(&winf->shrinker, "scoutfs-weak_item:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_ALLOC_SHRINKER(winf->shrinker, winf, 0, "scoutfs-weak_item:" SCSBF, SCSB_ARGS(sb));
|
||||
KC_INIT_SHRINKER_FUNCS(winf->shrinker, wkic_shrink_count, wkic_shrink_scan);
|
||||
KC_REGISTER_SHRINKER(winf->shrinker);
|
||||
|
||||
sbi->wkic_info = winf;
|
||||
return 0;
|
||||
@@ -1141,7 +1142,7 @@ void scoutfs_wkic_destroy(struct super_block *sb)
|
||||
|
||||
if (winf) {
|
||||
debugfs_remove(winf->drop_dentry);
|
||||
KC_UNREGISTER_SHRINKER(&winf->shrinker);
|
||||
KC_UNREGISTER_SHRINKER(winf->shrinker);
|
||||
|
||||
/* trees are in sync so tearing down one frees all pages */
|
||||
rbtree_postorder_for_each_entry_safe(wpage, tmp, &winf->wpage_roots[0], nodes[0]) {
|
||||
|
||||
Reference in New Issue
Block a user