From 13a93a4f7c17de5c5b9ab354aaf34b230583110e Mon Sep 17 00:00:00 2001 From: ssfdust Date: Sat, 6 Jan 2024 10:20:56 +0800 Subject: [PATCH] Fix for kernel 6.7+ * Use shrinker pointer instead of shrink struct for 6.7+, due to the `shrinker_alloc` function always return the pointer. * Most of the codes are stolen from drivers/android/binder_alloc.c --- ashmem/ashmem.c | 25 ++++++++++++++++++++++++- binder/binder_alloc.c | 19 ++++++++++++++++++- binder/binderfs.c | 16 ++++++++++++---- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/ashmem/ashmem.c b/ashmem/ashmem.c index b3c0762..df9cf90 100644 --- a/ashmem/ashmem.c +++ b/ashmem/ashmem.c @@ -494,6 +494,9 @@ ashmem_shrink_count(struct shrinker *shrink, struct shrink_control *sc) return lru_count; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) +static struct shrinker *ashmem_shrinker; +#else static struct shrinker ashmem_shrinker = { .count_objects = ashmem_shrink_count, .scan_objects = ashmem_shrink_scan, @@ -503,6 +506,7 @@ static struct shrinker ashmem_shrinker = { */ .seeks = DEFAULT_SEEKS * 4, }; +#endif static int set_prot_mask(struct ashmem_area *asma, unsigned long prot) { @@ -807,8 +811,13 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) .gfp_mask = GFP_KERNEL, .nr_to_scan = LONG_MAX, }; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + ret = ashmem_shrink_count(ashmem_shrinker, &sc); + ashmem_shrink_scan(ashmem_shrinker, &sc); +#else ret = ashmem_shrink_count(&ashmem_shrinker, &sc); ashmem_shrink_scan(&ashmem_shrinker, &sc); +#endif } break; } @@ -878,7 +887,17 @@ static int __init ashmem_init(void) return ret; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + ashmem_shrinker = shrinker_alloc(0, "android-ashmem"); + if (ashmem_shrinker) { + ashmem_shrinker->count_objects = ashmem_shrink_count; + ashmem_shrinker->scan_objects = ashmem_shrink_scan; + ashmem_shrinker->seeks = DEFAULT_SEEKS * 4; + shrinker_register(ashmem_shrinker); + } else { + return -ENOMEM; + } +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0)) register_shrinker(&ashmem_shrinker, "android-ashmem"); #else register_shrinker(&ashmem_shrinker); @@ -889,7 +908,11 @@ static int __init ashmem_init(void) static void __exit ashmem_exit(void) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + shrinker_free(ashmem_shrinker); +#else unregister_shrinker(&ashmem_shrinker); +#endif misc_deregister(&ashmem_misc); diff --git a/binder/binder_alloc.c b/binder/binder_alloc.c index 13b8b32..aed9c7a 100644 --- a/binder/binder_alloc.c +++ b/binder/binder_alloc.c @@ -1059,11 +1059,15 @@ binder_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) return ret; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) +static struct shrinker *binder_shrinker; +#else static struct shrinker binder_shrinker = { .count_objects = binder_shrink_count, .scan_objects = binder_shrink_scan, .seeks = DEFAULT_SEEKS, }; +#endif /** * binder_alloc_init() - called by binder_open() for per-proc initialization @@ -1084,7 +1088,16 @@ int binder_alloc_shrinker_init(void) int ret = list_lru_init(&binder_alloc_lru); if (ret == 0) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + binder_shrinker = shrinker_alloc(0, "android-binder"); + if (binder_shrinker) { + binder_shrinker->count_objects = binder_shrink_count; + binder_shrinker->scan_objects = binder_shrink_scan; + shrinker_register(binder_shrinker); + } else { + ret = -ENOMEM; + } +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6,0,0)) ret = register_shrinker(&binder_shrinker, "android-binder"); #else ret = register_shrinker(&binder_shrinker); @@ -1097,7 +1110,11 @@ int binder_alloc_shrinker_init(void) void binder_alloc_shrinker_exit(void) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + shrinker_free(binder_shrinker); +#else unregister_shrinker(&binder_shrinker); +#endif list_lru_destroy(&binder_alloc_lru); } diff --git a/binder/binderfs.c b/binder/binderfs.c index 8776fdf..8b8f45b 100644 --- a/binder/binderfs.c +++ b/binder/binderfs.c @@ -146,7 +146,9 @@ static int binderfs_binder_device_create(struct inode *ref_inode, goto err; inode->i_ino = minor + INODE_OFFSET; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + simple_inode_init_ts(inode); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode); #else inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); @@ -457,7 +459,9 @@ static int binderfs_binder_ctl_create(struct super_block *sb) } inode->i_ino = SECOND_INODE; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + simple_inode_init_ts(inode); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode); #else inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); @@ -503,7 +507,9 @@ static struct inode *binderfs_make_inode(struct super_block *sb, int mode) if (ret) { ret->i_ino = iunique(sb, BINDERFS_MAX_MINOR + INODE_OFFSET); ret->i_mode = mode; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + simple_inode_init_ts(ret); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) ret->i_atime = ret->i_mtime = inode_set_ctime_current(ret); #else ret->i_atime = ret->i_mtime = ret->i_ctime = current_time(ret); @@ -730,7 +736,9 @@ static int binderfs_fill_super(struct super_block *sb, struct fs_context *fc) inode->i_ino = FIRST_INODE; inode->i_fop = &simple_dir_operations; inode->i_mode = S_IFDIR | 0755; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,7,0)) + simple_inode_init_ts(inode); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6,6,0)) inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode); #else inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);