From b5a393c8a8d18854203880ddde2a7a15e819061b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 26 May 2021 13:05:36 -0700 Subject: [PATCH 01/60] f2fs: logging neatening Update the logging uses that have unnecessary newlines as the f2fs_printk function and so its f2fs_ macro callers already adds one. This allows searching single line logging entries with an easier grep and also avoids unnecessary blank lines in the logging. Miscellanea: o Coalesce formats o Align to open parenthesis Signed-off-by: Joe Perches Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 16 +++++++--------- fs/f2fs/file.c | 12 +++++------- fs/f2fs/gc.c | 4 ++-- fs/f2fs/segment.c | 2 +- fs/f2fs/super.c | 4 ++-- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a65191af9b93..85012e587901 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3844,7 +3844,7 @@ static int f2fs_is_file_aligned(struct inode *inode) /* hole */ if (!(map.m_flags & F2FS_MAP_FLAGS)) { - f2fs_err(sbi, "Swapfile has holes\n"); + f2fs_err(sbi, "Swapfile has holes"); ret = -ENOENT; goto out; } @@ -3865,9 +3865,8 @@ static int f2fs_is_file_aligned(struct inode *inode) cur_lblock += nr_pblocks; } if (not_aligned) - f2fs_warn(sbi, "Swapfile (%u) is not align to section: \n" - "\t1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", - not_aligned); + f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", + not_aligned); out: return ret; } @@ -3915,7 +3914,7 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, /* hole */ if (!(map.m_flags & F2FS_MAP_FLAGS)) { - f2fs_err(sbi, "Swapfile has holes\n"); + f2fs_err(sbi, "Swapfile has holes"); ret = -EINVAL; goto out; } @@ -3961,9 +3960,8 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, sis->highest_bit = cur_lblock - 1; if (not_aligned) - f2fs_warn(sbi, "Swapfile (%u) is not align to section: \n" - "\t1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", - not_aligned); + f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", + not_aligned); out: return ret; } @@ -4071,7 +4069,7 @@ static int check_swap_activate(struct swap_info_struct *sis, out: return ret; bad_bmap: - f2fs_err(sbi, "Swapfile has holes\n"); + f2fs_err(sbi, "Swapfile has holes"); return -EINVAL; } diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index de135917a3ac..d598c942bdcf 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3357,7 +3357,7 @@ static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg) if (!f2fs_sb_has_verity(F2FS_I_SB(inode))) { f2fs_warn(F2FS_I_SB(inode), - "Can't enable fs-verity on inode %lu: the verity feature is not enabled on this filesystem.\n", + "Can't enable fs-verity on inode %lu: the verity feature is not enabled on this filesystem", inode->i_ino); return -EOPNOTSUPP; } @@ -4141,9 +4141,8 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg) LLONG_MAX); if (ret) - f2fs_warn(sbi, "%s: The file might be partially decompressed " - "(errno=%d). Please delete the file.\n", - __func__, ret); + f2fs_warn(sbi, "%s: The file might be partially decompressed (errno=%d). Please delete the file.", + __func__, ret); out: inode_unlock(inode); file_end_write(filp); @@ -4215,9 +4214,8 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg) clear_inode_flag(inode, FI_ENABLE_COMPRESS); if (ret) - f2fs_warn(sbi, "%s: The file might be partially compressed " - "(errno=%d). Please delete the file.\n", - __func__, ret); + f2fs_warn(sbi, "%s: The file might be partially compressed (errno=%d). Please delete the file.", + __func__, ret); out: inode_unlock(inode); file_end_write(filp); diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index bcb3b488dbca..ab1c0123904f 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1031,8 +1031,8 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (unlikely(check_valid_map(sbi, segno, offset))) { if (!test_and_set_bit(segno, SIT_I(sbi)->invalid_segmap)) { - f2fs_err(sbi, "mismatched blkaddr %u (source_blkaddr %u) in seg %u\n", - blkaddr, source_blkaddr, segno); + f2fs_err(sbi, "mismatched blkaddr %u (source_blkaddr %u) in seg %u", + blkaddr, source_blkaddr, segno); f2fs_bug_on(sbi, 1); } } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 880f72b7c2e7..2cc970dfcfb5 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3920,7 +3920,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) /* sanity check for summary blocks */ if (nats_in_cursum(nat_j) > NAT_JOURNAL_ENTRIES || sits_in_cursum(sit_j) > SIT_JOURNAL_ENTRIES) { - f2fs_err(sbi, "invalid journal entries nats %u sits %u\n", + f2fs_err(sbi, "invalid journal entries nats %u sits %u", nats_in_cursum(nat_j), sits_in_cursum(sit_j)); return -EINVAL; } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 74b76d4b612b..c7819d36692c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1153,7 +1153,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) } if (test_opt(sbi, DISABLE_CHECKPOINT) && f2fs_lfs_mode(sbi)) { - f2fs_err(sbi, "LFS not compatible with checkpoint=disable\n"); + f2fs_err(sbi, "LFS not compatible with checkpoint=disable"); return -EINVAL; } @@ -3555,7 +3555,7 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) #ifdef CONFIG_BLK_DEV_ZONED if (bdev_zoned_model(FDEV(i).bdev) == BLK_ZONED_HM && !f2fs_sb_has_blkzoned(sbi)) { - f2fs_err(sbi, "Zoned block device feature not enabled\n"); + f2fs_err(sbi, "Zoned block device feature not enabled"); return -EINVAL; } if (bdev_zoned_model(FDEV(i).bdev) != BLK_ZONED_NONE) { From 832ee332626ace67d1475f33a060e056b8e39f70 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 21 May 2021 01:32:53 -0700 Subject: [PATCH 02/60] f2fs: support RO feature Given RO feature in superblock, we don't need to check provisioning/reserve spaces and SSA area. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 3 +++ fs/f2fs/segment.c | 4 ++++ fs/f2fs/super.c | 37 +++++++++++++++++++++++++++++++------ fs/f2fs/sysfs.c | 8 ++++++++ 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index bb51833ea123..761cdcac1bd8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -168,6 +168,7 @@ struct f2fs_mount_info { #define F2FS_FEATURE_SB_CHKSUM 0x0800 #define F2FS_FEATURE_CASEFOLD 0x1000 #define F2FS_FEATURE_COMPRESSION 0x2000 +#define F2FS_FEATURE_RO 0x4000 #define __F2FS_HAS_FEATURE(raw_super, mask) \ ((raw_super->feature & cpu_to_le32(mask)) != 0) @@ -940,6 +941,7 @@ static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode, #define NR_CURSEG_DATA_TYPE (3) #define NR_CURSEG_NODE_TYPE (3) #define NR_CURSEG_INMEM_TYPE (2) +#define NR_CURSEG_RO_TYPE (2) #define NR_CURSEG_PERSIST_TYPE (NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE) #define NR_CURSEG_TYPE (NR_CURSEG_INMEM_TYPE + NR_CURSEG_PERSIST_TYPE) @@ -4124,6 +4126,7 @@ F2FS_FEATURE_FUNCS(verity, VERITY); F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM); F2FS_FEATURE_FUNCS(casefold, CASEFOLD); F2FS_FEATURE_FUNCS(compression, COMPRESSION); +F2FS_FEATURE_FUNCS(readonly, RO); #ifdef CONFIG_BLK_DEV_ZONED static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi, diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 2cc970dfcfb5..d8f8e7f22744 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4683,6 +4683,10 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi) struct seg_entry *se = get_seg_entry(sbi, curseg->segno); unsigned int blkofs = curseg->next_blkoff; + if (f2fs_sb_has_readonly(sbi) && + i != CURSEG_HOT_DATA && i != CURSEG_HOT_NODE) + continue; + sanity_check_seg_type(sbi, curseg->seg_type); if (f2fs_test_bit(blkofs, se->cur_valid_map)) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index c7819d36692c..79c025749303 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -555,7 +555,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) int ret; if (!options) - return 0; + goto default_check; while ((p = strsep(&options, ",")) != NULL) { int token; @@ -1090,6 +1090,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) return -EINVAL; } } +default_check: #ifdef CONFIG_QUOTA if (f2fs_check_quota_options(sbi)) return -EINVAL; @@ -1162,6 +1163,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) */ if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_TYPE) F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; + + if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) { + f2fs_err(sbi, "Allow to mount readonly mode only"); + return -EROFS; + } return 0; } @@ -1822,7 +1828,11 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) static void default_options(struct f2fs_sb_info *sbi) { /* init some FS parameters */ - F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE; + if (f2fs_sb_has_readonly(sbi)) + F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE; + else + F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE; + F2FS_OPTION(sbi).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS; F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT; @@ -2004,6 +2014,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) if (f2fs_readonly(sb) && (*flags & SB_RDONLY)) goto skip; + if (f2fs_sb_has_readonly(sbi) && !(*flags & SB_RDONLY)) { + err = -EROFS; + goto restore_opts; + } + #ifdef CONFIG_QUOTA if (!f2fs_readonly(sb) && (*flags & SB_RDONLY)) { err = dquot_suspend(sb, -1); @@ -3137,14 +3152,15 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) ovp_segments = le32_to_cpu(ckpt->overprov_segment_count); reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count); - if (unlikely(fsmeta < F2FS_MIN_META_SEGMENTS || + if (!f2fs_sb_has_readonly(sbi) && + unlikely(fsmeta < F2FS_MIN_META_SEGMENTS || ovp_segments == 0 || reserved_segments == 0)) { f2fs_err(sbi, "Wrong layout: check mkfs.f2fs version"); return 1; } - user_block_count = le64_to_cpu(ckpt->user_block_count); - segment_count_main = le32_to_cpu(raw_super->segment_count_main); + segment_count_main = le32_to_cpu(raw_super->segment_count_main) + + (f2fs_sb_has_readonly(sbi) ? 1 : 0); log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); if (!user_block_count || user_block_count >= segment_count_main << log_blocks_per_seg) { @@ -3175,6 +3191,10 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs || le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg) return 1; + + if (f2fs_sb_has_readonly(sbi)) + goto check_data; + for (j = i + 1; j < NR_CURSEG_NODE_TYPE; j++) { if (le32_to_cpu(ckpt->cur_node_segno[i]) == le32_to_cpu(ckpt->cur_node_segno[j])) { @@ -3185,10 +3205,15 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) } } } +check_data: for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) { if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs || le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg) return 1; + + if (f2fs_sb_has_readonly(sbi)) + goto skip_cross; + for (j = i + 1; j < NR_CURSEG_DATA_TYPE; j++) { if (le32_to_cpu(ckpt->cur_data_segno[i]) == le32_to_cpu(ckpt->cur_data_segno[j])) { @@ -3210,7 +3235,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) } } } - +skip_cross: sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize); nat_bitmap_size = le32_to_cpu(ckpt->nat_ver_bitmap_bytesize); diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index dc71bc968c72..c579d5d3a916 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -158,6 +158,9 @@ static ssize_t features_show(struct f2fs_attr *a, if (f2fs_sb_has_casefold(sbi)) len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", len ? ", " : "", "casefold"); + if (f2fs_sb_has_readonly(sbi)) + len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", + len ? ", " : "", "readonly"); if (f2fs_sb_has_compression(sbi)) len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", len ? ", " : "", "compression"); @@ -578,6 +581,7 @@ enum feat_id { FEAT_SB_CHECKSUM, FEAT_CASEFOLD, FEAT_COMPRESSION, + FEAT_RO, FEAT_TEST_DUMMY_ENCRYPTION_V2, }; @@ -599,6 +603,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a, case FEAT_SB_CHECKSUM: case FEAT_CASEFOLD: case FEAT_COMPRESSION: + case FEAT_RO: case FEAT_TEST_DUMMY_ENCRYPTION_V2: return sprintf(buf, "supported\n"); } @@ -721,12 +726,14 @@ F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY); #endif F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD); +F2FS_FEATURE_RO_ATTR(readonly, FEAT_RO); #ifdef CONFIG_F2FS_FS_COMPRESSION F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode); #endif + /* For ATGC */ F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_ratio, candidate_ratio); F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_count); @@ -830,6 +837,7 @@ static struct attribute *f2fs_feat_attrs[] = { #endif ATTR_LIST(sb_checksum), ATTR_LIST(casefold), + ATTR_LIST(readonly), #ifdef CONFIG_F2FS_FS_COMPRESSION ATTR_LIST(compression), #endif From 7004c47db2b66abb63cfd7bc959ebafae1c0a873 Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Thu, 3 Jun 2021 09:50:37 +0000 Subject: [PATCH 03/60] f2fs: Show casefolding support only when supported The casefolding feature is only supported when CONFIG_UNICODE is set. This modifies the feature list f2fs presents under sysfs accordingly. Fixes: 5aba54302a46 ("f2fs: include charset encoding information in the superblock") Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Daniel Rosenberg Reviewed-by: Eric Biggers Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/sysfs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index c579d5d3a916..62fbe4f20dd6 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -725,7 +725,9 @@ F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY); #endif F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); +#ifdef CONFIG_UNICODE F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD); +#endif F2FS_FEATURE_RO_ATTR(readonly, FEAT_RO); #ifdef CONFIG_F2FS_FS_COMPRESSION F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION); @@ -836,7 +838,9 @@ static struct attribute *f2fs_feat_attrs[] = { ATTR_LIST(verity), #endif ATTR_LIST(sb_checksum), +#ifdef CONFIG_UNICODE ATTR_LIST(casefold), +#endif ATTR_LIST(readonly), #ifdef CONFIG_F2FS_FS_COMPRESSION ATTR_LIST(compression), From d8755821c43875b20f750d3a3e609d40d7729f6f Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Thu, 3 Jun 2021 09:50:38 +0000 Subject: [PATCH 04/60] f2fs: Advertise encrypted casefolding in sysfs Older kernels don't support encryption with casefolding. This adds the sysfs entry encrypted_casefold to show support for those combined features. Support for this feature was originally added by commit 7ad08a58bf67 ("f2fs: Handle casefolding with Encryption") Fixes: 7ad08a58bf67 ("f2fs: Handle casefolding with Encryption") Cc: stable@vger.kernel.org # v5.11+ Signed-off-by: Daniel Rosenberg Reviewed-by: Eric Biggers Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/sysfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 62fbe4f20dd6..4daa6aeb200b 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -583,6 +583,7 @@ enum feat_id { FEAT_COMPRESSION, FEAT_RO, FEAT_TEST_DUMMY_ENCRYPTION_V2, + FEAT_ENCRYPTED_CASEFOLD, }; static ssize_t f2fs_feature_show(struct f2fs_attr *a, @@ -605,6 +606,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a, case FEAT_COMPRESSION: case FEAT_RO: case FEAT_TEST_DUMMY_ENCRYPTION_V2: + case FEAT_ENCRYPTED_CASEFOLD: return sprintf(buf, "supported\n"); } return 0; @@ -709,7 +711,10 @@ F2FS_GENERAL_RO_ATTR(avg_vblocks); #ifdef CONFIG_FS_ENCRYPTION F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2, FEAT_TEST_DUMMY_ENCRYPTION_V2); +#ifdef CONFIG_UNICODE +F2FS_FEATURE_RO_ATTR(encrypted_casefold, FEAT_ENCRYPTED_CASEFOLD); #endif +#endif /* CONFIG_FS_ENCRYPTION */ #ifdef CONFIG_BLK_DEV_ZONED F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); #endif @@ -822,7 +827,10 @@ static struct attribute *f2fs_feat_attrs[] = { #ifdef CONFIG_FS_ENCRYPTION ATTR_LIST(encryption), ATTR_LIST(test_dummy_encryption_v2), +#ifdef CONFIG_UNICODE + ATTR_LIST(encrypted_casefold), #endif +#endif /* CONFIG_FS_ENCRYPTION */ #ifdef CONFIG_BLK_DEV_ZONED ATTR_LIST(block_zoned), #endif From 95f2afc02d37b02b748adcc5a7e607297c9f2741 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 3 Jun 2021 22:30:09 -0700 Subject: [PATCH 05/60] f2fs: add pin_file in feature list This patch adds missing pin_file feature supported by kernel. Fixes: f5a53edcf01e ("f2fs: support aligned pinned file") Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 4daa6aeb200b..e4d5090b7cb3 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -740,6 +740,7 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode); #endif +F2FS_FEATURE_RO_ATTR(pin_file); /* For ATGC */ F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_ratio, candidate_ratio); @@ -853,6 +854,7 @@ static struct attribute *f2fs_feat_attrs[] = { #ifdef CONFIG_F2FS_FS_COMPRESSION ATTR_LIST(compression), #endif + ATTR_LIST(pin_file), NULL, }; ATTRIBUTE_GROUPS(f2fs_feat); From d90505e519acde51fd97f40883334eaedb1bba71 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 3 Jun 2021 12:31:08 -0700 Subject: [PATCH 06/60] f2fs: clean up /sys/fs/f2fs//features Let's create /sys/fs/f2fs//feature_list/ to meet sysfs rule. Note that there are three feature list entries: 1) /sys/fs/f2fs/features : shows runtime features supported by in-kernel f2fs along with Kconfig. - ref. F2FS_FEATURE_RO_ATTR() 2) /sys/fs/f2fs/$s_id/features : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This won't add new feature anymore, and thus, users should check entries in 3) instead of this 2). 3) /sys/fs/f2fs/$s_id/feature_list : shows on-disk features enabled by mkfs.f2fs per instance, which follows sysfs entry rule where each entry should expose single value. This list covers old feature list provided by 2) and beyond. Therefore, please add new on-disk feature in this list only. - ref. F2FS_SB_FEATURE_RO_ATTR() Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 29 +++- fs/f2fs/f2fs.h | 3 + fs/f2fs/sysfs.c | 195 ++++++++++++++++-------- 3 files changed, 162 insertions(+), 65 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 5088281e312e..95155e4ec7fe 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -203,7 +203,34 @@ Description: Shows total written kbytes issued to disk. What: /sys/fs/f2fs//features Date: July 2017 Contact: "Jaegeuk Kim" -Description: Shows all enabled features in current device. +Description: /feature_list/ + Shows all enabled features in current device. + Supported features: + encryption, blkzoned, extra_attr, projquota, inode_checksum, + flexible_inline_xattr, quota_ino, inode_crtime, lost_found, + verity, sb_checksum, casefold, readonly, compression, pin_file. + +What: /sys/fs/f2fs//feature_list/ +Date: June 2021 +Contact: "Jaegeuk Kim" +Description: Expand /sys/fs/f2fs//features to meet sysfs rule. + Supported on-disk features: + encryption, block_zoned (aka blkzoned), extra_attr, + project_quota (aka projquota), inode_checksum, + flexible_inline_xattr, quota_ino, inode_crtime, lost_found, + verity, sb_checksum, casefold, readonly, compression. + Note that, pin_file is moved into /sys/fs/f2fs/features/. + +What: /sys/fs/f2fs/features/ +Date: July 2017 +Contact: "Jaegeuk Kim" +Description: Shows all enabled kernel features. + Supported features: + encryption, block_zoned, extra_attr, project_quota, + inode_checksum, flexible_inline_xattr, quota_ino, + inode_crtime, lost_found, verity, sb_checksum, + casefold, readonly, compression, test_dummy_encryption_v2, + atomic_write, pin_file, encrypted_casefold. What: /sys/fs/f2fs//inject_rate Date: May 2016 diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 761cdcac1bd8..20530fe3caa4 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1665,6 +1665,9 @@ struct f2fs_sb_info { struct kobject s_stat_kobj; /* /sys/fs/f2fs//stat */ struct completion s_stat_kobj_unregister; + struct kobject s_feature_list_kobj; /* /sys/fs/f2fs//feature_list */ + struct completion s_feature_list_kobj_unregister; + /* For shrinker support */ struct list_head s_list; int s_ndevs; /* number of devices */ diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index e4d5090b7cb3..6642246206bd 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -566,50 +566,49 @@ static void f2fs_sb_release(struct kobject *kobj) complete(&sbi->s_kobj_unregister); } -enum feat_id { - FEAT_CRYPTO = 0, - FEAT_BLKZONED, - FEAT_ATOMIC_WRITE, - FEAT_EXTRA_ATTR, - FEAT_PROJECT_QUOTA, - FEAT_INODE_CHECKSUM, - FEAT_FLEXIBLE_INLINE_XATTR, - FEAT_QUOTA_INO, - FEAT_INODE_CRTIME, - FEAT_LOST_FOUND, - FEAT_VERITY, - FEAT_SB_CHECKSUM, - FEAT_CASEFOLD, - FEAT_COMPRESSION, - FEAT_RO, - FEAT_TEST_DUMMY_ENCRYPTION_V2, - FEAT_ENCRYPTED_CASEFOLD, -}; - +/* + * Note that there are three feature list entries: + * 1) /sys/fs/f2fs/features + * : shows runtime features supported by in-kernel f2fs along with Kconfig. + * - ref. F2FS_FEATURE_RO_ATTR() + * + * 2) /sys/fs/f2fs/$s_id/features + * : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This + * won't add new feature anymore, and thus, users should check entries in 3) + * instead of this 2). + * + * 3) /sys/fs/f2fs/$s_id/feature_list + * : shows on-disk features enabled by mkfs.f2fs per instance, which follows + * sysfs entry rule where each entry should expose single value. + * This list covers old feature list provided by 2) and beyond. Therefore, + * please add new on-disk feature in this list only. + * - ref. F2FS_SB_FEATURE_RO_ATTR() + */ static ssize_t f2fs_feature_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { - switch (a->id) { - case FEAT_CRYPTO: - case FEAT_BLKZONED: - case FEAT_ATOMIC_WRITE: - case FEAT_EXTRA_ATTR: - case FEAT_PROJECT_QUOTA: - case FEAT_INODE_CHECKSUM: - case FEAT_FLEXIBLE_INLINE_XATTR: - case FEAT_QUOTA_INO: - case FEAT_INODE_CRTIME: - case FEAT_LOST_FOUND: - case FEAT_VERITY: - case FEAT_SB_CHECKSUM: - case FEAT_CASEFOLD: - case FEAT_COMPRESSION: - case FEAT_RO: - case FEAT_TEST_DUMMY_ENCRYPTION_V2: - case FEAT_ENCRYPTED_CASEFOLD: + return sprintf(buf, "supported\n"); +} + +#define F2FS_FEATURE_RO_ATTR(_name) \ +static struct f2fs_attr f2fs_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0444 }, \ + .show = f2fs_feature_show, \ +} + +static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + if (F2FS_HAS_FEATURE(sbi, a->id)) return sprintf(buf, "supported\n"); - } - return 0; + return sprintf(buf, "unsupported\n"); +} + +#define F2FS_SB_FEATURE_RO_ATTR(_name, _feat) \ +static struct f2fs_attr f2fs_attr_sb_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0444 }, \ + .show = f2fs_sb_feature_show, \ + .id = F2FS_FEATURE_##_feat, \ } #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ @@ -629,13 +628,6 @@ static struct f2fs_attr f2fs_attr_##_name = { \ #define F2FS_GENERAL_RO_ATTR(name) \ static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) -#define F2FS_FEATURE_RO_ATTR(_name, _id) \ -static struct f2fs_attr f2fs_attr_##_name = { \ - .attr = {.name = __stringify(_name), .mode = 0444 }, \ - .show = f2fs_feature_show, \ - .id = _id, \ -} - #define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = 0444 }, \ @@ -709,33 +701,33 @@ F2FS_GENERAL_RO_ATTR(avg_vblocks); #endif #ifdef CONFIG_FS_ENCRYPTION -F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); -F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2, FEAT_TEST_DUMMY_ENCRYPTION_V2); +F2FS_FEATURE_RO_ATTR(encryption); +F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2); #ifdef CONFIG_UNICODE -F2FS_FEATURE_RO_ATTR(encrypted_casefold, FEAT_ENCRYPTED_CASEFOLD); +F2FS_FEATURE_RO_ATTR(encrypted_casefold); #endif #endif /* CONFIG_FS_ENCRYPTION */ #ifdef CONFIG_BLK_DEV_ZONED -F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); +F2FS_FEATURE_RO_ATTR(block_zoned); #endif -F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE); -F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); -F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); -F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM); -F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR); -F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO); -F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); -F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); +F2FS_FEATURE_RO_ATTR(atomic_write); +F2FS_FEATURE_RO_ATTR(extra_attr); +F2FS_FEATURE_RO_ATTR(project_quota); +F2FS_FEATURE_RO_ATTR(inode_checksum); +F2FS_FEATURE_RO_ATTR(flexible_inline_xattr); +F2FS_FEATURE_RO_ATTR(quota_ino); +F2FS_FEATURE_RO_ATTR(inode_crtime); +F2FS_FEATURE_RO_ATTR(lost_found); #ifdef CONFIG_FS_VERITY -F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY); +F2FS_FEATURE_RO_ATTR(verity); #endif -F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); +F2FS_FEATURE_RO_ATTR(sb_checksum); #ifdef CONFIG_UNICODE -F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD); +F2FS_FEATURE_RO_ATTR(casefold); #endif -F2FS_FEATURE_RO_ATTR(readonly, FEAT_RO); +F2FS_FEATURE_RO_ATTR(readonly); #ifdef CONFIG_F2FS_FS_COMPRESSION -F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION); +F2FS_FEATURE_RO_ATTR(compression); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode); @@ -866,6 +858,40 @@ static struct attribute *f2fs_stat_attrs[] = { }; ATTRIBUTE_GROUPS(f2fs_stat); +F2FS_SB_FEATURE_RO_ATTR(encryption, ENCRYPT); +F2FS_SB_FEATURE_RO_ATTR(block_zoned, BLKZONED); +F2FS_SB_FEATURE_RO_ATTR(extra_attr, EXTRA_ATTR); +F2FS_SB_FEATURE_RO_ATTR(project_quota, PRJQUOTA); +F2FS_SB_FEATURE_RO_ATTR(inode_checksum, INODE_CHKSUM); +F2FS_SB_FEATURE_RO_ATTR(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR); +F2FS_SB_FEATURE_RO_ATTR(quota_ino, QUOTA_INO); +F2FS_SB_FEATURE_RO_ATTR(inode_crtime, INODE_CRTIME); +F2FS_SB_FEATURE_RO_ATTR(lost_found, LOST_FOUND); +F2FS_SB_FEATURE_RO_ATTR(verity, VERITY); +F2FS_SB_FEATURE_RO_ATTR(sb_checksum, SB_CHKSUM); +F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD); +F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION); +F2FS_SB_FEATURE_RO_ATTR(readonly, RO); + +static struct attribute *f2fs_sb_feat_attrs[] = { + ATTR_LIST(sb_encryption), + ATTR_LIST(sb_block_zoned), + ATTR_LIST(sb_extra_attr), + ATTR_LIST(sb_project_quota), + ATTR_LIST(sb_inode_checksum), + ATTR_LIST(sb_flexible_inline_xattr), + ATTR_LIST(sb_quota_ino), + ATTR_LIST(sb_inode_crtime), + ATTR_LIST(sb_lost_found), + ATTR_LIST(sb_verity), + ATTR_LIST(sb_sb_checksum), + ATTR_LIST(sb_casefold), + ATTR_LIST(sb_compression), + ATTR_LIST(sb_readonly), + NULL, +}; +ATTRIBUTE_GROUPS(f2fs_sb_feat); + static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, .store = f2fs_attr_store, @@ -932,6 +958,33 @@ static struct kobj_type f2fs_stat_ktype = { .release = f2fs_stat_kobj_release, }; +static ssize_t f2fs_sb_feat_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, + s_feature_list_kobj); + struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); + + return a->show ? a->show(a, sbi, buf) : 0; +} + +static void f2fs_feature_list_kobj_release(struct kobject *kobj) +{ + struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, + s_feature_list_kobj); + complete(&sbi->s_feature_list_kobj_unregister); +} + +static const struct sysfs_ops f2fs_feature_list_attr_ops = { + .show = f2fs_sb_feat_attr_show, +}; + +static struct kobj_type f2fs_feature_list_ktype = { + .default_groups = f2fs_sb_feat_groups, + .sysfs_ops = &f2fs_feature_list_attr_ops, + .release = f2fs_feature_list_kobj_release, +}; + static int __maybe_unused segment_info_seq_show(struct seq_file *seq, void *offset) { @@ -1148,6 +1201,14 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi) if (err) goto put_stat_kobj; + sbi->s_feature_list_kobj.kset = &f2fs_kset; + init_completion(&sbi->s_feature_list_kobj_unregister); + err = kobject_init_and_add(&sbi->s_feature_list_kobj, + &f2fs_feature_list_ktype, + &sbi->s_kobj, "feature_list"); + if (err) + goto put_feature_list_kobj; + if (f2fs_proc_root) sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); @@ -1162,6 +1223,9 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi) victim_bits_seq_show, sb); } return 0; +put_feature_list_kobj: + kobject_put(&sbi->s_feature_list_kobj); + wait_for_completion(&sbi->s_feature_list_kobj_unregister); put_stat_kobj: kobject_put(&sbi->s_stat_kobj); wait_for_completion(&sbi->s_stat_kobj_unregister); @@ -1184,6 +1248,9 @@ void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi) kobject_del(&sbi->s_stat_kobj); kobject_put(&sbi->s_stat_kobj); wait_for_completion(&sbi->s_stat_kobj_unregister); + kobject_del(&sbi->s_feature_list_kobj); + kobject_put(&sbi->s_feature_list_kobj); + wait_for_completion(&sbi->s_feature_list_kobj_unregister); kobject_del(&sbi->s_kobj); kobject_put(&sbi->s_kobj); From ec3ea14d2fd3e1c6c9181440d181f3fe0c3b4a0a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 20 May 2021 19:51:50 +0800 Subject: [PATCH 07/60] f2fs: compress: add compress_inode to cache compressed blocks Support to use address space of inner inode to cache compressed block, in order to improve cache hit ratio of random read. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.rst | 3 + fs/f2fs/compress.c | 168 ++++++++++++++++++++++++++++- fs/f2fs/data.c | 41 +++++-- fs/f2fs/debug.c | 13 +++ fs/f2fs/f2fs.h | 71 +++++++++++- fs/f2fs/gc.c | 1 + fs/f2fs/inode.c | 21 +++- fs/f2fs/node.c | 14 +++ fs/f2fs/node.h | 1 + fs/f2fs/segment.c | 6 +- fs/f2fs/super.c | 35 +++++- include/linux/f2fs_fs.h | 1 + 12 files changed, 361 insertions(+), 14 deletions(-) diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index 992bf91eeec8..809c4d0a696f 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -289,6 +289,9 @@ compress_mode=%s Control file compression mode. This supports "fs" and "user" choosing the target file and the timing. The user can do manual compression/decompression on the compression enabled files using ioctls. +compress_cache Support to use address space of a filesystem managed inode to + cache compressed block, in order to improve cache hit ratio of + random read. inlinecrypt When possible, encrypt/decrypt the contents of encrypted files using the blk-crypto framework rather than filesystem-layer encryption. This allows the use of diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 1c3e98085591..455561826c7d 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -12,9 +12,11 @@ #include #include #include +#include #include "f2fs.h" #include "node.h" +#include "segment.h" #include static struct kmem_cache *cic_entry_slab; @@ -736,7 +738,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc) return ret; } -static void f2fs_decompress_cluster(struct decompress_io_ctx *dic) +void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); struct f2fs_inode_info *fi = F2FS_I(dic->inode); @@ -835,7 +837,8 @@ static void f2fs_decompress_cluster(struct decompress_io_ctx *dic) * page being waited on in the cluster, and if so, it decompresses the cluster * (or in the case of a failure, cleans up without actually decompressing). */ -void f2fs_end_read_compressed_page(struct page *page, bool failed) +void f2fs_end_read_compressed_page(struct page *page, bool failed, + block_t blkaddr) { struct decompress_io_ctx *dic = (struct decompress_io_ctx *)page_private(page); @@ -845,6 +848,9 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed) if (failed) WRITE_ONCE(dic->failed, true); + else if (blkaddr) + f2fs_cache_compressed_page(sbi, page, + dic->inode->i_ino, blkaddr); if (atomic_dec_and_test(&dic->remaining_pages)) f2fs_decompress_cluster(dic); @@ -1660,6 +1666,164 @@ void f2fs_put_page_dic(struct page *page) f2fs_put_dic(dic); } +const struct address_space_operations f2fs_compress_aops = { + .releasepage = f2fs_release_page, + .invalidatepage = f2fs_invalidate_page, +}; + +struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi) +{ + return sbi->compress_inode->i_mapping; +} + +void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr) +{ + if (!sbi->compress_inode) + return; + invalidate_mapping_pages(COMPRESS_MAPPING(sbi), blkaddr, blkaddr); +} + +void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + nid_t ino, block_t blkaddr) +{ + struct page *cpage; + int ret; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return; + + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) + return; + + if (!f2fs_available_free_memory(sbi, COMPRESS_PAGE)) + return; + + cpage = find_get_page(COMPRESS_MAPPING(sbi), blkaddr); + if (cpage) { + f2fs_put_page(cpage, 0); + return; + } + + cpage = alloc_page(__GFP_NOWARN | __GFP_IO); + if (!cpage) + return; + + ret = add_to_page_cache_lru(cpage, COMPRESS_MAPPING(sbi), + blkaddr, GFP_NOFS); + if (ret) { + f2fs_put_page(cpage, 0); + return; + } + + set_page_private_data(cpage, ino); + + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) + goto out; + + memcpy(page_address(cpage), page_address(page), PAGE_SIZE); + SetPageUptodate(cpage); +out: + f2fs_put_page(cpage, 1); +} + +bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + block_t blkaddr) +{ + struct page *cpage; + bool hitted = false; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return false; + + cpage = f2fs_pagecache_get_page(COMPRESS_MAPPING(sbi), + blkaddr, FGP_LOCK | FGP_NOWAIT, GFP_NOFS); + if (cpage) { + if (PageUptodate(cpage)) { + atomic_inc(&sbi->compress_page_hit); + memcpy(page_address(page), + page_address(cpage), PAGE_SIZE); + hitted = true; + } + f2fs_put_page(cpage, 1); + } + + return hitted; +} + +void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino) +{ + struct address_space *mapping = sbi->compress_inode->i_mapping; + struct pagevec pvec; + pgoff_t index = 0; + pgoff_t end = MAX_BLKADDR(sbi); + + if (!mapping->nrpages) + return; + + pagevec_init(&pvec); + + do { + unsigned int nr_pages; + int i; + + nr_pages = pagevec_lookup_range(&pvec, mapping, + &index, end - 1); + if (!nr_pages) + break; + + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + if (page->index > end) + break; + + lock_page(page); + if (page->mapping != mapping) { + unlock_page(page); + continue; + } + + if (ino != get_page_private_data(page)) { + unlock_page(page); + continue; + } + + generic_error_remove_page(mapping, page); + unlock_page(page); + } + pagevec_release(&pvec); + cond_resched(); + } while (index < end); +} + +int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) +{ + struct inode *inode; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return 0; + + inode = f2fs_iget(sbi->sb, F2FS_COMPRESS_INO(sbi)); + if (IS_ERR(inode)) + return PTR_ERR(inode); + sbi->compress_inode = inode; + + sbi->compress_percent = COMPRESS_PERCENT; + sbi->compress_watermark = COMPRESS_WATERMARK; + + atomic_set(&sbi->compress_page_hit, 0); + + return 0; +} + +void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) +{ + if (!sbi->compress_inode) + return; + iput(sbi->compress_inode); + sbi->compress_inode = NULL; +} + int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { dev_t dev = sbi->sb->s_bdev->bd_dev; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 85012e587901..26684893ad71 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -132,7 +132,7 @@ static void f2fs_finish_read_bio(struct bio *bio) if (f2fs_is_compressed_page(page)) { if (bio->bi_status) - f2fs_end_read_compressed_page(page, true); + f2fs_end_read_compressed_page(page, true, 0); f2fs_put_page_dic(page); continue; } @@ -228,15 +228,19 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) struct bio_vec *bv; struct bvec_iter_all iter_all; bool all_compressed = true; + block_t blkaddr = SECTOR_TO_BLOCK(ctx->bio->bi_iter.bi_sector); bio_for_each_segment_all(bv, ctx->bio, iter_all) { struct page *page = bv->bv_page; /* PG_error was set if decryption failed. */ if (f2fs_is_compressed_page(page)) - f2fs_end_read_compressed_page(page, PageError(page)); + f2fs_end_read_compressed_page(page, PageError(page), + blkaddr); else all_compressed = false; + + blkaddr++; } /* @@ -1363,9 +1367,11 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) old_blkaddr = dn->data_blkaddr; f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr, &sum, seg_type, NULL); - if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) + if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(sbi), old_blkaddr, old_blkaddr); + f2fs_invalidate_compress_page(sbi, old_blkaddr); + } f2fs_update_data_blkaddr(dn, dn->data_blkaddr); /* @@ -2185,7 +2191,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, goto out_put_dnode; } - for (i = 0; i < dic->nr_cpages; i++) { + for (i = 0; i < cc->nr_cpages; i++) { struct page *page = dic->cpages[i]; block_t blkaddr; struct bio_post_read_ctx *ctx; @@ -2193,6 +2199,14 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, blkaddr = data_blkaddr(dn.inode, dn.node_page, dn.ofs_in_node + i + 1); + f2fs_wait_on_block_writeback(inode, blkaddr); + + if (f2fs_load_compressed_page(sbi, page, blkaddr)) { + if (atomic_dec_and_test(&dic->remaining_pages)) + f2fs_decompress_cluster(dic); + continue; + } + if (bio && (!page_is_mergeable(sbi, bio, *last_block_in_bio, blkaddr) || !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) { @@ -2214,8 +2228,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, } } - f2fs_wait_on_block_writeback(inode, blkaddr); - if (bio_add_page(bio, page, blocksize, 0) < blocksize) goto submit_and_realloc; @@ -3629,6 +3641,13 @@ void f2fs_invalidate_page(struct page *page, unsigned int offset, clear_page_private_gcing(page); + if (test_opt(sbi, COMPRESS_CACHE)) { + if (f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_COMPRESS_INO(sbi)) + clear_page_private_data(page); + } + if (page_private_atomic(page)) return f2fs_drop_inmem_page(inode, page); @@ -3646,6 +3665,16 @@ int f2fs_release_page(struct page *page, gfp_t wait) if (page_private_atomic(page)) return 0; + if (test_opt(F2FS_P_SB(page), COMPRESS_CACHE)) { + struct f2fs_sb_info *sbi = F2FS_P_SB(page); + struct inode *inode = page->mapping->host; + + if (f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_COMPRESS_INO(sbi)) + clear_page_private_data(page); + } + clear_page_private_gcing(page); detach_page_private(page); diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index c03949a7ccff..833325038ef3 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -152,6 +152,12 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->node_pages = NODE_MAPPING(sbi)->nrpages; if (sbi->meta_inode) si->meta_pages = META_MAPPING(sbi)->nrpages; +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (sbi->compress_inode) { + si->compress_pages = COMPRESS_MAPPING(sbi)->nrpages; + si->compress_page_hit = atomic_read(&sbi->compress_page_hit); + } +#endif si->nats = NM_I(sbi)->nat_cnt[TOTAL_NAT]; si->dirty_nats = NM_I(sbi)->nat_cnt[DIRTY_NAT]; si->sits = MAIN_SEGS(sbi); @@ -309,6 +315,12 @@ static void update_mem_info(struct f2fs_sb_info *sbi) si->page_mem += (unsigned long long)npages << PAGE_SHIFT; } +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (sbi->compress_inode) { + unsigned npages = COMPRESS_MAPPING(sbi)->nrpages; + si->page_mem += (unsigned long long)npages << PAGE_SHIFT; + } +#endif } static int stat_show(struct seq_file *s, void *v) @@ -476,6 +488,7 @@ static int stat_show(struct seq_file *s, void *v) "volatile IO: %4d (Max. %4d)\n", si->inmem_pages, si->aw_cnt, si->max_aw_cnt, si->vw_cnt, si->max_vw_cnt); + seq_printf(s, " - compress: %4d, hit:%8d\n", si->compress_pages, si->compress_page_hit); seq_printf(s, " - nodes: %4d in %4d\n", si->ndirty_node, si->node_pages); seq_printf(s, " - dents: %4d in dirs:%4d (%4d)\n", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 20530fe3caa4..1c09fcbb4e12 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -98,6 +98,7 @@ extern const char *f2fs_fault_name[FAULT_MAX]; #define F2FS_MOUNT_ATGC 0x08000000 #define F2FS_MOUNT_MERGE_CHECKPOINT 0x10000000 #define F2FS_MOUNT_GC_MERGE 0x20000000 +#define F2FS_MOUNT_COMPRESS_CACHE 0x40000000 #define F2FS_OPTION(sbi) ((sbi)->mount_opt) #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option) @@ -1374,6 +1375,37 @@ PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION); PAGE_PRIVATE_CLEAR_FUNC(atomic, ATOMIC_WRITE); PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE); +static inline unsigned long get_page_private_data(struct page *page) +{ + unsigned long data = page_private(page); + + if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data)) + return 0; + return data >> PAGE_PRIVATE_MAX; +} + +static inline void set_page_private_data(struct page *page, unsigned long data) +{ + if (!PagePrivate(page)) { + get_page(page); + SetPagePrivate(page); + } + set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); + page_private(page) |= data << PAGE_PRIVATE_MAX; +} + +static inline void clear_page_private_data(struct page *page) +{ + page_private(page) &= (1 << PAGE_PRIVATE_MAX) - 1; + if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) { + set_page_private(page, 0); + if (PagePrivate(page)) { + ClearPagePrivate(page); + put_page(page); + } + } +} + /* For compression */ enum compress_algorithm_type { COMPRESS_LZO, @@ -1388,6 +1420,9 @@ enum compress_flag { COMPRESS_MAX_FLAG, }; +#define COMPRESS_WATERMARK 20 +#define COMPRESS_PERCENT 20 + #define COMPRESS_DATA_RESERVED_SIZE 4 struct compress_data { __le32 clen; /* compressed data size */ @@ -1700,6 +1735,12 @@ struct f2fs_sb_info { u64 compr_written_block; u64 compr_saved_block; u32 compr_new_inode; + + /* For compressed block cache */ + struct inode *compress_inode; /* cache compressed blocks */ + unsigned int compress_percent; /* cache page percentage */ + unsigned int compress_watermark; /* cache page watermark */ + atomic_t compress_page_hit; /* cache hit count */ #endif }; @@ -3667,7 +3708,8 @@ struct f2fs_stat_info { unsigned int bimodal, avg_vblocks; int util_free, util_valid, util_invalid; int rsvd_segs, overp_segs; - int dirty_count, node_pages, meta_pages; + int dirty_count, node_pages, meta_pages, compress_pages; + int compress_page_hit; int prefree_count, call_count, cp_count, bg_cp_count; int tot_segs, node_segs, data_segs, free_segs, free_secs; int bg_node_segs, bg_data_segs; @@ -4003,7 +4045,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page); bool f2fs_is_compress_backend_ready(struct inode *inode); int f2fs_init_compress_mempool(void); void f2fs_destroy_compress_mempool(void); -void f2fs_end_read_compressed_page(struct page *page, bool failed); +void f2fs_decompress_cluster(struct decompress_io_ctx *dic); +void f2fs_end_read_compressed_page(struct page *page, bool failed, + block_t blkaddr); bool f2fs_cluster_is_empty(struct compress_ctx *cc); bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index); void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page); @@ -4021,10 +4065,19 @@ void f2fs_put_page_dic(struct page *page); int f2fs_init_compress_ctx(struct compress_ctx *cc); void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); void f2fs_init_compress_info(struct f2fs_sb_info *sbi); +int f2fs_init_compress_inode(struct f2fs_sb_info *sbi); +void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi); int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi); void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi); int __init f2fs_init_compress_cache(void); void f2fs_destroy_compress_cache(void); +struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi); +void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr); +void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + nid_t ino, block_t blkaddr); +bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + block_t blkaddr); +void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino); #define inc_compr_inode_stat(inode) \ do { \ struct f2fs_sb_info *sbi = F2FS_I_SB(inode); \ @@ -4053,7 +4106,9 @@ static inline struct page *f2fs_compress_control_page(struct page *page) } static inline int f2fs_init_compress_mempool(void) { return 0; } static inline void f2fs_destroy_compress_mempool(void) { } -static inline void f2fs_end_read_compressed_page(struct page *page, bool failed) +static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { } +static inline void f2fs_end_read_compressed_page(struct page *page, + bool failed, block_t blkaddr) { WARN_ON_ONCE(1); } @@ -4061,10 +4116,20 @@ static inline void f2fs_put_page_dic(struct page *page) { WARN_ON_ONCE(1); } +static inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; } +static inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { } static inline int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi) { } static inline int __init f2fs_init_compress_cache(void) { return 0; } static inline void f2fs_destroy_compress_cache(void) { } +static inline void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, + block_t blkaddr) { } +static inline void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, + struct page *page, nid_t ino, block_t blkaddr) { } +static inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, + struct page *page, block_t blkaddr) { return false; } +static inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, + nid_t ino) { } #define inc_compr_inode_stat(inode) do { } while (0) #endif diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index ab1c0123904f..da5947b30142 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1261,6 +1261,7 @@ static int move_data_block(struct inode *inode, block_t bidx, f2fs_put_page(mpage, 1); invalidate_mapping_pages(META_MAPPING(fio.sbi), fio.old_blkaddr, fio.old_blkaddr); + f2fs_invalidate_compress_page(fio.sbi, fio.old_blkaddr); set_page_dirty(fio.encrypted_page); if (clear_page_dirty_for_io(fio.encrypted_page)) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index cbda7ca3b3be..9141147b5bb0 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -18,6 +18,10 @@ #include +#ifdef CONFIG_F2FS_FS_COMPRESSION +extern const struct address_space_operations f2fs_compress_aops; +#endif + void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) { if (is_inode_flag_set(inode, FI_NEW_INODE)) @@ -494,6 +498,11 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi)) goto make_now; +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (ino == F2FS_COMPRESS_INO(sbi)) + goto make_now; +#endif + ret = do_read_inode(inode); if (ret) goto bad_inode; @@ -504,6 +513,12 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) } else if (ino == F2FS_META_INO(sbi)) { inode->i_mapping->a_ops = &f2fs_meta_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); + } else if (ino == F2FS_COMPRESS_INO(sbi)) { +#ifdef CONFIG_F2FS_FS_COMPRESSION + inode->i_mapping->a_ops = &f2fs_compress_aops; +#endif + mapping_set_gfp_mask(inode->i_mapping, + GFP_NOFS | __GFP_HIGHMEM | __GFP_MOVABLE); } else if (S_ISREG(inode->i_mode)) { inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; @@ -723,8 +738,12 @@ void f2fs_evict_inode(struct inode *inode) trace_f2fs_evict_inode(inode); truncate_inode_pages_final(&inode->i_data); + if (test_opt(sbi, COMPRESS_CACHE) && f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_NODE_INO(sbi) || - inode->i_ino == F2FS_META_INO(sbi)) + inode->i_ino == F2FS_META_INO(sbi) || + inode->i_ino == F2FS_COMPRESS_INO(sbi)) goto out_clear; f2fs_bug_on(sbi, get_dirty_pages(inode)); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 7dc18676f204..2fc48321319f 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -97,6 +97,20 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type) mem_size = (atomic_read(&dcc->discard_cmd_cnt) * sizeof(struct discard_cmd)) >> PAGE_SHIFT; res = mem_size < (avail_ram * nm_i->ram_thresh / 100); + } else if (type == COMPRESS_PAGE) { +#ifdef CONFIG_F2FS_FS_COMPRESSION + unsigned long free_ram = val.freeram; + + /* + * free memory is lower than watermark or cached page count + * exceed threshold, deny caching compress page. + */ + res = (free_ram > avail_ram * sbi->compress_watermark / 100) && + (COMPRESS_MAPPING(sbi)->nrpages < + free_ram * sbi->compress_percent / 100); +#else + res = false; +#endif } else { if (!sbi->sb->s_bdi->wb.dirty_exceeded) return true; diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index d85e8659cfda..84d45385d1f2 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -148,6 +148,7 @@ enum mem_type { EXTENT_CACHE, /* indicates extent cache */ INMEM_PAGES, /* indicates inmemory pages */ DISCARD_CACHE, /* indicates memory of cached discard cmds */ + COMPRESS_PAGE, /* indicates memory of cached compressed pages */ BASE_CHECK, /* check kernel status */ }; diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index d8f8e7f22744..046b00cc7879 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -2322,6 +2322,7 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr) return; invalidate_mapping_pages(META_MAPPING(sbi), addr, addr); + f2fs_invalidate_compress_page(sbi, addr); /* add it into sit main buffer */ down_write(&sit_i->sentry_lock); @@ -3469,9 +3470,11 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) reallocate: f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr, &fio->new_blkaddr, sum, type, fio); - if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO) + if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(fio->sbi), fio->old_blkaddr, fio->old_blkaddr); + f2fs_invalidate_compress_page(fio->sbi, fio->old_blkaddr); + } /* writeout dirty page into bdev */ f2fs_submit_page_write(fio); @@ -3661,6 +3664,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(sbi), old_blkaddr, old_blkaddr); + f2fs_invalidate_compress_page(sbi, old_blkaddr); if (!from_gc) update_segment_mtime(sbi, old_blkaddr, 0); update_sit_entry(sbi, old_blkaddr, -1); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 79c025749303..2e5ced47fb21 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -150,6 +150,7 @@ enum { Opt_compress_extension, Opt_compress_chksum, Opt_compress_mode, + Opt_compress_cache, Opt_atgc, Opt_gc_merge, Opt_nogc_merge, @@ -224,6 +225,7 @@ static match_table_t f2fs_tokens = { {Opt_compress_extension, "compress_extension=%s"}, {Opt_compress_chksum, "compress_chksum"}, {Opt_compress_mode, "compress_mode=%s"}, + {Opt_compress_cache, "compress_cache"}, {Opt_atgc, "atgc"}, {Opt_gc_merge, "gc_merge"}, {Opt_nogc_merge, "nogc_merge"}, @@ -1066,12 +1068,16 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) } kfree(name); break; + case Opt_compress_cache: + set_opt(sbi, COMPRESS_CACHE); + break; #else case Opt_compress_algorithm: case Opt_compress_log_size: case Opt_compress_extension: case Opt_compress_chksum: case Opt_compress_mode: + case Opt_compress_cache: f2fs_info(sbi, "compression options not supported"); break; #endif @@ -1412,6 +1418,8 @@ static void f2fs_put_super(struct super_block *sb) f2fs_bug_on(sbi, sbi->fsync_node_num); + f2fs_destroy_compress_inode(sbi); + iput(sbi->node_inode); sbi->node_inode = NULL; @@ -1681,6 +1689,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq, seq_printf(seq, ",compress_mode=%s", "fs"); else if (F2FS_OPTION(sbi).compress_mode == COMPR_MODE_USER) seq_printf(seq, ",compress_mode=%s", "user"); + + if (test_opt(sbi, COMPRESS_CACHE)) + seq_puts(seq, ",compress_cache"); } #endif @@ -1959,6 +1970,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT); bool no_io_align = !F2FS_IO_ALIGNED(sbi); bool no_atgc = !test_opt(sbi, ATGC); + bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE); bool checkpoint_changed; #ifdef CONFIG_QUOTA int i, j; @@ -2056,6 +2068,12 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; } + if (no_compress_cache == !!test_opt(sbi, COMPRESS_CACHE)) { + err = -EINVAL; + f2fs_warn(sbi, "switch compress_cache option is not allowed"); + goto restore_opts; + } + if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) { err = -EINVAL; f2fs_warn(sbi, "disabling checkpoint not compatible with read-only"); @@ -3965,10 +3983,14 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_node_inode; } - err = f2fs_register_sysfs(sbi); + err = f2fs_init_compress_inode(sbi); if (err) goto free_root_inode; + err = f2fs_register_sysfs(sbi); + if (err) + goto free_compress_inode; + #ifdef CONFIG_QUOTA /* Enable quota usage during mount */ if (f2fs_sb_has_quota_ino(sbi) && !f2fs_readonly(sb)) { @@ -4109,6 +4131,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* evict some inodes being cached by GC */ evict_inodes(sb); f2fs_unregister_sysfs(sbi); +free_compress_inode: + f2fs_destroy_compress_inode(sbi); free_root_inode: dput(sb->s_root); sb->s_root = NULL; @@ -4187,6 +4211,15 @@ static void kill_f2fs_super(struct super_block *sb) f2fs_stop_gc_thread(sbi); f2fs_stop_discard_thread(sbi); +#ifdef CONFIG_F2FS_FS_COMPRESSION + /* + * latter evict_inode() can bypass checking and invalidating + * compress inode cache. + */ + if (test_opt(sbi, COMPRESS_CACHE)) + truncate_inode_pages_final(COMPRESS_MAPPING(sbi)); +#endif + if (is_sbi_flag_set(sbi, SBI_IS_DIRTY) || !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { struct cp_control cpc = { diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index f93000c3a127..d445150c5350 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -34,6 +34,7 @@ #define F2FS_ROOT_INO(sbi) ((sbi)->root_ino_num) #define F2FS_NODE_INO(sbi) ((sbi)->node_ino_num) #define F2FS_META_INO(sbi) ((sbi)->meta_ino_num) +#define F2FS_COMPRESS_INO(sbi) (NM_I(sbi)->max_nid) #define F2FS_MAX_QUOTAS 3 From 34c703ff0470169c9329843c209f0bb3d0ec1f41 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 26 May 2021 14:29:26 +0800 Subject: [PATCH 08/60] f2fs: swap: remove dead codes After commit af4b6b8edf6a ("f2fs: introduce check_swap_activate_fast()"), we will never run into original logic of check_swap_activate() before f2fs supports non 4k-sized page, so let's delete those dead codes. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 168 +------------------------------------------------ 1 file changed, 1 insertion(+), 167 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 26684893ad71..45cb016cab5e 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3841,66 +3841,7 @@ int f2fs_migrate_page(struct address_space *mapping, #endif #ifdef CONFIG_SWAP -static int f2fs_is_file_aligned(struct inode *inode) -{ - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - block_t main_blkaddr = SM_I(sbi)->main_blkaddr; - block_t cur_lblock; - block_t last_lblock; - block_t pblock; - unsigned long nr_pblocks; - unsigned int blocks_per_sec = BLKS_PER_SEC(sbi); - unsigned int not_aligned = 0; - int ret = 0; - - cur_lblock = 0; - last_lblock = bytes_to_blks(inode, i_size_read(inode)); - - while (cur_lblock < last_lblock) { - struct f2fs_map_blocks map; - - memset(&map, 0, sizeof(map)); - map.m_lblk = cur_lblock; - map.m_len = last_lblock - cur_lblock; - map.m_next_pgofs = NULL; - map.m_next_extent = NULL; - map.m_seg_type = NO_CHECK_TYPE; - map.m_may_create = false; - - ret = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_FIEMAP); - if (ret) - goto out; - - /* hole */ - if (!(map.m_flags & F2FS_MAP_FLAGS)) { - f2fs_err(sbi, "Swapfile has holes"); - ret = -ENOENT; - goto out; - } - - pblock = map.m_pblk; - nr_pblocks = map.m_len; - - if ((pblock - main_blkaddr) & (blocks_per_sec - 1) || - nr_pblocks & (blocks_per_sec - 1)) { - if (f2fs_is_pinned_file(inode)) { - f2fs_err(sbi, "Swapfile does not align to section"); - ret = -EINVAL; - goto out; - } - not_aligned++; - } - - cur_lblock += nr_pblocks; - } - if (not_aligned) - f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", - not_aligned); -out: - return ret; -} - -static int check_swap_activate_fast(struct swap_info_struct *sis, +static int check_swap_activate(struct swap_info_struct *sis, struct file *swap_file, sector_t *span) { struct address_space *mapping = swap_file->f_mapping; @@ -3995,113 +3936,6 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, return ret; } -/* Copied from generic_swapfile_activate() to check any holes */ -static int check_swap_activate(struct swap_info_struct *sis, - struct file *swap_file, sector_t *span) -{ - struct address_space *mapping = swap_file->f_mapping; - struct inode *inode = mapping->host; - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - unsigned blocks_per_page; - unsigned long page_no; - sector_t probe_block; - sector_t last_block; - sector_t lowest_block = -1; - sector_t highest_block = 0; - int nr_extents = 0; - int ret = 0; - - if (PAGE_SIZE == F2FS_BLKSIZE) - return check_swap_activate_fast(sis, swap_file, span); - - ret = f2fs_is_file_aligned(inode); - if (ret) - goto out; - - blocks_per_page = bytes_to_blks(inode, PAGE_SIZE); - - /* - * Map all the blocks into the extent list. This code doesn't try - * to be very smart. - */ - probe_block = 0; - page_no = 0; - last_block = bytes_to_blks(inode, i_size_read(inode)); - while ((probe_block + blocks_per_page) <= last_block && - page_no < sis->max) { - unsigned block_in_page; - sector_t first_block; - sector_t block = 0; - - cond_resched(); - - block = probe_block; - ret = bmap(inode, &block); - if (ret) - goto out; - if (!block) - goto bad_bmap; - first_block = block; - - /* - * It must be PAGE_SIZE aligned on-disk - */ - if (first_block & (blocks_per_page - 1)) { - probe_block++; - goto reprobe; - } - - for (block_in_page = 1; block_in_page < blocks_per_page; - block_in_page++) { - - block = probe_block + block_in_page; - ret = bmap(inode, &block); - if (ret) - goto out; - if (!block) - goto bad_bmap; - - if (block != first_block + block_in_page) { - /* Discontiguity */ - probe_block++; - goto reprobe; - } - } - - first_block >>= (PAGE_SHIFT - inode->i_blkbits); - if (page_no) { /* exclude the header page */ - if (first_block < lowest_block) - lowest_block = first_block; - if (first_block > highest_block) - highest_block = first_block; - } - - /* - * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks - */ - ret = add_swap_extent(sis, page_no, 1, first_block); - if (ret < 0) - goto out; - nr_extents += ret; - page_no++; - probe_block += blocks_per_page; -reprobe: - continue; - } - ret = nr_extents; - *span = 1 + highest_block - lowest_block; - if (page_no == 0) - page_no = 1; /* force Empty message */ - sis->max = page_no; - sis->pages = page_no - 1; - sis->highest_bit = page_no - 1; -out: - return ret; -bad_bmap: - f2fs_err(sbi, "Swapfile has holes"); - return -EINVAL; -} - static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file, sector_t *span) { From eaef955b91d10a461eda134c28b3181f92d0a4e0 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 26 May 2021 14:29:27 +0800 Subject: [PATCH 09/60] f2fs: swap: support migrating swapfile in aligned write mode This patch supports to migrate swapfile in aligned write mode during swapon in order to keep swapfile being aligned to section as much as possible, then pinned swapfile will locates fully filled section which may not affected by GC. However, for the case that swapfile's size is not aligned to section size, it will still leave last extent in file's tail as unaligned due to its size is smaller than section size, like case #2. case #1 xfs_io -f /mnt/f2fs/file -c "pwrite 0 4M" -c "fsync" Before swapon: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..3047]: 1123352..1126399 3048 0x1000 1: [3048..7143]: 237568..241663 4096 0x1000 2: [7144..8191]: 245760..246807 1048 0x1001 After swapon: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..8191]: 249856..258047 8192 0x1001 Kmsg: F2FS-fs (zram0): Swapfile (2) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(2097152 * n) case #2 xfs_io -f /mnt/f2fs/file -c "pwrite 0 3M" -c "fsync" Before swapon: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..3047]: 246808..249855 3048 0x1000 1: [3048..6143]: 237568..240663 3096 0x1001 After swapon: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..4095]: 258048..262143 4096 0x1000 1: [4096..6143]: 238616..240663 2048 0x1001 Kmsg: F2FS-fs (zram0): Swapfile: last extent is not aligned to section F2FS-fs (zram0): Swapfile (2) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(2097152 * n) Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 108 ++++++++++++++++++++++++++++++++++++++++------ fs/f2fs/f2fs.h | 1 + fs/f2fs/node.h | 3 ++ fs/f2fs/segment.c | 3 ++ 4 files changed, 101 insertions(+), 14 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 45cb016cab5e..23f020a1859a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2483,6 +2483,10 @@ static inline bool check_inplace_update_policy(struct inode *inode, bool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio) { + /* swap file is migrating in aligned write mode */ + if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) + return false; + if (f2fs_is_pinned_file(inode)) return true; @@ -2505,6 +2509,11 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) return true; if (f2fs_is_atomic_file(inode)) return true; + + /* swap file is migrating in aligned write mode */ + if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) + return true; + if (fio) { if (page_private_gcing(fio->page)) return true; @@ -3841,6 +3850,65 @@ int f2fs_migrate_page(struct address_space *mapping, #endif #ifdef CONFIG_SWAP +static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, + unsigned int blkcnt) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + unsigned int blkofs; + unsigned int blk_per_sec = BLKS_PER_SEC(sbi); + unsigned int secidx = start_blk / blk_per_sec; + unsigned int end_sec = secidx + blkcnt / blk_per_sec; + int ret = 0; + + down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + down_write(&F2FS_I(inode)->i_mmap_sem); + + set_inode_flag(inode, FI_ALIGNED_WRITE); + + for (; secidx < end_sec; secidx++) { + down_write(&sbi->pin_sem); + + f2fs_lock_op(sbi); + f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); + f2fs_unlock_op(sbi); + + set_inode_flag(inode, FI_DO_DEFRAG); + + for (blkofs = 0; blkofs < blk_per_sec; blkofs++) { + struct page *page; + unsigned int blkidx = secidx * blk_per_sec + blkofs; + + page = f2fs_get_lock_data_page(inode, blkidx, true); + if (IS_ERR(page)) { + up_write(&sbi->pin_sem); + ret = PTR_ERR(page); + goto done; + } + + set_page_dirty(page); + f2fs_put_page(page, 1); + } + + clear_inode_flag(inode, FI_DO_DEFRAG); + + ret = filemap_fdatawrite(inode->i_mapping); + + up_write(&sbi->pin_sem); + + if (ret) + break; + } + +done: + clear_inode_flag(inode, FI_DO_DEFRAG); + clear_inode_flag(inode, FI_ALIGNED_WRITE); + + up_write(&F2FS_I(inode)->i_mmap_sem); + up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + + return ret; +} + static int check_swap_activate(struct swap_info_struct *sis, struct file *swap_file, sector_t *span) { @@ -3854,7 +3922,8 @@ static int check_swap_activate(struct swap_info_struct *sis, sector_t highest_pblock = 0; int nr_extents = 0; unsigned long nr_pblocks; - unsigned int blocks_per_sec = BLKS_PER_SEC(sbi); + unsigned int blks_per_sec = BLKS_PER_SEC(sbi); + unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1; unsigned int not_aligned = 0; int ret = 0; @@ -3867,7 +3936,7 @@ static int check_swap_activate(struct swap_info_struct *sis, while (cur_lblock < last_lblock && cur_lblock < sis->max) { struct f2fs_map_blocks map; - +retry: cond_resched(); memset(&map, 0, sizeof(map)); @@ -3892,16 +3961,28 @@ static int check_swap_activate(struct swap_info_struct *sis, pblock = map.m_pblk; nr_pblocks = map.m_len; - if ((pblock - SM_I(sbi)->main_blkaddr) & (blocks_per_sec - 1) || - nr_pblocks & (blocks_per_sec - 1)) { - if (f2fs_is_pinned_file(inode)) { - f2fs_err(sbi, "Swapfile does not align to section"); - ret = -EINVAL; - goto out; - } + if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask || + nr_pblocks & sec_blks_mask) { not_aligned++; - } + nr_pblocks = roundup(nr_pblocks, blks_per_sec); + if (cur_lblock + nr_pblocks > sis->max) + nr_pblocks -= blks_per_sec; + + if (!nr_pblocks) { + /* this extent is last one */ + nr_pblocks = map.m_len; + f2fs_warn(sbi, "Swapfile: last extent is not aligned to section"); + goto next; + } + + ret = f2fs_migrate_blocks(inode, cur_lblock, + nr_pblocks); + if (ret) + goto out; + goto retry; + } +next: if (cur_lblock + nr_pblocks >= sis->max) nr_pblocks = sis->max - cur_lblock; @@ -3928,11 +4009,10 @@ static int check_swap_activate(struct swap_info_struct *sis, sis->max = cur_lblock; sis->pages = cur_lblock - 1; sis->highest_bit = cur_lblock - 1; - - if (not_aligned) - f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", - not_aligned); out: + if (not_aligned) + f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(%u * N)", + not_aligned, blks_per_sec * F2FS_BLKSIZE); return ret; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 1c09fcbb4e12..8db6af75bdc3 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -709,6 +709,7 @@ enum { FI_MMAP_FILE, /* indicate file was mmapped */ FI_ENABLE_COMPRESS, /* enable compression in "user" compression mode */ FI_COMPRESS_RELEASED, /* compressed blocks were released */ + FI_ALIGNED_WRITE, /* enable aligned write */ FI_MAX, /* max flag, never be used */ }; diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 84d45385d1f2..ff14a6e5ac1c 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -38,6 +38,9 @@ /* return value for read_node_page */ #define LOCKED_PAGE 1 +/* check pinned file's alignment status of physical blocks */ +#define FILE_NOT_ALIGNED 1 + /* For flag in struct node_info */ enum { IS_CHECKPOINTED, /* is it checkpointed before? */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 046b00cc7879..996f7667f0cb 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3291,6 +3291,9 @@ static int __get_segment_type_6(struct f2fs_io_info *fio) if (fio->type == DATA) { struct inode *inode = fio->page->mapping->host; + if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) + return CURSEG_COLD_DATA_PINNED; + if (page_private_gcing(fio->page)) { if (fio->sbi->am.atgc_enabled && (fio->io_type == FS_DATA_IO) && From 44e0be85eb6b89588fd7db6eb5e606c19978d815 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 11 Jun 2021 07:46:30 +0800 Subject: [PATCH 10/60] f2fs: introduce f2fs_casefolded_name slab cache Add a slab cache: "f2fs_casefolded_name" for memory allocation of casefold name. Reviewed-by: Eric Biggers Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 17 +++++++++++------ fs/f2fs/recovery.c | 6 +++++- fs/f2fs/super.c | 24 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 4cf07050fefe..2d93dc257ea1 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -16,6 +16,10 @@ #include "xattr.h" #include +#ifdef CONFIG_UNICODE +extern struct kmem_cache *f2fs_cf_name_slab; +#endif + static unsigned long dir_blocks(struct inode *inode) { return ((unsigned long long) (i_size_read(inode) + PAGE_SIZE - 1)) @@ -77,11 +81,10 @@ int f2fs_init_casefolded_name(const struct inode *dir, { #ifdef CONFIG_UNICODE struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); if (IS_CASEFOLDED(dir)) { - fname->cf_name.name = f2fs_kmalloc(sbi, F2FS_NAME_LEN, - GFP_NOFS); + fname->cf_name.name = kmem_cache_alloc(f2fs_cf_name_slab, + GFP_NOFS); if (!fname->cf_name.name) return -ENOMEM; fname->cf_name.len = utf8_casefold(sb->s_encoding, @@ -89,7 +92,7 @@ int f2fs_init_casefolded_name(const struct inode *dir, fname->cf_name.name, F2FS_NAME_LEN); if ((int)fname->cf_name.len <= 0) { - kfree(fname->cf_name.name); + kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); fname->cf_name.name = NULL; if (sb_has_strict_encoding(sb)) return -EINVAL; @@ -172,8 +175,10 @@ void f2fs_free_filename(struct f2fs_filename *fname) fname->crypto_buf.name = NULL; #endif #ifdef CONFIG_UNICODE - kfree(fname->cf_name.name); - fname->cf_name.name = NULL; + if (fname->cf_name.name) { + kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); + fname->cf_name.name = NULL; + } #endif } diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 4cfe36fa41be..76e62771433c 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -45,6 +45,10 @@ static struct kmem_cache *fsync_entry_slab; +#ifdef CONFIG_UNICODE +extern struct kmem_cache *f2fs_cf_name_slab; +#endif + bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi) { s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count); @@ -145,7 +149,7 @@ static int init_recovered_filename(const struct inode *dir, f2fs_hash_filename(dir, fname); #ifdef CONFIG_UNICODE /* Case-sensitive match is fine for recovery */ - kfree(fname->cf_name.name); + kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); fname->cf_name.name = NULL; #endif } else { diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2e5ced47fb21..eb376e7e71a3 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -277,6 +277,24 @@ static int f2fs_sb_read_encoding(const struct f2fs_super_block *sb, return 0; } + +struct kmem_cache *f2fs_cf_name_slab; +static int __init f2fs_create_casefold_cache(void) +{ + f2fs_cf_name_slab = f2fs_kmem_cache_create("f2fs_casefolded_name", + F2FS_NAME_LEN); + if (!f2fs_cf_name_slab) + return -ENOMEM; + return 0; +} + +static void f2fs_destroy_casefold_cache(void) +{ + kmem_cache_destroy(f2fs_cf_name_slab); +} +#else +static int __init f2fs_create_casefold_cache(void) { return 0; } +static void f2fs_destroy_casefold_cache(void) { } #endif static inline void limit_reserve_root(struct f2fs_sb_info *sbi) @@ -4319,7 +4337,12 @@ static int __init init_f2fs_fs(void) err = f2fs_init_compress_cache(); if (err) goto free_compress_mempool; + err = f2fs_create_casefold_cache(); + if (err) + goto free_compress_cache; return 0; +free_compress_cache: + f2fs_destroy_compress_cache(); free_compress_mempool: f2fs_destroy_compress_mempool(); free_bioset: @@ -4355,6 +4378,7 @@ static int __init init_f2fs_fs(void) static void __exit exit_f2fs_fs(void) { + f2fs_destroy_casefold_cache(); f2fs_destroy_compress_cache(); f2fs_destroy_compress_mempool(); f2fs_destroy_bioset(); From 15a475975ec97f6d983fb58a51e9ae60baf7f31a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 8 Jun 2021 07:31:22 +0800 Subject: [PATCH 11/60] f2fs: fix to avoid adding tab before doc section Otherwise whole section after tab will be invisible in compiled html format document. Cc: Mauro Carvalho Chehab Fixes: 89272ca1102e ("docs: filesystems: convert f2fs.txt to ReST") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index 809c4d0a696f..b91e5a8444d5 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -720,10 +720,10 @@ users. ===================== ======================== =================== User F2FS Block ===================== ======================== =================== - META WRITE_LIFE_NOT_SET - HOT_NODE " - WARM_NODE " - COLD_NODE " +N/A META WRITE_LIFE_NOT_SET +N/A HOT_NODE " +N/A WARM_NODE " +N/A COLD_NODE " ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME extension list " " @@ -749,10 +749,10 @@ WRITE_LIFE_LONG " WRITE_LIFE_LONG ===================== ======================== =================== User F2FS Block ===================== ======================== =================== - META WRITE_LIFE_MEDIUM; - HOT_NODE WRITE_LIFE_NOT_SET - WARM_NODE " - COLD_NODE WRITE_LIFE_NONE +N/A META WRITE_LIFE_MEDIUM; +N/A HOT_NODE WRITE_LIFE_NOT_SET +N/A WARM_NODE " +N/A COLD_NODE WRITE_LIFE_NONE ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME extension list " " From cdeff03989baaeacd6fffbc864036509b487558e Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Tue, 15 Jun 2021 15:39:04 -0700 Subject: [PATCH 12/60] f2fs: enable extent cache for compression files in read-only Let's allow extent cache for RO partition. Signed-off-by: Daeho Jeong Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 8db6af75bdc3..ea6ae1ae5487 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3148,25 +3148,6 @@ static inline bool is_dot_dotdot(const u8 *name, size_t len) return false; } -static inline bool f2fs_may_extent_tree(struct inode *inode) -{ - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - - if (!test_opt(sbi, EXTENT_CACHE) || - is_inode_flag_set(inode, FI_NO_EXTENT) || - is_inode_flag_set(inode, FI_COMPRESSED_FILE)) - return false; - - /* - * for recovered files during mount do not create extents - * if shrinker is not registered. - */ - if (list_empty(&sbi->s_list)) - return false; - - return S_ISREG(inode->i_mode); -} - static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi, size_t size, gfp_t flags) { @@ -4197,6 +4178,26 @@ F2FS_FEATURE_FUNCS(casefold, CASEFOLD); F2FS_FEATURE_FUNCS(compression, COMPRESSION); F2FS_FEATURE_FUNCS(readonly, RO); +static inline bool f2fs_may_extent_tree(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + + if (!test_opt(sbi, EXTENT_CACHE) || + is_inode_flag_set(inode, FI_NO_EXTENT) || + (is_inode_flag_set(inode, FI_COMPRESSED_FILE) && + !f2fs_sb_has_readonly(sbi))) + return false; + + /* + * for recovered files during mount do not create extents + * if shrinker is not registered. + */ + if (list_empty(&sbi->s_list)) + return false; + + return S_ISREG(inode->i_mode); +} + #ifdef CONFIG_BLK_DEV_ZONED static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi, block_t blkaddr) From c81ac64da10f0d3562528d4de6d8ca187d8834d4 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 22 Jun 2021 12:56:44 -0700 Subject: [PATCH 13/60] f2fs: remove false alarm on iget failure during GC This patch removes setting SBI_NEED_FSCK when GC gets an error on f2fs_iget, since f2fs_iget can give ENOMEM and others by race condition. If we set this critical fsck flag, we'll get EIO during fsync via the below code path. In f2fs_inplace_write_data(), if (is_sbi_flag_set(sbi, SBI_NEED_FSCK) || f2fs_cp_error(sbi)) { err = -EIO; goto drop_bio; } Fixes: 9557727876674 ("f2fs: drop inplace IO if fs status is abnormal") Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index da5947b30142..0e42ee5f7770 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1451,10 +1451,8 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (phase == 3) { inode = f2fs_iget(sb, dni.ino); - if (IS_ERR(inode) || is_bad_inode(inode)) { - set_sbi_flag(sbi, SBI_NEED_FSCK); + if (IS_ERR(inode) || is_bad_inode(inode)) continue; - } if (!down_write_trylock( &F2FS_I(inode)->i_gc_rwsem[WRITE])) { From bb51a331824e70cbc89479ea4d78dfb70e2a02bc Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Jun 2021 01:42:05 -0700 Subject: [PATCH 14/60] Revert "f2fs: avoid attaching SB_ACTIVE flag during mount/remount" This reverts commit 42bbf0bcc2a57eca1323976af8ebbe58d13cb4e2. --- fs/f2fs/checkpoint.c | 3 +++ fs/f2fs/recovery.c | 8 ++++++-- fs/f2fs/super.c | 11 +++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 3497bac4c53d..23d36de40317 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -691,6 +691,9 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) } #ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sbi->sb->s_flags |= SB_ACTIVE; + /* * Turn on quotas which were not enabled for read-only mounts if * filesystem has quota feature, so that they are updated correctly. diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 76e62771433c..695eacfe776c 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -786,6 +786,8 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) } #ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sbi->sb->s_flags |= SB_ACTIVE; /* Turn on quotas so that they are updated correctly */ quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY); #endif @@ -813,8 +815,10 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) err = recover_data(sbi, &inode_list, &tmp_inode_list, &dir_list); if (!err) f2fs_bug_on(sbi, !list_empty(&inode_list)); - else - f2fs_bug_on(sbi, sbi->sb->s_flags & SB_ACTIVE); + else { + /* restore s_flags to let iput() trash data */ + sbi->sb->s_flags = s_flags; + } skip: fix_curseg_write_pointer = !check_only || list_empty(&inode_list); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index eb376e7e71a3..6d2eba662b84 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1908,15 +1908,17 @@ static int f2fs_enable_quotas(struct super_block *sb); static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) { + unsigned int s_flags = sbi->sb->s_flags; struct cp_control cpc; int err = 0; int ret; block_t unusable; - if (sbi->sb->s_flags & SB_RDONLY) { + if (s_flags & SB_RDONLY) { f2fs_err(sbi, "checkpoint=disable on readonly fs"); return -EINVAL; } + sbi->sb->s_flags |= SB_ACTIVE; f2fs_update_time(sbi, DISABLE_TIME); @@ -1934,13 +1936,13 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) ret = sync_filesystem(sbi->sb); if (ret || err) { err = ret ? ret : err; - goto out; + goto restore_flag; } unusable = f2fs_get_unusable_blocks(sbi); if (f2fs_disable_cp_again(sbi, unusable)) { err = -EAGAIN; - goto out; + goto restore_flag; } down_write(&sbi->gc_lock); @@ -1956,7 +1958,8 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) out_unlock: up_write(&sbi->gc_lock); -out: +restore_flag: + sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */ return err; } From 9d55580966da3a812780156da2878cd46d8b3548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bram=20Bonn=C3=A9?= Date: Fri, 30 Apr 2021 11:50:19 +0200 Subject: [PATCH 15/60] ANDROID: selinux: modify RTM_GETNEIGH{TBL} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Map the permission gating RTM_GETNEIGH/RTM_GETNEIGHTBL messages to a new permission so that it can be distinguished from the other netlink route permissions in selinux policy. The new permission is triggered by a flag set in system images T and up. This change is intended to be backported to all kernels that a T system image can run on top of. Bug: 171572148 Test: atest NetworkInterfaceTest Test: atest CtsSelinuxTargetSdkCurrentTestCases Test: atest bionic-unit-tests-static Test: On Cuttlefish, run combinations of: - Policy bit set or omitted (see https://r.android.com/1701847) - This patch applied or omitted - App having nlmsg_readneigh permission or not Verify that only the combination of this patch + the policy bit being set + the app not having the nlmsg_readneigh permission prevents the app from sending RTM_GETNEIGH messages. Change-Id: I4bcfce4decb34ea9388eeedfc4be67403de8a980 Signed-off-by: Bram Bonné (cherry picked from commit fac07550bdac9adea0dbe3edbdbec7a9a690a178) --- security/selinux/include/classmap.h | 3 ++- security/selinux/include/security.h | 8 ++++++++ security/selinux/nlmsgtab.c | 24 ++++++++++++++++++++---- security/selinux/ss/policydb.c | 4 ++++ security/selinux/ss/policydb.h | 2 ++ security/selinux/ss/services.c | 1 + 6 files changed, 37 insertions(+), 5 deletions(-) diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index f3ad0a7facfa..955e8c8389cd 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -117,7 +117,8 @@ struct security_class_mapping secclass_map[] = { { COMMON_IPC_PERMS, NULL } }, { "netlink_route_socket", { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", "nlmsg_readpriv", NULL } }, + "nlmsg_read", "nlmsg_write", "nlmsg_readpriv", "nlmsg_getneigh", + NULL } }, { "netlink_tcpdiag_socket", { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", NULL } }, diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 0f7e1aeaba11..a2c0cf6293ca 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -98,6 +98,7 @@ struct selinux_state { bool initialized; bool policycap[__POLICYDB_CAPABILITY_MAX]; bool android_netlink_route; + bool android_netlink_getneigh; struct page *status_page; struct mutex status_lock; @@ -227,6 +228,13 @@ static inline bool selinux_android_nlroute_getlink(void) return state->android_netlink_route; } +static inline bool selinux_android_nlroute_getneigh(void) +{ + struct selinux_state *state = &selinux_state; + + return state->android_netlink_getneigh; +} + struct selinux_policy_convert_data; struct selinux_load_state { diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 7968c2e45e39..9ad6f9b893f5 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -212,12 +212,12 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) return err; } -static void nlmsg_set_getlink_perm(u32 perm) +static void nlmsg_set_perm_for_type(u32 perm, u16 type) { int i; for (i = 0; i < ARRAY_SIZE(nlmsg_route_perms); i++) { - if (nlmsg_route_perms[i].nlmsg_type == RTM_GETLINK) { + if (nlmsg_route_perms[i].nlmsg_type == type) { nlmsg_route_perms[i].perm = perm; break; } @@ -227,11 +227,27 @@ static void nlmsg_set_getlink_perm(u32 perm) /** * Use nlmsg_readpriv as the permission for RTM_GETLINK messages if the * netlink_route_getlink policy capability is set. Otherwise use nlmsg_read. + * Similarly, use nlmsg_getneigh for RTM_GETNEIGH and RTM_GETNEIGHTBL if the + * netlink_route_getneigh policy capability is set. Otherwise use nlmsg_read. */ void selinux_nlmsg_init(void) { if (selinux_android_nlroute_getlink()) - nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV, + RTM_GETLINK); else - nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READ); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ, + RTM_GETLINK); + + if (selinux_android_nlroute_getneigh()) { + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_GETNEIGH, + RTM_GETNEIGH); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_GETNEIGH, + RTM_GETNEIGHTBL); + } else { + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ, + RTM_GETNEIGH); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ, + RTM_GETNEIGHTBL); + } } diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index ff5cc4b3f3c0..572370c71af5 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -2497,6 +2497,10 @@ int policydb_read(struct policydb *p, void *fp) p->android_netlink_route = 1; } + if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH)) { + p->android_netlink_getneigh = 1; + } + if (p->policyvers >= POLICYDB_VERSION_POLCAP) { rc = ebitmap_read(&p->policycaps, fp); if (rc) diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 6bedec43aa0b..be9988ebfa1b 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -239,6 +239,7 @@ struct genfs { struct policydb { int mls_enabled; int android_netlink_route; + int android_netlink_getneigh; /* symbol tables */ struct symtab symtab[SYM_NUM]; @@ -336,6 +337,7 @@ extern struct role_trans_datum *policydb_roletr_search( #define POLICYDB_CONFIG_MLS 1 #define POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE (1 << 31) +#define POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH (1 << 30) /* the config flags related to unknown classes/perms are bits 2 and 3 */ #define REJECT_UNKNOWN 0x00000002 diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b70abc68aa19..a2fcde88ce0f 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2162,6 +2162,7 @@ static void security_load_policycaps(struct selinux_state *state, } state->android_netlink_route = p->android_netlink_route; + state->android_netlink_getneigh = p->android_netlink_getneigh; selinux_nlmsg_init(); } From 728626cb04aa17ba0a3f08d027fa7fa933bf57fa Mon Sep 17 00:00:00 2001 From: heshuai1 Date: Thu, 10 Jun 2021 15:46:59 +0800 Subject: [PATCH 16/60] ANDROID: power: Add vendor hook to qos for GKI purpose. Add the vendor hook to qos.c, because of some special cases related to our feature. we add the hook at freq_qos_add_request and remove_request to make sure we can go to our own qos process logic. Bug: 187458531 Signed-off-by: heshuai1 Change-Id: I1fb8fd6134432ecfb44ad242c66ccd8280ab9b43 --- drivers/android/vendor_hooks.c | 3 +++ include/trace/hooks/power.h | 17 +++++++++++++++++ kernel/power/qos.c | 6 ++++++ 3 files changed, 26 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index aa21aa87ef67..2cff702df817 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -321,6 +321,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_force_compatible_pre); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_force_compatible_post); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_uid); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_user); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_add_request); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_update_request); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_remove_request); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_balance_anon_file_reclaim); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_enter); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_exit); diff --git a/include/trace/hooks/power.h b/include/trace/hooks/power.h index 049c8995932d..149ea08580b8 100644 --- a/include/trace/hooks/power.h +++ b/include/trace/hooks/power.h @@ -20,6 +20,23 @@ DECLARE_HOOK(android_vh_try_to_freeze_todo_unfrozen, TP_PROTO(struct task_struct *p), TP_ARGS(p)); +enum freq_qos_req_type; +struct freq_qos_request; +struct freq_constraints; + +DECLARE_HOOK(android_vh_freq_qos_add_request, + TP_PROTO(struct freq_constraints *qos, struct freq_qos_request *req, + enum freq_qos_req_type type, int value, int ret), + TP_ARGS(qos, req, type, value, ret)); + +DECLARE_HOOK(android_vh_freq_qos_update_request, + TP_PROTO(struct freq_qos_request *req, int value), + TP_ARGS(req, value)); + +DECLARE_HOOK(android_vh_freq_qos_remove_request, + TP_PROTO(struct freq_qos_request *req), + TP_ARGS(req)); + /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_POWER_H */ diff --git a/kernel/power/qos.c b/kernel/power/qos.c index ec7e1e85923e..8da76f9baca2 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -38,6 +38,9 @@ #include #include #include +#undef CREATE_TRACE_POINT +#include + /* * locking rule: all changes to constraints or notifiers lists @@ -546,6 +549,7 @@ int freq_qos_add_request(struct freq_constraints *qos, req->type = 0; } + trace_android_vh_freq_qos_add_request(qos, req, type, value, ret); return ret; } EXPORT_SYMBOL_GPL(freq_qos_add_request); @@ -570,6 +574,7 @@ int freq_qos_update_request(struct freq_qos_request *req, s32 new_value) "%s() called for unknown object\n", __func__)) return -EINVAL; + trace_android_vh_freq_qos_update_request(req, new_value); if (req->pnode.prio == new_value) return 0; @@ -598,6 +603,7 @@ int freq_qos_remove_request(struct freq_qos_request *req) "%s() called for unknown object\n", __func__)) return -EINVAL; + trace_android_vh_freq_qos_remove_request(req); ret = freq_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); req->qos = NULL; req->type = 0; From 77c9f446b68c6193297ae6ce0b8ee0e8c918d621 Mon Sep 17 00:00:00 2001 From: Rohan Sethi Date: Wed, 23 Jun 2021 19:33:51 +0530 Subject: [PATCH 17/60] ANDROID: GKI: Update abi_gki_aarch64_qcom list for shmem allocations Add support for shmem allocations in kernel. Update allowed list with symbols for the feature implementation. Leaf changes summary: 2 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 2 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 2 Added functions: [A] 'function struct file* shmem_file_setup(const char*, loff_t, unsigned long) [A] 'function struct page* shmem_read_mapping_page_gfp( struct address_space*, pgoff_t, gfp_t) Bug: 191813051 Change-Id: I4ca5f36cfac146695b64739b426df71834789d9f Signed-off-by: Rohan Sethi --- android/abi_gki_aarch64.xml | 229 ++++++++++++++++++----------------- android/abi_gki_aarch64_qcom | 2 + 2 files changed, 120 insertions(+), 111 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 1aaa9f281ff0..6f16d3f2df7e 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -3666,6 +3666,7 @@ + @@ -59242,44 +59243,44 @@ - - + + - - - + + + - - - - - + + + + + - - - + + + - - - + + + - - + + - - - - + + + + - - + + @@ -59287,69 +59288,69 @@ - - + + - - - - + + + + - - + + - - + + - - + + - - - + + + - - + + - - - + + + - - - - - + + + + + - - - + + + - - - - - + + + + + - - - + + + - - - + + + @@ -115528,8 +115529,8 @@ - - + + @@ -115537,9 +115538,9 @@ - - - + + + @@ -115559,8 +115560,8 @@ - - + + @@ -115586,16 +115587,16 @@ - - + + - - + + - - + + @@ -115633,9 +115634,9 @@ - - - + + + @@ -115643,8 +115644,8 @@ - - + + @@ -115657,9 +115658,9 @@ - - - + + + @@ -167619,6 +167620,12 @@ + + + + + + @@ -167816,34 +167823,34 @@ - - - + + + - - + + - - - - + + + + - - - + + + - - - + + + - - - + + + @@ -173428,7 +173435,7 @@ - + @@ -173640,7 +173647,7 @@ - + @@ -173820,7 +173827,7 @@ - + @@ -174020,7 +174027,7 @@ - + @@ -174474,7 +174481,7 @@ - + @@ -174807,7 +174814,7 @@ - + @@ -174938,7 +174945,7 @@ - + @@ -174946,12 +174953,12 @@ - + - + diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index a7d889fdaadf..a12b3668fd7e 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -2131,7 +2131,9 @@ sg_pcopy_from_buffer sg_pcopy_to_buffer sg_scsi_ioctl + shmem_file_setup shmem_mark_page_lazyfree + shmem_read_mapping_page_gfp shmem_truncate_range show_rcu_gp_kthreads show_regs From 08327b90075eeab3cb94088230a53c00c4357b99 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 17 Nov 2020 14:37:59 +0000 Subject: [PATCH 18/60] FROMLIST: genirq: Add __irq_modify_status() helper to clear/set special flags Some arch-specific flags need to be set/cleared, but not exposed to random device drivers. Introduce a new helper (__irq_modify_status()) that takes an arbitrary mask, and rewrite irq_modify_status() to use this new helper. No functionnal change. Bug: 191808738 Link: https://lore.kernel.org/lkml/20201124141449.572446-5-maz@kernel.org/ Change-Id: I2c2c0d6599d0ab39fad22462bf4c87694362fba8 Signed-off-by: Marc Zyngier [minor port to 5.10] Signed-off-by: Stephen Dickey --- include/linux/irq.h | 3 +++ kernel/irq/chip.c | 12 ++++++++++-- kernel/irq/settings.h | 10 ++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/linux/irq.h b/include/linux/irq.h index a36d35c25996..7c80b10cec59 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -751,6 +751,9 @@ void irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle, void *data); +void __irq_modify_status(unsigned int irq, unsigned long clr, + unsigned long set, unsigned long mask); + void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set); static inline void irq_set_status_flags(unsigned int irq, unsigned long set) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 9e385bd90552..37fbb3076174 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1122,7 +1122,8 @@ irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, } EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name); -void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) +void __irq_modify_status(unsigned int irq, unsigned long clr, + unsigned long set, unsigned long mask) { unsigned long flags, trigger, tmp; struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); @@ -1136,7 +1137,9 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) */ WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN)); - irq_settings_clr_and_set(desc, clr, set); + /* Warn when trying to clear or set a bit disallowed by the mask */ + WARN_ON((clr | set) & ~mask); + __irq_settings_clr_and_set(desc, clr, set, mask); trigger = irqd_get_trigger_type(&desc->irq_data); @@ -1159,6 +1162,11 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) irq_put_desc_unlock(desc, flags); } + +void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) +{ + __irq_modify_status(irq, clr, set, _IRQF_MODIFY_MASK); +} EXPORT_SYMBOL_GPL(irq_modify_status); /** diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h index 403378b9947b..51acdf43eadc 100644 --- a/kernel/irq/settings.h +++ b/kernel/irq/settings.h @@ -36,11 +36,17 @@ enum { #undef IRQF_MODIFY_MASK #define IRQF_MODIFY_MASK GOT_YOU_MORON +static inline void +__irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set, u32 mask) +{ + desc->status_use_accessors &= ~(clr & mask); + desc->status_use_accessors |= (set & mask); +} + static inline void irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set) { - desc->status_use_accessors &= ~(clr & _IRQF_MODIFY_MASK); - desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK); + __irq_settings_clr_and_set(desc, clr, set, _IRQF_MODIFY_MASK); } static inline bool irq_settings_is_per_cpu(struct irq_desc *desc) From 3f9d45d8021df4739103db8f902f588782c4f81b Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 20 Oct 2020 15:36:33 +0100 Subject: [PATCH 19/60] FROMLIST: genirq: Allow an interrupt to be marked as 'raw' Some interrupts (such as the rescheduling IPI) rely on not going through the irq_enter()/irq_exit() calls. To distinguish such interrupts, add a new IRQ flag that allows the low-level handling code to sidestep the enter()/exit() calls. Only the architecture code is expected to use this. It will do the wrong thing on normal interrupts. Note that this is a band-aid until we can move to some more correct infrastructure (such as kernel/entry/common.c). Bug: 191808738 Link: https://lore.kernel.org/lkml/20201124141449.572446-3-maz@kernel.org/ Change-Id: I0609a8b689219ba9e769c8b9f7fcf1e77a0ff1ca Signed-off-by: Marc Zyngier [minor port to 5.10] Signed-off-by: Stephen Dickey --- include/linux/irq.h | 2 ++ kernel/irq/Kconfig | 3 +++ kernel/irq/debugfs.c | 1 + kernel/irq/irqdesc.c | 19 +++++++++++++------ kernel/irq/settings.h | 15 +++++++++++++++ 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/include/linux/irq.h b/include/linux/irq.h index 7c80b10cec59..a29a6de8090d 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -72,6 +72,7 @@ enum irqchip_irq_state; * mechanism and from core side polling. * IRQ_DISABLE_UNLAZY - Disable lazy irq disable * IRQ_HIDDEN - Don't show up in /proc/interrupts + * IRQ_RAW - Skip tick management and irqtime accounting */ enum { IRQ_TYPE_NONE = 0x00000000, @@ -99,6 +100,7 @@ enum { IRQ_IS_POLLED = (1 << 18), IRQ_DISABLE_UNLAZY = (1 << 19), IRQ_HIDDEN = (1 << 20), + IRQ_RAW = (1 << 21), }; #define IRQF_MODIFY_MASK \ diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 164a031cfdb6..ae9b13d5ee91 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -109,6 +109,9 @@ config GENERIC_IRQ_MATRIX_ALLOCATOR config GENERIC_IRQ_RESERVATION_MODE bool +config ARCH_WANTS_IRQ_RAW + bool + # Support forced irq threading config IRQ_FORCED_THREADING bool diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c index e4cff358b437..f53475d88072 100644 --- a/kernel/irq/debugfs.c +++ b/kernel/irq/debugfs.c @@ -140,6 +140,7 @@ static const struct irq_bit_descr irqdesc_states[] = { BIT_MASK_DESCR(_IRQ_IS_POLLED), BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY), BIT_MASK_DESCR(_IRQ_HIDDEN), + BIT_MASK_DESCR(_IRQ_RAW), }; static const struct irq_bit_descr irqdesc_istates[] = { diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 86315fc9356a..aa636e19ea59 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -667,10 +667,9 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, { struct pt_regs *old_regs = set_irq_regs(regs); unsigned int irq = hwirq; + struct irq_desc *desc; int ret = 0; - irq_enter(); - #ifdef CONFIG_IRQ_DOMAIN if (lookup) irq = irq_find_mapping(domain, hwirq); @@ -680,14 +679,22 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. */ - if (unlikely(!irq || irq >= nr_irqs)) { + if (unlikely(!irq || irq >= nr_irqs || !(desc = irq_to_desc(irq)))) { ack_bad_irq(irq); ret = -EINVAL; - } else { - generic_handle_irq(irq); + goto out; } - irq_exit(); + if (IS_ENABLED(CONFIG_ARCH_WANTS_IRQ_RAW) && + unlikely(irq_settings_is_raw(desc))) { + generic_handle_irq_desc(desc); + } else { + irq_enter(); + generic_handle_irq_desc(desc); + irq_exit(); + } + +out: set_irq_regs(old_regs); return ret; } diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h index 51acdf43eadc..0033d459fdac 100644 --- a/kernel/irq/settings.h +++ b/kernel/irq/settings.h @@ -18,6 +18,7 @@ enum { _IRQ_IS_POLLED = IRQ_IS_POLLED, _IRQ_DISABLE_UNLAZY = IRQ_DISABLE_UNLAZY, _IRQ_HIDDEN = IRQ_HIDDEN, + _IRQ_RAW = IRQ_RAW, _IRQF_MODIFY_MASK = IRQF_MODIFY_MASK, }; @@ -33,6 +34,7 @@ enum { #define IRQ_IS_POLLED GOT_YOU_MORON #define IRQ_DISABLE_UNLAZY GOT_YOU_MORON #define IRQ_HIDDEN GOT_YOU_MORON +#define IRQ_RAW GOT_YOU_MORON #undef IRQF_MODIFY_MASK #define IRQF_MODIFY_MASK GOT_YOU_MORON @@ -180,3 +182,16 @@ static inline bool irq_settings_is_hidden(struct irq_desc *desc) { return desc->status_use_accessors & _IRQ_HIDDEN; } + +static inline bool irq_settings_is_raw(struct irq_desc *desc) +{ + if (IS_ENABLED(CONFIG_ARCH_WANTS_IRQ_RAW)) + return desc->status_use_accessors & _IRQ_RAW; + + /* + * Using IRQ_RAW on architectures that don't expect it is + * likely to be wrong. + */ + WARN_ON_ONCE(1); + return false; +} From 42f775df7290a84151220f3e705f7bc2c27027eb Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 20 Oct 2020 15:37:04 +0100 Subject: [PATCH 20/60] FROMLIST: arm64: Mark the recheduling IPI as raw interrupt Flag the rescheduling IPI as 'raw', making sure such interrupt skips both tick management and irqtime accounting. Bug: 191808738 Link: https://lore.kernel.org/lkml/20201124141449.572446-4-maz@kernel.org/ Change-Id: Ibeda817de7618a98d457d09a6fa7e54f867b72f0 Signed-off-by: Marc Zyngier [minor port to 5.10] Signed-off-by: Stephen Dickey --- arch/arm64/Kconfig | 1 + arch/arm64/kernel/smp.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a7c07ae524d9..cf21e80963b5 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -111,6 +111,7 @@ config ARM64 select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP select GENERIC_IRQ_IPI + select ARCH_WANTS_IRQ_RAW select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 3e42884f1591..22c65fbbf4c5 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -1005,6 +1005,10 @@ void __init set_smp_ipi_range(int ipi_base, int n) ipi_desc[i] = irq_to_desc(ipi_base + i); irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); + + /* The recheduling IPI is special... */ + if (i == IPI_RESCHEDULE) + __irq_modify_status(ipi_base + i, 0, IRQ_RAW, ~0); } ipi_irq_base = ipi_base; From 951bdfd077dbe3f9ff5a4274e42b46c964c1696e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 20 Oct 2020 15:37:04 +0100 Subject: [PATCH 21/60] FROMLIST: arm: Mark the recheduling IPI as raw interrupt Flag the rescheduling IPI as 'raw', making sure such interrupt skips both tick management and irqtime accounting. Bug: 191808738 Link: https://lore.kernel.org/lkml/20201124141449.572446-5-maz@kernel.org/ Change-Id: Ia9c2b989621eef6f49a1c30a08302a448ae286e6 Signed-off-by: Marc Zyngier [minor port to 5.10] Signed-off-by: Stephen Dickey --- arch/arm/Kconfig | 1 + arch/arm/kernel/smp.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 002e0cf025f5..e485c4813441 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -51,6 +51,7 @@ config ARM select GENERIC_ATOMIC64 if CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IRQ_IPI if SMP + select ARCH_WANTS_IRQ_RAW if GENERIC_IRQ_IPI select GENERIC_CPU_AUTOPROBE select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index e3ae634a36d5..ba27e184402a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -742,6 +742,10 @@ void __init set_smp_ipi_range(int ipi_base, int n) ipi_desc[i] = irq_to_desc(ipi_base + i); irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); + + /* The recheduling IPI is special... */ + if (i == IPI_RESCHEDULE) + __irq_modify_status(ipi_base + i, 0, IRQ_RAW, ~0); } ipi_irq_base = ipi_base; From 0d054fc5d7775a7b38e33fe243fdabdf4fada8fa Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Tue, 22 Jun 2021 10:35:43 -0700 Subject: [PATCH 22/60] Revert "ANDROID: make per-cgroup PSI tracking configurable" This reverts commit bd3983c8a85b5e69e0e7596449824d8b419af746. Bug: 178872719 Bug: 191734423 Signed-off-by: Suren Baghdasaryan Change-Id: Iae7997d518693f09fcc0bf8a3ee5caac6145ada5 --- init/Kconfig | 15 --------------- kernel/sched/psi.c | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index fc95d832e0a9..4413af4302ea 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -635,21 +635,6 @@ config PSI_DEFAULT_DISABLED Say N if unsure. -config PSI_PER_CGROUP_ACCT - bool "Enable per-cgroup pressure stall information tracking" - default n - depends on PSI - depends on CGROUPS - help - If set, pressure stall information will be tracked for each - individual cgroup. Otherwise, pressure stall information will - be tracked only at the system level under /proc/pressure/. - - This feature generates overhead that depends on the number of - cgroups in the cgroup v2 hierarchy. - - Say N if unsure. - endmenu # "CPU/Task time and stats accounting" config CPU_ISOLATION diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index ecd0618dcaad..5047c17e39a1 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -750,7 +750,7 @@ static void psi_group_change(struct psi_group *group, int cpu, static struct psi_group *iterate_groups(struct task_struct *task, void **iter) { -#if defined CONFIG_CGROUPS && defined CONFIG_PSI_PER_CGROUP_ACCT +#ifdef CONFIG_CGROUPS struct cgroup *cgroup = NULL; if (!*iter) From c7186c2c46d869c1a4c55bd0a1f83373b8a1b93a Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Mon, 24 May 2021 12:53:39 -0700 Subject: [PATCH 23/60] FROMGIT: cgroup: make per-cgroup pressure stall tracking configurable PSI accounts stalls for each cgroup separately and aggregates it at each level of the hierarchy. This causes additional overhead with psi_avgs_work being called for each cgroup in the hierarchy. psi_avgs_work has been highly optimized, however on systems with large number of cgroups the overhead becomes noticeable. Systems which use PSI only at the system level could avoid this overhead if PSI can be configured to skip per-cgroup stall accounting. Add "cgroup_disable=pressure" kernel command-line option to allow requesting system-wide only pressure stall accounting. When set, it keeps system-wide accounting under /proc/pressure/ but skips accounting for individual cgroups and does not expose PSI nodes in cgroup hierarchy. Signed-off-by: Suren Baghdasaryan Acked-by: Peter Zijlstra (Intel) Acked-by: Johannes Weiner Signed-off-by: Tejun Heo Link: https://lore.kernel.org/patchwork/patch/1435705 (cherry picked from commit 3958e2d0c34e18c41b60dc01832bd670a59ef70f https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git tj) Bug: 178872719 Bug: 191734423 Signed-off-by: Suren Baghdasaryan Change-Id: Ifc8fbc52f9a1131d7c2668edbb44c525c76c3360 --- .../admin-guide/kernel-parameters.txt | 9 +++- include/linux/cgroup-defs.h | 1 + include/linux/cgroup.h | 7 +++ kernel/cgroup/cgroup.c | 48 +++++++++++++++++++ kernel/sched/psi.c | 30 +++++++----- 5 files changed, 80 insertions(+), 15 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index ed42c3bad107..29c5f46bee20 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -513,16 +513,21 @@ ccw_timeout_log [S390] See Documentation/s390/common_io.rst for details. - cgroup_disable= [KNL] Disable a particular controller - Format: {name of the controller(s) to disable} + cgroup_disable= [KNL] Disable a particular controller or optional feature + Format: {name of the controller(s) or feature(s) to disable} The effects of cgroup_disable=foo are: - foo isn't auto-mounted if you mount all cgroups in a single hierarchy - foo isn't visible as an individually mountable subsystem + - if foo is an optional feature then the feature is + disabled and corresponding cgroup files are not + created {Currently only "memory" controller deal with this and cut the overhead, others just disable the usage. So only cgroup_disable=memory is actually worthy} + Specifying "pressure" disables per-cgroup pressure + stall information accounting feature cgroup_no_v1= [KNL] Disable cgroup controllers and named hierarchies in v1 Format: { { controller | "all" | "named" } diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index fee0b5547cd0..8c193033604f 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -110,6 +110,7 @@ enum { CFTYPE_NO_PREFIX = (1 << 3), /* (DON'T USE FOR NEW FILES) no subsys prefix */ CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */ CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */ + CFTYPE_PRESSURE = (1 << 6), /* only if pressure feature is enabled */ /* internal flags, do not use outside cgroup core proper */ __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */ diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 618838c48313..14b808b02872 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -676,6 +676,8 @@ static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) return &cgrp->psi; } +bool cgroup_psi_enabled(void); + static inline void cgroup_init_kthreadd(void) { /* @@ -735,6 +737,11 @@ static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) return NULL; } +static inline bool cgroup_psi_enabled(void) +{ + return false; +} + static inline bool task_under_cgroup_hierarchy(struct task_struct *task, struct cgroup *ancestor) { diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 66981dfd3d7c..eae1ce5569bf 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -212,6 +212,22 @@ struct cgroup_namespace init_cgroup_ns = { static struct file_system_type cgroup2_fs_type; static struct cftype cgroup_base_files[]; +/* cgroup optional features */ +enum cgroup_opt_features { +#ifdef CONFIG_PSI + OPT_FEATURE_PRESSURE, +#endif + OPT_FEATURE_COUNT +}; + +static const char *cgroup_opt_feature_names[OPT_FEATURE_COUNT] = { +#ifdef CONFIG_PSI + "pressure", +#endif +}; + +static u16 cgroup_feature_disable_mask __read_mostly; + static int cgroup_apply_control(struct cgroup *cgrp); static void cgroup_finalize_control(struct cgroup *cgrp, int ret); static void css_task_iter_skip(struct css_task_iter *it, @@ -3632,6 +3648,18 @@ static void cgroup_pressure_release(struct kernfs_open_file *of) { psi_trigger_replace(&of->priv, NULL); } + +bool cgroup_psi_enabled(void) +{ + return (cgroup_feature_disable_mask & (1 << OPT_FEATURE_PRESSURE)) == 0; +} + +#else /* CONFIG_PSI */ +bool cgroup_psi_enabled(void) +{ + return false; +} + #endif /* CONFIG_PSI */ static int cgroup_freeze_show(struct seq_file *seq, void *v) @@ -3882,6 +3910,8 @@ static int cgroup_addrm_files(struct cgroup_subsys_state *css, restart: for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) { /* does cft->flags tell us to skip this file on @cgrp? */ + if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled()) + continue; if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp)) continue; if ((cft->flags & __CFTYPE_NOT_ON_DFL) && cgroup_on_dfl(cgrp)) @@ -3959,6 +3989,9 @@ static int cgroup_init_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) WARN_ON(cft->ss || cft->kf_ops); + if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled()) + continue; + if (cft->seq_start) kf_ops = &cgroup_kf_ops; else @@ -4895,6 +4928,7 @@ static struct cftype cgroup_base_files[] = { #ifdef CONFIG_PSI { .name = "io.pressure", + .flags = CFTYPE_PRESSURE, .seq_show = cgroup_io_pressure_show, .write = cgroup_io_pressure_write, .poll = cgroup_pressure_poll, @@ -4902,6 +4936,7 @@ static struct cftype cgroup_base_files[] = { }, { .name = "memory.pressure", + .flags = CFTYPE_PRESSURE, .seq_show = cgroup_memory_pressure_show, .write = cgroup_memory_pressure_write, .poll = cgroup_pressure_poll, @@ -4909,6 +4944,7 @@ static struct cftype cgroup_base_files[] = { }, { .name = "cpu.pressure", + .flags = CFTYPE_PRESSURE, .seq_show = cgroup_cpu_pressure_show, .write = cgroup_cpu_pressure_write, .poll = cgroup_pressure_poll, @@ -6259,6 +6295,15 @@ static int __init cgroup_disable(char *str) continue; cgroup_disable_mask |= 1 << i; } + + for (i = 0; i < OPT_FEATURE_COUNT; i++) { + if (strcmp(token, cgroup_opt_feature_names[i])) + continue; + cgroup_feature_disable_mask |= 1 << i; + pr_info("Disabling %s control group feature\n", + cgroup_opt_feature_names[i]); + break; + } } return 1; } @@ -6557,6 +6602,9 @@ static ssize_t show_delegatable_files(struct cftype *files, char *buf, if (!(cft->flags & CFTYPE_NS_DELEGATABLE)) continue; + if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled()) + continue; + if (prefix) ret += snprintf(buf + ret, size - ret, "%s.", prefix); diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index 5047c17e39a1..d46f7585e772 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -147,6 +147,7 @@ static int psi_bug __read_mostly; DEFINE_STATIC_KEY_FALSE(psi_disabled); +DEFINE_STATIC_KEY_TRUE(psi_cgroups_enabled); #ifdef CONFIG_PSI_DEFAULT_DISABLED static bool psi_enable; @@ -210,6 +211,9 @@ void __init psi_init(void) return; } + if (!cgroup_psi_enabled()) + static_branch_disable(&psi_cgroups_enabled); + psi_period = jiffies_to_nsecs(PSI_FREQ); group_init(&psi_system); } @@ -750,23 +754,23 @@ static void psi_group_change(struct psi_group *group, int cpu, static struct psi_group *iterate_groups(struct task_struct *task, void **iter) { + if (*iter == &psi_system) + return NULL; + #ifdef CONFIG_CGROUPS - struct cgroup *cgroup = NULL; + if (static_branch_likely(&psi_cgroups_enabled)) { + struct cgroup *cgroup = NULL; - if (!*iter) - cgroup = task->cgroups->dfl_cgrp; - else if (*iter == &psi_system) - return NULL; - else - cgroup = cgroup_parent(*iter); + if (!*iter) + cgroup = task->cgroups->dfl_cgrp; + else + cgroup = cgroup_parent(*iter); - if (cgroup && cgroup_parent(cgroup)) { - *iter = cgroup; - return cgroup_psi(cgroup); + if (cgroup && cgroup_parent(cgroup)) { + *iter = cgroup; + return cgroup_psi(cgroup); + } } -#else - if (*iter) - return NULL; #endif *iter = &psi_system; return &psi_system; From cfe1f5aea680b08668a9cb3d375fa098e163dbf9 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Tue, 22 Jun 2021 10:46:17 -0700 Subject: [PATCH 24/60] ANDROID: gki_config: disable per-cgroup pressure tracking Disable per-cgroup psi tracking to prevent unnecessary overhead since Android does not use per-cgroup psi information. Bug: 178872719 Bug: 191734423 Signed-off-by: Suren Baghdasaryan Change-Id: Ic6f84630cd478139fb8cce00410163e4e767c86a --- arch/arm64/configs/gki_defconfig | 2 +- arch/x86/configs/gki_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index bebfbf7a3140..4b4acae5e6e2 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -59,7 +59,7 @@ CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y CONFIG_RANDOMIZE_BASE=y # CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set -CONFIG_CMDLINE="stack_depot_disable=on kasan.stacktrace=off kvm-arm.mode=protected" +CONFIG_CMDLINE="stack_depot_disable=on kasan.stacktrace=off kvm-arm.mode=protected cgroup_disable=pressure" CONFIG_CMDLINE_EXTEND=y # CONFIG_DMI is not set CONFIG_PM_WAKELOCKS=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 66d90c85ec3e..c8bf506d767e 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -53,7 +53,7 @@ CONFIG_PARAVIRT=y CONFIG_NR_CPUS=32 CONFIG_EFI=y CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="stack_depot_disable=on" +CONFIG_CMDLINE="stack_depot_disable=on cgroup_disable=pressure" CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set From 7d3618b8b9f6f42b6bc6cb5c2d4be1a5434e998a Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Tue, 22 Jun 2021 19:49:51 -0700 Subject: [PATCH 25/60] ANDROID: fix permission error of page_pinner longterm_pinner/alloc_contig_failed should be 444 for reading for everyone and threshold/failure_traking should be 644 to allow read/write root. Bug: 191827366 Signed-off-by: Minchan Kim Change-Id: I5493c6ae6d39b692282e5428416da80a7d555aa0 --- mm/page_pinner.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm/page_pinner.c b/mm/page_pinner.c index 5bd7364b4a91..c932788bb451 100644 --- a/mm/page_pinner.c +++ b/mm/page_pinner.c @@ -475,17 +475,17 @@ static int __init page_pinner_init(void) pp_debugfs_root = debugfs_create_dir("page_pinner", NULL); - debugfs_create_file("longterm_pinner", 0400, pp_debugfs_root, NULL, + debugfs_create_file("longterm_pinner", 0444, pp_debugfs_root, NULL, &proc_longterm_pinner_operations); - debugfs_create_file("threshold", 0444, pp_debugfs_root, NULL, + debugfs_create_file("threshold", 0644, pp_debugfs_root, NULL, &pp_threshold_fops); - debugfs_create_file("alloc_contig_failed", 0400, + debugfs_create_file("alloc_contig_failed", 0444, pp_debugfs_root, NULL, &proc_alloc_contig_failed_operations); - debugfs_create_file("failure_tracking", 0444, + debugfs_create_file("failure_tracking", 0644, pp_debugfs_root, NULL, &failure_tracking_fops); return 0; From 39147716e824cde335cad65cad4ee28e45df71f0 Mon Sep 17 00:00:00 2001 From: Tor Vic Date: Thu, 10 Jun 2021 20:58:06 +0000 Subject: [PATCH 26/60] UPSTREAM: x86, lto: Pass -stack-alignment only on LLD < 13.0.0 Since LLVM commit 3787ee4, the '-stack-alignment' flag has been dropped [1], leading to the following error message when building a LTO kernel with Clang-13 and LLD-13: ld.lld: error: -plugin-opt=-: ld.lld: Unknown command line argument '-stack-alignment=8'. Try 'ld.lld --help' ld.lld: Did you mean '--stackrealign=8'? It also appears that the '-code-model' flag is not necessary anymore starting with LLVM-9 [2]. Drop '-code-model' and make '-stack-alignment' conditional on LLD < 13.0.0. These flags were necessary because these flags were not encoded in the IR properly, so the link would restart optimizations without them. Now there are properly encoded in the IR, and these flags exposing implementation details are no longer necessary. [1] https://reviews.llvm.org/D103048 [2] https://reviews.llvm.org/D52322 Cc: stable@vger.kernel.org Link: https://github.com/ClangBuiltLinux/linux/issues/1377 Signed-off-by: Tor Vic Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/f2c018ee-5999-741e-58d4-e482d5246067@mailbox.org (cherry picked from commit 2398ce80152aae33b9501ef54452e09e8e8d4262) Change-Id: Icebcd5669e851e2c26e9f807b9d1aeb86e95dcea Signed-off-by: Nathan Chancellor --- arch/x86/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 75b49418c89e..c824dc6acea4 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -199,8 +199,9 @@ endif KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE) ifdef CONFIG_LTO_CLANG -KBUILD_LDFLAGS += -plugin-opt=-code-model=kernel \ - -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) +ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 130000; echo $$?),0) +KBUILD_LDFLAGS += -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) +endif endif ifdef CONFIG_X86_NEED_RELOCS From ee682ec7667aba7aa0fb1a1c6e3198609efc65c4 Mon Sep 17 00:00:00 2001 From: Orson Zhai Date: Mon, 17 May 2021 16:17:55 +0800 Subject: [PATCH 27/60] ANDROID: GKI: Enable ARCH_SPRD and SPRD_TIMER Add SPRD_TIMER config into GKI for the same reason as other vendors have described before. Bug: 188373235 Change-Id: I70f1296f11759d9010252a52a88f9329744172f6 Signed-off-by: Orson Zhai --- arch/arm64/configs/gki_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 4b4acae5e6e2..4dc06f9c2f37 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -48,6 +48,7 @@ CONFIG_PROFILING=y CONFIG_ARCH_SUNXI=y CONFIG_ARCH_HISI=y CONFIG_ARCH_QCOM=y +CONFIG_ARCH_SPRD=y CONFIG_SCHED_MC=y CONFIG_NR_CPUS=32 CONFIG_PARAVIRT=y @@ -518,6 +519,7 @@ CONFIG_STAGING=y CONFIG_ASHMEM=y CONFIG_DEBUG_KINFO=y CONFIG_COMMON_CLK_SCPI=y +# CONFIG_SPRD_COMMON_CLK is not set # CONFIG_CLK_SUNXI is not set # CONFIG_SUNXI_CCU is not set CONFIG_HWSPINLOCK=y From dde40c10899c29e2c72e473e5cc8d24602c14bef Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Mon, 5 Apr 2021 17:42:52 +0100 Subject: [PATCH 28/60] UPSTREAM: KVM: arm64: Handle access to TRFCR_EL1 Rather than falling to an "unhandled access", inject add an explicit "undefined access" for TRFCR_EL1 access from the guest. Bug: 174685394 Cc: Marc Zyngier Cc: Will Deacon Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/20210405164307.1720226-6-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier (cherry picked from commit cc427cbb15375f1229e78908064cdff98138b8b1) Signed-off-by: Qais Yousef Change-Id: If0efe01af21894ed29cb85338f802ac1f6a194fc --- arch/arm64/kvm/sys_regs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index cdd073d8ea32..47b05731b16c 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1472,6 +1472,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_GCR_EL1), undef_access }, { SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility }, + { SYS_DESC(SYS_TRFCR_EL1), undef_access }, { SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 }, { SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 }, { SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 }, From b6b0927eacc230a2c614b5a5c51dceea0af3df3c Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Mon, 5 Apr 2021 17:42:53 +0100 Subject: [PATCH 29/60] BACKPORT: KVM: arm64: Move SPE availability check to VCPU load At the moment, we check the availability of SPE on the given CPU (i.e, SPE is implemented and is allowed at the host) during every guest entry. This can be optimized a bit by moving the check to vcpu_load time and recording the availability of the feature on the current CPU via a new flag. This will also be useful for adding the TRBE support. Bug: 174685394 Cc: Marc Zyngier Cc: Will Deacon Cc: Alexandru Elisei Cc: James Morse Signed-off-by: Suzuki K Poulose Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/20210405164307.1720226-7-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier (cherry picked from commit d2602bb4f5a450642b96d467e27e6d5d3ef7fa54) [Conflict in: arch/arm64/kvm/hyp/nvhe/debug-sr.c Trivial conflict because of an additional __debug_save_trace() call since a previous version of the series was backported already.] Signed-off-by: Qais Yousef Change-Id: I4ca2bb14f7b647a1e118ea4a8c4313154a482685 --- arch/arm64/include/asm/kvm_host.h | 5 +++++ arch/arm64/kvm/arm.c | 2 ++ arch/arm64/kvm/debug.c | 23 +++++++++++++++++++++++ arch/arm64/kvm/hyp/nvhe/debug-sr.c | 22 +++++++++------------- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e573bc2b1b83..8abac197803b 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -405,6 +405,7 @@ struct kvm_vcpu_arch { #define KVM_ARM64_GUEST_HAS_PTRAUTH (1 << 7) /* PTRAUTH exposed to guest */ #define KVM_ARM64_PENDING_EXCEPTION (1 << 8) /* Exception pending */ #define KVM_ARM64_EXCEPT_MASK (7 << 9) /* Target EL/MODE */ +#define KVM_ARM64_DEBUG_STATE_SAVE_SPE (1 << 12) /* Save SPE context if active */ /* * When KVM_ARM64_PENDING_EXCEPTION is set, KVM_ARM64_EXCEPT_MASK can @@ -733,6 +734,10 @@ static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr) return (!has_vhe() && attr->exclude_host); } +/* Flags for host debug state */ +void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu); +void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu); + #ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */ static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) { diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 93f21e4a9b1e..4024be1e59c9 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -416,10 +416,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_disable(vcpu); + kvm_arch_vcpu_load_debug_state_flags(vcpu); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { + kvm_arch_vcpu_put_debug_state_flags(vcpu); kvm_arch_vcpu_put_fp(vcpu); if (has_vhe()) kvm_vcpu_put_sysregs_vhe(vcpu); diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index 2484b2cca74b..a53c5238faca 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -263,3 +263,26 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) } } } + +void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu) +{ + u64 dfr0; + + /* For VHE, there is nothing to do */ + if (has_vhe()) + return; + + dfr0 = read_sysreg(id_aa64dfr0_el1); + /* + * If SPE is present on this CPU and is available at current EL, + * we may need to check if the host state needs to be saved. + */ + if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_PMSVER_SHIFT) && + !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(SYS_PMBIDR_EL1_P_SHIFT))) + vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_SPE; +} + +void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu) +{ + vcpu->arch.flags &= ~KVM_ARM64_DEBUG_STATE_SAVE_SPE; +} diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c index 9499e18dd28f..1577a3be407d 100644 --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c @@ -21,17 +21,11 @@ static void __debug_save_spe(u64 *pmscr_el1) /* Clear pmscr in case of early return */ *pmscr_el1 = 0; - /* SPE present on this CPU? */ - if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1), - ID_AA64DFR0_PMSVER_SHIFT)) - return; - - /* Yes; is it owned by EL3? */ - reg = read_sysreg_s(SYS_PMBIDR_EL1); - if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT)) - return; - - /* No; is the host actually using the thing? */ + /* + * At this point, we know that this CPU implements + * SPE and is available to the host. + * Check if the host is actually using it ? + */ reg = read_sysreg_s(SYS_PMBLIMITR_EL1); if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT))) return; @@ -100,7 +94,8 @@ static void __debug_restore_trace(u64 trfcr_el1) void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) { /* Disable and flush SPE data generation */ - __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) + __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); /* Disable and flush Self-Hosted Trace generation */ __debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1); } @@ -112,7 +107,8 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu) void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) { - __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) + __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); __debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1); } From ee7e80c81bb7977791e16e90f1a82eddf483501d Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Mon, 5 Apr 2021 17:42:54 +0100 Subject: [PATCH 30/60] BACKPORT: arm64: KVM: Enable access to TRBE support for host For a nvhe host, the EL2 must allow the EL1&0 translation regime for TraceBuffer (MDCR_EL2.E2TB == 0b11). This must be saved/restored over a trip to the guest. Also, before entering the guest, we must flush any trace data if the TRBE was enabled. And we must prohibit the generation of trace while we are in EL1 by clearing the TRFCR_EL1. For vhe, the EL2 must prevent the EL1 access to the Trace Buffer. The MDCR_EL2 bit definitions for TRBE are available here : https://developer.arm.com/documentation/ddi0601/2020-12/AArch64-Registers/ Bug: 174685394 Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Cc: Mark Rutland Cc: Anshuman Khandual Signed-off-by: Suzuki K Poulose Acked-by: Marc Zyngier Link: https://lore.kernel.org/r/20210405164307.1720226-8-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier (cherry picked from commit a1319260bf62951e279ea228f682bf4b8834a3c2) [Conflict: - arch/arm64/kvm/debug.c - arch/arm64/kvm/hyp/nvhe/debug-sr.c Trivial conflicts except for one which tried to replce kvm_arm_setup_mdcr_el2(vcpu); we rejected that hunk.] Signed-off-by: Qais Yousef Change-Id: I88316a7b2d7b7b23a01914a7de0a2898c4a66afa --- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/debug.c | 16 ++++++++++++++-- arch/arm64/kvm/hyp/nvhe/debug-sr.c | 16 ++++------------ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 8abac197803b..923ffa4cbc5f 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -406,6 +406,7 @@ struct kvm_vcpu_arch { #define KVM_ARM64_PENDING_EXCEPTION (1 << 8) /* Exception pending */ #define KVM_ARM64_EXCEPT_MASK (7 << 9) /* Target EL/MODE */ #define KVM_ARM64_DEBUG_STATE_SAVE_SPE (1 << 12) /* Save SPE context if active */ +#define KVM_ARM64_DEBUG_STATE_SAVE_TRBE (1 << 13) /* Save TRBE context if active */ /* * When KVM_ARM64_PENDING_EXCEPTION is set, KVM_ARM64_EXCEPT_MASK can diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index a53c5238faca..d2b120ec577f 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -141,7 +141,13 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) * @vcpu: the vcpu pointer * * This is called before each entry into the hypervisor to setup any - * debug related registers. + * debug related registers. Currently this just ensures we will trap + * access to: + * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) + * - Debug ROM Address (MDCR_EL2_TDRA) + * - OS related registers (MDCR_EL2_TDOSA) + * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) + * - Self-hosted Trace (MDCR_EL2_TTRF/MDCR_EL2_E2TB) * * Additionally, KVM only traps guest accesses to the debug registers if * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY @@ -280,9 +286,15 @@ void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu) if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_PMSVER_SHIFT) && !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(SYS_PMBIDR_EL1_P_SHIFT))) vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_SPE; + + /* Check if we have TRBE implemented and available at the host */ + if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRBE_SHIFT) && + !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_PROG)) + vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_TRBE; } void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu) { - vcpu->arch.flags &= ~KVM_ARM64_DEBUG_STATE_SAVE_SPE; + vcpu->arch.flags &= ~(KVM_ARM64_DEBUG_STATE_SAVE_SPE | + KVM_ARM64_DEBUG_STATE_SAVE_TRBE); } diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c index 1577a3be407d..7d3f25868cae 100644 --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c @@ -54,18 +54,8 @@ static void __debug_restore_spe(u64 pmscr_el1) static void __debug_save_trace(u64 *trfcr_el1) { - *trfcr_el1 = 0; - /* Check if we have TRBE */ - if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1), - ID_AA64DFR0_TRBE_SHIFT)) - return; - - /* Check we can access the TRBE */ - if ((read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_PROG)) - return; - /* Check if the TRBE is enabled */ if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_ENABLE)) return; @@ -97,7 +87,8 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); /* Disable and flush Self-Hosted Trace generation */ - __debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE) + __debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1); } void __debug_switch_to_guest(struct kvm_vcpu *vcpu) @@ -109,7 +100,8 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) { if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); - __debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE) + __debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1); } void __debug_switch_to_host(struct kvm_vcpu *vcpu) From ce71010347a06aee2010655c9c4f35eddb0d6c2c Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Mon, 26 Apr 2021 13:26:14 +0100 Subject: [PATCH 31/60] ANDROID: kvm: arm64: Clarify the comment for SPE save context Make the comment in line with the upstream version. Bug: 174685394 Signed-off-by: Suzuki K Poulose Signed-off-by: Qais Yousef Change-Id: I8c239d37c96c0c8de1261df6d2a5a2defd43ccfb --- arch/arm64/kvm/hyp/nvhe/switch.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 9cc4c9ebfd8f..e9f6ea704d07 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -193,12 +193,11 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) __sysreg_save_state_nvhe(host_ctxt); /* - * For nVHE, we must save and disable any SPE - * buffers, as the translation regime is going - * to be loaded with that of the guest. And we must - * save host context for SPE, before we change the - * ownership to EL2 (via MDCR_EL2_E2PB == 0) and before - * we load guest Stage1. + * We must flush and disable the SPE buffer for nVHE, as + * the translation regime(EL1&0) is going to be loaded with + * that of the guest. And we must do this before we change the + * translation regime to EL2 (via MDCR_EL2_E2PB == 0) and + * before we load guest Stage1. */ __debug_save_host_buffers_nvhe(vcpu); From 6f1bd7583f13c7173991428d8ffe9cca7bb02291 Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Mon, 26 Apr 2021 12:21:58 +0100 Subject: [PATCH 32/60] ANDROID: coresight: Update ETE/TRBE to v6 merged upstream Mark the buffer as truncated in irq + minor cleanups picked along the way. Bug: 174685394 Signed-off-by: Qais Yousef Change-Id: I36111a14ef066b579a28c39e265f3d601a82e18a --- drivers/hwtracing/coresight/coresight-core.c | 2 +- .../hwtracing/coresight/coresight-etm4x-core.c | 4 ++-- drivers/hwtracing/coresight/coresight-trbe.c | 18 +++++++++++++----- drivers/hwtracing/coresight/coresight-trbe.h | 3 +-- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index c4c9f41c0622..1504eb09f8e5 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -23,7 +23,7 @@ #include "coresight-priv.h" static DEFINE_MUTEX(coresight_mutex); -DEFINE_PER_CPU(struct coresight_device *, csdev_sink); +static DEFINE_PER_CPU(struct coresight_device *, csdev_sink); /** * struct coresight_node - elements of a path, from source to sink diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 90827077d2f9..6fee02bf7b71 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -115,7 +115,7 @@ void etm4x_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) } } -u64 ete_sysreg_read(u32 offset, bool _relaxed, bool _64bit) +static u64 ete_sysreg_read(u32 offset, bool _relaxed, bool _64bit) { u64 res = 0; @@ -132,7 +132,7 @@ u64 ete_sysreg_read(u32 offset, bool _relaxed, bool _64bit) return res; } -void ete_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) +static void ete_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) { if (!_relaxed) __iowmb(); /* Imitate the !relaxed I/O helpers */ diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index a7484abda325..176868496879 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -5,6 +5,8 @@ * device (ETE) thus generating required trace data. Trace can be enabled * via the perf framework. * + * The AUX buffer handling is inspired from Arm SPE PMU driver. + * * Copyright (C) 2020 ARM Ltd. * * Author: Anshuman Khandual @@ -515,7 +517,7 @@ static void *arm_trbe_alloc_buffer(struct coresight_device *csdev, if (!buf->trbe_base) { kfree(pglist); kfree(buf); - return ERR_PTR(buf->trbe_base); + return ERR_PTR(-ENOMEM); } buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE; buf->trbe_write = buf->trbe_base; @@ -614,9 +616,10 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev, /* * Otherwise, the buffer is full and the write pointer * has reached base. Adjust this back to the Limit pointer - * for correct size. + * for correct size. Also, mark the buffer truncated. */ write = get_trbe_limit_pointer(); + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); } offset = write - base; @@ -703,7 +706,12 @@ static void trbe_handle_overflow(struct perf_output_handle *handle) if (buf->snapshot) handle->head += size; - perf_aux_output_flag(handle, PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW); + /* + * Mark the buffer as truncated, as we have stopped the trace + * collection upon the WRAP event, without stopping the source. + */ + perf_aux_output_flag(handle, PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW | + PERF_AUX_FLAG_TRUNCATED); perf_aux_output_end(handle, size); event_data = perf_aux_output_begin(handle, event); if (!event_data) { @@ -863,7 +871,7 @@ static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cp dev = &cpudata->drvdata->pdev->dev; desc.name = devm_kasprintf(dev, GFP_KERNEL, "trbe%d", cpu); - if (IS_ERR(desc.name)) + if (!desc.name) goto cpu_clear; desc.type = CORESIGHT_DEV_TYPE_SINK; @@ -1038,7 +1046,7 @@ static int arm_trbe_probe_irq(struct platform_device *pdev, if (irq_get_percpu_devid_partition(drvdata->irq, &drvdata->supported_cpus)) return -EINVAL; - drvdata->handle = alloc_percpu(typeof(*drvdata->handle)); + drvdata->handle = alloc_percpu(struct perf_output_handle *); if (!drvdata->handle) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-trbe.h b/drivers/hwtracing/coresight/coresight-trbe.h index 499b846ccfee..abf3e36082f0 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.h +++ b/drivers/hwtracing/coresight/coresight-trbe.h @@ -128,8 +128,7 @@ static inline void set_trbe_write_pointer(unsigned long addr) static inline unsigned long get_trbe_limit_pointer(void) { u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1); - unsigned long limit = (trblimitr >> TRBLIMITR_LIMIT_SHIFT) & TRBLIMITR_LIMIT_MASK; - unsigned long addr = limit << TRBLIMITR_LIMIT_SHIFT; + unsigned long addr = trblimitr & (TRBLIMITR_LIMIT_MASK << TRBLIMITR_LIMIT_SHIFT); WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE)); return addr; From 4198bdb2cff86af72de536067e11d8783928c881 Mon Sep 17 00:00:00 2001 From: Qais Yousef Date: Mon, 26 Apr 2021 14:18:32 +0100 Subject: [PATCH 33/60] ANDROID: coresight: Update ETE DT yaml file Update ETE yaml file to bring it inline with upstream. The change is minor and updates the ports property. Bug: 174685394 Signed-off-by: Qais Yousef Change-Id: Ia5bb2ddcbdfa171e998f4f023a0a164ac14f5dd3 --- Documentation/devicetree/bindings/arm/ete.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/ete.yaml b/Documentation/devicetree/bindings/arm/ete.yaml index 35a42d92bf97..572564a0fc6f 100644 --- a/Documentation/devicetree/bindings/arm/ete.yaml +++ b/Documentation/devicetree/bindings/arm/ete.yaml @@ -37,7 +37,11 @@ properties: out-ports: description: | Output connections from the ETE to legacy CoreSight trace bus. - $ref: /schemas/graph.yaml#/properties/port + $ref: /schemas/graph.yaml#/properties/ports + properties: + port: + description: Output connection from the ETE to legacy CoreSight Trace bus. + $ref: /schemas/graph.yaml#/properties/port required: required: - compatible From f502bc761ac25dadb0ca9d4f2b0209bb4f97c82d Mon Sep 17 00:00:00 2001 From: wangchenggang <11061793@bbktel.com> Date: Wed, 23 Jun 2021 19:13:00 +0800 Subject: [PATCH 34/60] ANDROID: GKI: Update symbols to symbol list Update symbols to symbol list externed by oem modules. Leaf changes summary: 0 artifact changed (1 filtered out) Changed leaf types summary: 0 (1 filtered out) leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 0 Added function Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable Bug: 191844515 Change-Id: Ifbf1d9bdf30bac43342ae8987aba0d937657d983 Signed-off-by: Chenggang Wang Signed-off-by: wangchenggang <11061793@bbktel.com> --- android/abi_gki_aarch64_vivo | 1969 ++++++++++++++++++++++++++++++++++ build.config.gki.aarch64 | 1 + 2 files changed, 1970 insertions(+) create mode 100644 android/abi_gki_aarch64_vivo diff --git a/android/abi_gki_aarch64_vivo b/android/abi_gki_aarch64_vivo new file mode 100644 index 000000000000..2ffed65fcc1f --- /dev/null +++ b/android/abi_gki_aarch64_vivo @@ -0,0 +1,1969 @@ +[abi_symbol_list] + activate_task + add_cpu + add_device_randomness + add_memory + add_memory_subsection + add_timer + add_uevent_var + add_wait_queue + alarm_cancel + alarm_init + alarm_start + alloc_anon_inode + alloc_chrdev_region + __alloc_disk_node + alloc_io_pgtable_ops + __alloc_pages_nodemask + __alloc_percpu + __alloc_skb + alloc_skb_with_frags + alloc_workqueue + amba_bustype + amba_driver_register + amba_driver_unregister + android_debug_per_cpu_symbol + android_debug_symbol + android_rvh_probe_register + anon_inode_getfile + __arch_copy_from_user + __arch_copy_in_user + __arch_copy_to_user + arch_timer_read_counter + argv_free + argv_split + arm64_const_caps_ready + arm64_use_ng_mappings + __arm_smccc_smc + atomic_notifier_call_chain + atomic_notifier_chain_register + atomic_notifier_chain_unregister + available_idle_cpu + bdget_disk + bdput + bio_endio + bitmap_allocate_region + __bitmap_clear + bitmap_find_next_zero_area_off + __bitmap_or + bitmap_parselist_user + bitmap_print_to_pagebuf + bitmap_release_region + __bitmap_set + blk_alloc_queue + blk_cleanup_queue + blk_execute_rq + blk_execute_rq_nowait + blk_get_request + blk_mq_rq_cpu + blk_put_request + blk_queue_flag_clear + blk_queue_flag_set + blk_queue_io_min + blk_queue_io_opt + blk_queue_logical_block_size + blk_queue_max_discard_sectors + blk_queue_max_write_zeroes_sectors + blk_queue_physical_block_size + blk_rq_map_kern + blk_rq_map_user + blk_rq_map_user_iov + blk_rq_unmap_user + blk_verify_command + blocking_notifier_call_chain + blocking_notifier_chain_register + blocking_notifier_chain_unregister + bpf_trace_run10 + bpf_trace_run12 + bpf_trace_run1 + bpf_trace_run2 + bpf_trace_run3 + bpf_trace_run4 + bpf_trace_run5 + bpf_trace_run6 + bpf_trace_run7 + bpf_trace_run8 + bpf_trace_run9 + bus_find_device + bus_for_each_dev + bus_register + bus_set_iommu + bus_unregister + cancel_delayed_work + cancel_delayed_work_sync + cancel_work_sync + capable + cdev_add + cdev_alloc + cdev_del + cdev_device_add + cdev_device_del + cdev_init + __cfi_slowpath + cgroup_path_ns + cgroup_taskset_first + cgroup_taskset_next + __check_object_size + check_preempt_curr + check_zeroed_user + __class_create + class_destroy + class_find_device + class_for_each_device + class_interface_unregister + __class_register + class_unregister + cleanup_srcu_struct + clear_page + __ClearPageMovable + clk_bulk_disable + clk_bulk_enable + clk_bulk_prepare + clk_bulk_put_all + clk_bulk_unprepare + __clk_determine_rate + clk_disable + clk_enable + clk_fixed_factor_ops + clk_fixed_rate_ops + clk_get + __clk_get_hw + __clk_get_name + clk_get_parent + clk_get_rate + clk_hw_get_flags + clk_hw_get_name + clk_hw_get_num_parents + clk_hw_get_parent + clk_hw_get_parent_by_index + clk_hw_get_rate + clk_hw_is_enabled + clk_hw_is_prepared + clk_hw_register + clk_hw_round_rate + clk_hw_unregister + __clk_is_enabled + __clk_mux_determine_rate_closest + clk_notifier_register + clk_notifier_unregister + clk_prepare + clk_put + clk_round_rate + clk_set_parent + clk_set_rate + clk_sync_state + clk_unprepare + cma_alloc + cma_get_name + cma_release + compat_alloc_user_space + compat_ptr_ioctl + complete + complete_all + completion_done + component_add + component_bind_all + component_del + component_master_add_with_match + component_master_del + component_match_add_release + component_unbind_all + config_ep_by_speed + configfs_register_subsystem + configfs_unregister_subsystem + config_group_init + config_group_init_type_name + config_item_get + config_item_put + console_stop + console_suspend_enabled + __const_udelay + consume_skb + contig_page_data + _copy_from_iter_full + __cpu_active_mask + cpu_bit_bitmap + cpufreq_cpu_get + cpufreq_cpu_get_raw + cpufreq_cpu_put + cpufreq_disable_fast_switch + cpufreq_driver_fast_switch + cpufreq_driver_resolve_freq + __cpufreq_driver_target + cpufreq_enable_fast_switch + cpufreq_freq_attr_scaling_available_freqs + cpufreq_freq_attr_scaling_boost_freqs + cpufreq_generic_frequency_table_verify + cpufreq_get_policy + cpufreq_register_driver + cpufreq_register_governor + cpufreq_register_notifier + cpufreq_unregister_driver + cpufreq_unregister_notifier + __cpuhp_remove_state + __cpuhp_setup_state + __cpuhp_setup_state_cpuslocked + __cpuhp_state_add_instance + __cpuhp_state_remove_instance + cpu_hwcap_keys + cpu_hwcaps + cpuidle_governor_latency_req + cpuidle_register_governor + cpu_irqtime + cpu_latency_qos_add_request + cpu_latency_qos_remove_request + cpu_latency_qos_request_active + cpu_latency_qos_update_request + cpumask_next + cpumask_next_and + cpu_number + __cpu_online_mask + cpu_pm_register_notifier + cpu_pm_unregister_notifier + __cpu_possible_mask + __cpu_present_mask + cpupri_find_fitness + cpu_scale + cpus_read_lock + cpus_read_unlock + cpu_subsys + cpu_topology + crc8 + crc8_populate_msb + crypto_alloc_base + crypto_comp_compress + crypto_comp_decompress + crypto_destroy_tfm + crypto_has_alg + crypto_register_alg + crypto_register_rngs + crypto_register_scomp + crypto_unregister_alg + crypto_unregister_rngs + crypto_unregister_scomp + css_next_child + _ctype + datagram_poll + deactivate_task + debugfs_attr_read + debugfs_attr_write + debugfs_create_bool + debugfs_create_dir + debugfs_create_file + debugfs_create_file_unsafe + debugfs_create_u32 + debugfs_create_u8 + debugfs_create_x32 + debugfs_create_x8 + debugfs_file_get + debugfs_file_put + debugfs_lookup + debugfs_remove + dec_zone_page_state + default_llseek + deferred_free + delayed_work_timer_fn + del_gendisk + del_timer + del_timer_sync + desc_to_gpio + destroy_workqueue + dev_coredumpv + _dev_crit + dev_driver_string + _dev_err + devfreq_add_device + devfreq_add_governor + devfreq_cooling_unregister + devfreq_remove_device + devfreq_remove_governor + devfreq_resume_device + devfreq_suspend_device + dev_fwnode + dev_get_by_name + dev_get_regmap + device_add + device_add_disk + device_add_groups + device_create + device_create_file + device_del + device_destroy + device_find_child + device_for_each_child + device_get_match_data + device_initialize + device_init_wakeup + device_link_add + device_match_fwnode + device_match_name + device_property_present + device_property_read_string + device_property_read_u16_array + device_property_read_u32_array + device_register + device_remove_file + device_show_int + device_store_int + device_unregister + device_wakeup_disable + device_wakeup_enable + _dev_info + devm_add_action + devm_blk_ksm_init + devm_clk_bulk_get_all + devm_clk_get + devm_clk_hw_register + devm_clk_put + devm_clk_register + devm_device_add_group + devm_device_remove_group + devm_extcon_dev_allocate + devm_extcon_dev_register + devm_extcon_dev_unregister + devm_free_irq + devm_gpiod_get_optional + devm_gpio_request + devm_gpio_request_one + devm_hwspin_lock_register + devm_iio_channel_get + devm_iio_device_alloc + __devm_iio_device_register + devm_input_allocate_device + devm_ioremap + devm_ioremap_resource + devm_ioremap_wc + devm_iounmap + devm_kasprintf + devm_kfree + devm_kmalloc + devm_kmemdup + devm_kstrdup + devm_led_classdev_register_ext + devm_nvmem_cell_get + devm_nvmem_device_get + devm_nvmem_register + devm_of_clk_add_hw_provider + devm_of_icc_get + __devm_of_phy_provider_register + devm_of_platform_populate + devm_of_pwm_get + devm_pci_alloc_host_bridge + devm_phy_create + devm_phy_get + devm_pinctrl_get + devm_pinctrl_put + devm_pinctrl_register + devm_platform_ioremap_resource + devm_platform_ioremap_resource_byname + devm_power_supply_register + devm_regmap_field_alloc + __devm_regmap_init + __devm_regmap_init_i2c + __devm_regmap_init_mmio_clk + devm_regulator_bulk_get + devm_regulator_get + devm_regulator_get_optional + devm_regulator_put + devm_regulator_register + devm_regulator_register_notifier + devm_request_any_context_irq + devm_request_threaded_irq + __devm_reset_control_get + devm_reset_controller_register + devm_rtc_allocate_device + devm_thermal_of_cooling_device_register + devm_thermal_zone_of_sensor_register + devm_usb_get_phy_by_node + _dev_notice + dev_pm_domain_attach + dev_pm_domain_attach_by_name + dev_pm_domain_detach + dev_pm_genpd_add_notifier + dev_pm_genpd_remove_notifier + dev_pm_genpd_set_next_wakeup + dev_pm_genpd_set_performance_state + dev_pm_opp_add + dev_pm_opp_find_freq_ceil + dev_pm_opp_find_freq_exact + dev_pm_opp_find_freq_floor + dev_pm_opp_get_opp_count + dev_pm_opp_get_voltage + dev_pm_opp_of_add_table + dev_pm_opp_of_find_icc_paths + dev_pm_opp_of_register_em + dev_pm_opp_of_remove_table + dev_pm_opp_put + dev_pm_opp_put_clkname + dev_pm_opp_remove_all_dynamic + dev_pm_opp_set_clkname + dev_pm_opp_set_rate + dev_pm_opp_set_sharing_cpus + dev_pm_qos_add_notifier + dev_pm_qos_add_request + dev_pm_qos_read_value + dev_pm_qos_remove_notifier + dev_pm_qos_remove_request + dev_pm_qos_update_request + dev_printk + devres_add + devres_alloc_node + devres_free + devres_release + dev_set_name + _dev_warn + disable_irq + disable_irq_nosync + disable_percpu_irq + disk_end_io_acct + disk_start_io_acct + divider_get_val + divider_recalc_rate + divider_ro_round_rate_parent + divider_round_rate_parent + dma_alloc_attrs + dma_async_device_register + dma_async_device_unregister + dma_async_tx_descriptor_init + dma_buf_attach + dma_buf_begin_cpu_access + dma_buf_begin_cpu_access_partial + dma_buf_detach + dma_buf_end_cpu_access + dma_buf_end_cpu_access_partial + dma_buf_export + dma_buf_fd + dma_buf_get + dma_buf_map_attachment + dma_buf_put + dma_buf_unmap_attachment + dma_buf_vmap + dma_buf_vunmap + dma_fence_add_callback + dma_fence_array_create + dma_fence_array_ops + dma_fence_context_alloc + dma_fence_default_wait + dma_fence_enable_sw_signaling + dma_fence_free + dma_fence_get_status + dma_fence_init + dma_fence_release + dma_fence_remove_callback + dma_fence_signal + dma_fence_signal_locked + dma_fence_wait_timeout + dma_free_attrs + dma_get_sgtable_attrs + dma_get_slave_channel + dma_heap_add + dma_heap_buffer_alloc + dma_heap_find + dma_heap_get_dev + dma_heap_get_drvdata + dma_heap_get_name + dmam_alloc_attrs + dma_map_page_attrs + dma_map_resource + dma_map_sg_attrs + dmam_free_coherent + dma_release_channel + dma_request_chan + dma_set_coherent_mask + dma_set_mask + dma_sync_sg_for_cpu + dma_sync_sg_for_device + dma_sync_single_for_cpu + dma_sync_single_for_device + dma_unmap_page_attrs + dma_unmap_resource + dma_unmap_sg_attrs + do_exit + down_read + down_write + d_path + dput + drain_workqueue + driver_find_device + driver_register + driver_unregister + edac_device_add_device + edac_device_alloc_ctl_info + edac_device_alloc_index + edac_device_del_device + edac_device_free_ctl_info + edac_device_handle_ce_count + edac_device_handle_ue_count + enable_irq + enable_percpu_irq + eventfd_ctx_fdget + eventfd_ctx_fileget + eventfd_ctx_put + eventfd_ctx_remove_wait_queue + eventfd_signal + event_triggers_call + extcon_get_edev_by_phandle + extcon_get_edev_name + extcon_get_property + extcon_get_state + extcon_register_notifier + extcon_set_state_sync + failure_tracking + fasync_helper + __fdget + fd_install + fget + filp_close + filp_open_block + find_last_bit + find_next_bit + find_next_zero_bit + find_snd_usb_substream + find_task_by_vpid + find_vma + find_vpid + finish_wait + firmware_request_nowarn + flush_dcache_page + flush_delayed_work + flush_work + flush_workqueue + fput + free_io_pgtable_ops + free_irq + __free_pages + free_pages + free_percpu + free_percpu_irq + freq_qos_add_request + freq_qos_remove_request + freq_qos_update_request + freq_scale + fsync_bdev + fwnode_find_reference + fwnode_get_next_child_node + fwnode_handle_get + fwnode_handle_put + fwnode_property_present + fwnode_property_read_string + fwnode_property_read_u32_array + generic_device_group + generic_handle_irq + generic_iommu_put_resv_regions + genlmsg_put + genl_register_family + genl_unregister_family + gen_pool_add_owner + gen_pool_alloc_algo_owner + gen_pool_avail + gen_pool_best_fit + gen_pool_create + gen_pool_destroy + gen_pool_first_fit_order_align + gen_pool_free_owner + gen_pool_has_addr + gen_pool_set_algo + gen_pool_size + gen_pool_virt_to_phys + getboottime64 + get_cpu_device + get_device + __get_free_pages + get_governor_parent_kobj + get_option + get_pid_task + get_random_bytes + get_random_u32 + get_sg_io_hdr + __get_task_comm + get_task_mm + get_task_pid + get_unmapped_area + get_unused_fd_flags + get_user_pages + gfp_zone + gic_nonsecure_priorities + gov_attr_set_init + gov_attr_set_put + governor_sysfs_ops + gpiochip_add_data_with_key + gpiochip_add_pin_range + gpiochip_generic_free + gpiochip_generic_request + gpiochip_get_data + gpiochip_line_is_valid + gpiochip_lock_as_irq + gpiochip_remove + gpiochip_unlock_as_irq + gpiod_direction_input + gpiod_direction_output + gpiod_direction_output_raw + gpiod_get_optional + gpiod_get_raw_value + gpiod_get_raw_value_cansleep + gpiod_get_value + gpiod_set_raw_value + gpiod_set_value + gpiod_set_value_cansleep + gpiod_to_irq + gpio_free + gpio_request + gpio_request_one + gpio_to_desc + handle_bad_irq + handle_edge_irq + handle_fasteoi_ack_irq + handle_fasteoi_irq + handle_level_irq + handle_nested_irq + handle_simple_irq + handle_sysrq + hashlen_string + hex_dump_to_buffer + hrtimer_active + hrtimer_cancel + hrtimer_forward + __hrtimer_get_remaining + hrtimer_init + hrtimer_start_range_ns + hrtimer_try_to_cancel + hvc_alloc + hvc_kick + hvc_poll + hvc_remove + hwrng_register + hwrng_unregister + hwspin_lock_free + hwspin_lock_request_specific + __hwspin_lock_timeout + __hwspin_unlock + hypervisor_kobj + i2c_add_adapter + i2c_del_adapter + i2c_del_driver + i2c_get_dma_safe_msg_buf + i2c_put_dma_safe_msg_buf + i2c_register_driver + i2c_smbus_read_byte_data + i2c_smbus_write_byte_data + i2c_transfer + i2c_transfer_buffer_flags + icc_get + icc_link_create + icc_node_add + icc_node_create + icc_node_del + icc_node_destroy + icc_provider_add + icc_provider_del + icc_put + icc_set_bw + icc_set_tag + ida_alloc_range + ida_free + idr_alloc + idr_alloc_cyclic + idr_destroy + idr_find + idr_for_each + idr_get_next + idr_preload + idr_remove + idr_replace + iio_channel_get + iio_channel_get_all + iio_channel_release + iio_read_channel_processed + import_iovec + inc_zone_page_state + in_egroup_p + init_iova_domain + init_net + init_pseudo + __init_rwsem + init_srcu_struct + __init_swait_queue_head + init_task + init_timer_key + init_uts_ns + init_wait_entry + __init_waitqueue_head + input_alloc_absinfo + input_allocate_device + input_close_device + input_event + input_free_device + input_mt_init_slots + input_mt_report_pointer_emulation + input_mt_report_slot_state + input_open_device + input_register_device + input_register_handle + input_register_handler + input_set_abs_params + input_set_capability + input_unregister_device + input_unregister_handle + input_unregister_handler + interval_tree_insert + interval_tree_iter_first + interval_tree_iter_next + interval_tree_remove + int_sqrt + iommu_alloc_resv_region + iommu_attach_device + iommu_detach_device + iommu_device_register + iommu_device_sysfs_add + iommu_device_sysfs_remove + iommu_device_unregister + iommu_dma_get_resv_regions + iommu_domain_alloc + iommu_domain_free + iommu_domain_get_attr + iommu_domain_set_attr + iommu_fwspec_add_ids + iommu_fwspec_free + iommu_get_dma_cookie + iommu_get_domain_for_dev + iommu_get_msi_cookie + iommu_group_for_each_dev + iommu_group_get + iommu_group_get_iommudata + iommu_group_put + iommu_group_ref_get + iommu_group_set_iommudata + iommu_iova_to_phys + iommu_map + iommu_map_sg + iommu_present + iommu_put_dma_cookie + iommu_set_fault_handler + iommu_unmap + __ioread32_copy + __ioremap + iounmap + __iowrite32_copy + ipi_desc_get + iput + irq_chip_ack_parent + irq_chip_disable_parent + irq_chip_enable_parent + irq_chip_eoi_parent + irq_chip_get_parent_state + irq_chip_mask_parent + irq_chip_retrigger_hierarchy + irq_chip_set_affinity_parent + irq_chip_set_parent_state + irq_chip_set_type_parent + irq_chip_set_vcpu_affinity_parent + irq_chip_set_wake_parent + irq_chip_unmask_parent + irq_create_fwspec_mapping + irq_dispose_mapping + __irq_domain_add + irq_domain_alloc_irqs_parent + irq_domain_create_hierarchy + irq_domain_free_irqs_common + irq_domain_free_irqs_parent + irq_domain_get_irq_data + irq_domain_remove + irq_domain_set_hwirq_and_chip + irq_domain_set_info + irq_domain_update_bus_token + irq_domain_xlate_twocell + irq_find_mapping + irq_find_matching_fwspec + irq_get_irqchip_state + irq_get_irq_data + irq_modify_status + irq_of_parse_and_map + irq_set_affinity_hint + irq_set_affinity_notifier + irq_set_chained_handler_and_data + irq_set_chip_and_handler_name + irq_set_chip_data + irq_set_irqchip_state + irq_set_irq_type + irq_set_irq_wake + irq_set_parent + irq_to_desc + irq_work_queue + irq_work_queue_on + irq_work_sync + is_dma_buf_file + is_vmalloc_addr + jiffies + jiffies_to_msecs + jiffies_to_usecs + kasan_flag_enabled + kasprintf + kernel_bind + kernel_connect + kernel_getsockname + kernel_kobj + kernel_recvmsg + kernel_restart + kernel_sendmsg + kern_mount + kern_unmount + __kfifo_alloc + __kfifo_in + __kfifo_out + kfree + kfree_const + kfree_sensitive + kfree_skb + kill_anon_super + kill_fasync + kimage_vaddr + kimage_voffset + __kmalloc + kmalloc_caches + kmalloc_order_trace + kmem_cache_alloc + kmem_cache_alloc_trace + kmem_cache_create + kmem_cache_create_usercopy + kmem_cache_destroy + kmem_cache_free + kmemdup + kmemdup_nul + kobject_add + kobject_create_and_add + kobject_del + kobject_init + kobject_init_and_add + kobject_put + kobject_set_name + kobject_uevent + kobj_sysfs_ops + krealloc + kset_create_and_add + ksize + ksoftirqd + kstat + kstat_irqs_cpu + kstat_irqs_usr + kstrdup + kstrdup_const + kstrndup + kstrtobool + kstrtoint + kstrtoll + kstrtou16 + kstrtou16_from_user + kstrtou8 + kstrtou8_from_user + kstrtouint + kstrtouint_from_user + kstrtoul_from_user + kstrtoull + kstrtoull_from_user + kthread_bind_mask + kthread_cancel_work_sync + kthread_create_on_node + kthread_create_worker + kthread_destroy_worker + kthread_flush_worker + __kthread_init_worker + kthread_queue_work + kthread_should_stop + kthread_stop + kthread_worker_fn + ktime_get + ktime_get_mono_fast_ns + ktime_get_real_seconds + ktime_get_real_ts64 + ktime_get_with_offset + kvfree + kvmalloc_node + led_classdev_flash_register_ext + led_classdev_flash_unregister + led_classdev_unregister + __list_add_valid + __list_del_entry_valid + list_sort + llist_add_batch + llist_reverse_order + __lock_page + lock_sock_nested + log_buf_addr_get + log_buf_len_get + __log_post_read_mmio + __log_read_mmio + __log_write_mmio + lzo1x_1_compress + lzo1x_decompress_safe + lzorle1x_1_compress + match_string + mbox_chan_received_data + mbox_chan_txdone + mbox_client_txdone + mbox_controller_register + mbox_controller_unregister + mbox_free_channel + mbox_request_channel + mbox_send_message + memblock_end_of_DRAM + __memcat_p + memcpy + __memcpy_fromio + __memcpy_toio + memdup_user + memmove + memory_block_size_bytes + memory_read_from_buffer + memparse + mempool_alloc + mempool_alloc_slab + mempool_create + mempool_destroy + mempool_free + mempool_free_slab + memremap + memset64 + memset + __memset_io + memstart_addr + memunmap + migrate_swap + misc_deregister + misc_register + mmc_cqe_request_done + mmc_of_parse + mmc_regulator_get_supply + mmc_regulator_set_ocr + mmc_regulator_set_vqmmc + mmc_send_tuning + mmput + mod_delayed_work_on + mod_node_page_state + mod_timer + __module_get + module_layout + module_put + __msecs_to_jiffies + msleep + msleep_interruptible + __mutex_init + mutex_is_locked + mutex_lock + mutex_lock_interruptible + mutex_trylock + mutex_unlock + netlink_broadcast + __netlink_kernel_create + netlink_kernel_release + netlink_unicast + __next_zones_zonelist + nla_find + nla_put + nla_reserve_64bit + nla_reserve + __nla_validate + __nlmsg_put + no_llseek + nonseekable_open + noop_llseek + nr_cpu_ids + nr_ipi_get + nr_irqs + ns_to_timespec64 + __num_online_cpus + nvmem_cell_get + nvmem_cell_put + nvmem_cell_read + nvmem_cell_read_u32 + nvmem_cell_write + nvmem_device_read + nvmem_device_write + of_address_to_resource + of_alias_get_id + of_clk_add_hw_provider + of_clk_add_provider + of_clk_del_provider + of_clk_hw_simple_get + of_clk_src_simple_get + of_count_phandle_with_args + of_cpufreq_cooling_register + of_cpu_node_to_id + of_devfreq_cooling_register + of_device_get_match_data + of_device_is_available + of_device_is_compatible + of_dma_configure_id + of_dma_controller_free + of_dma_controller_register + of_dma_is_coherent + of_drm_find_panel + of_find_compatible_node + of_find_device_by_node + of_find_i2c_device_by_node + of_find_matching_node_and_match + of_find_node_by_name + of_find_node_by_phandle + of_find_node_opts_by_path + of_find_node_with_property + of_find_property + of_fwnode_ops + of_genpd_add_provider_onecell + of_genpd_del_provider + of_get_address + of_get_child_by_name + of_get_cpu_node + of_get_named_gpio_flags + of_get_next_available_child + of_get_next_child + of_get_next_parent + of_get_property + of_get_regulator_init_data + of_graph_get_next_endpoint + of_graph_get_port_parent + of_graph_get_remote_endpoint + of_graph_is_present + of_graph_parse_endpoint + of_hwspin_lock_get_id + of_icc_get + of_icc_xlate_onecell + of_iomap + of_irq_find_parent + of_irq_get + of_irq_get_byname + of_irq_parse_one + of_match_device + of_match_node + of_n_addr_cells + of_node_name_eq + of_n_size_cells + of_parse_phandle + of_parse_phandle_with_args + of_parse_phandle_with_fixed_args + of_phandle_iterator_init + of_phandle_iterator_next + of_phy_simple_xlate + of_platform_depopulate + of_platform_device_create + of_platform_device_destroy + of_platform_populate + of_property_count_elems_of_size + of_property_match_string + of_property_read_string + of_property_read_string_helper + of_property_read_u32_index + of_property_read_u64_index + of_property_read_variable_u16_array + of_property_read_variable_u32_array + of_property_read_variable_u8_array + of_prop_next_string + of_prop_next_u32 + of_reserved_mem_device_init_by_idx + of_reserved_mem_device_release + of_reserved_mem_lookup + of_root + of_thermal_get_ntrips + of_thermal_get_trip_points + of_thermal_is_trip_valid + of_translate_address + on_each_cpu + oops_in_progress + overflowuid + page_endio + page_mapping + __page_pinner_migration_failed + panic + panic_notifier_list + panic_timeout + param_get_int + param_ops_bool + param_ops_int + param_ops_uint + param_set_bool + pause_cpus + pci_alloc_irq_vectors_affinity + pci_assign_resource + pci_bus_type + pci_clear_master + pci_device_group + pci_dev_present + pci_disable_device + pcie_capability_read_word + pci_enable_device + pci_find_ext_capability + pci_free_irq_vectors + pci_get_device + pci_host_probe + pci_iomap + pci_irq_vector + pci_load_and_free_saved_state + pci_load_saved_state + pci_msi_create_irq_domain + pci_msi_mask_irq + pci_msi_unmask_irq + pci_read_config_dword + pci_read_config_word + __pci_register_driver + pci_release_region + pci_request_region + pci_restore_state + pci_save_state + pci_set_master + pci_set_power_state + pci_store_saved_state + pci_unregister_driver + pci_walk_bus + pci_write_config_dword + __per_cpu_offset + per_cpu_ptr_to_phys + perf_aux_output_begin + perf_aux_output_end + perf_aux_output_flag + perf_event_create_kernel_counter + perf_event_disable + perf_event_enable + perf_event_read_local + perf_event_read_value + perf_event_release_kernel + perf_get_aux + perf_pmu_register + perf_pmu_unregister + perf_trace_buf_alloc + perf_trace_run_bpf_submit + pfn_valid + phy_calibrate + phy_exit + phy_init + phy_power_off + phy_power_on + phy_set_mode_ext + pick_highest_pushable_task + pid_nr_ns + pid_task + pinconf_generic_dt_node_to_map + pinctrl_dev_get_drvdata + pinctrl_force_default + pinctrl_force_sleep + pinctrl_lookup_state + pinctrl_pm_select_default_state + pinctrl_pm_select_sleep_state + pinctrl_select_state + pinctrl_utils_free_map + platform_bus_type + platform_device_add + platform_device_alloc + platform_device_del + platform_device_put + platform_device_register_full + platform_device_unregister + __platform_driver_register + platform_driver_unregister + platform_get_irq + platform_get_irq_byname + platform_get_resource + platform_get_resource_byname + platform_irq_count + pm_clk_add + pm_clk_create + pm_clk_destroy + pm_clk_resume + pm_clk_suspend + pm_genpd_add_subdomain + pm_genpd_init + pm_genpd_remove + pm_genpd_remove_subdomain + pm_power_off + __pm_relax + pm_relax + pm_runtime_allow + pm_runtime_barrier + __pm_runtime_disable + pm_runtime_enable + pm_runtime_forbid + pm_runtime_force_resume + pm_runtime_force_suspend + __pm_runtime_idle + pm_runtime_irq_safe + pm_runtime_no_callbacks + __pm_runtime_resume + pm_runtime_set_autosuspend_delay + __pm_runtime_set_status + __pm_runtime_suspend + __pm_runtime_use_autosuspend + __pm_stay_awake + pm_stay_awake + pm_wakeup_dev_event + pm_wakeup_ws_event + power_supply_changed + power_supply_get_by_name + power_supply_get_drvdata + power_supply_get_property + power_supply_put + power_supply_register + power_supply_reg_notifier + power_supply_set_property + power_supply_unregister + power_supply_unreg_notifier + prandom_u32 + preempt_schedule + preempt_schedule_notrace + prepare_to_wait_event + print_hex_dump + printk + printk_deferred + proc_dointvec + proc_dointvec_minmax + proc_dostring + proc_douintvec_minmax + proto_register + proto_unregister + __pskb_pull_tail + put_device + put_disk + put_iova_domain + __put_page + put_pid + put_sg_io_hdr + __put_task_struct + put_unused_fd + pwm_apply_state + pwmchip_add + pwmchip_remove + qcom_smem_state_get + qcom_smem_state_register + qcom_smem_state_unregister + qcom_smem_state_update_bits + queue_delayed_work_on + queue_work_on + radix_tree_insert + radix_tree_iter_delete + radix_tree_lookup + radix_tree_next_chunk + ___ratelimit + rational_best_approximation + raw_notifier_call_chain + raw_notifier_chain_register + raw_notifier_chain_unregister + _raw_read_lock + _raw_read_lock_bh + _raw_read_lock_irq + _raw_read_lock_irqsave + _raw_read_unlock + _raw_read_unlock_bh + _raw_read_unlock_irq + _raw_read_unlock_irqrestore + _raw_spin_lock + _raw_spin_lock_bh + _raw_spin_lock_irq + _raw_spin_lock_irqsave + _raw_spin_trylock + _raw_spin_trylock_bh + _raw_spin_unlock + _raw_spin_unlock_bh + _raw_spin_unlock_irq + _raw_spin_unlock_irqrestore + _raw_write_lock + _raw_write_lock_bh + _raw_write_lock_irq + _raw_write_lock_irqsave + _raw_write_unlock + _raw_write_unlock_bh + _raw_write_unlock_irq + _raw_write_unlock_irqrestore + rb_erase + rb_first + rb_insert_color + rb_last + rb_next + rb_prev + __rcu_read_lock + __rcu_read_unlock + rdev_get_drvdata + reboot_mode + refcount_dec_and_lock + refcount_dec_not_one + refcount_warn_saturate + register_blkdev + __register_chrdev + register_chrdev_region + register_console + register_die_notifier + register_ftrace_export + register_kretprobe + register_memory_notifier + register_module_notifier + register_pm_notifier + register_reboot_notifier + register_restart_handler + __register_rpmsg_driver + register_shrinker + register_syscore_ops + register_sysctl_table + regmap_bulk_read + regmap_bulk_write + regmap_check_range_table + regmap_field_read + regmap_field_update_bits_base + __regmap_init + regmap_mmio_detach_clk + regmap_read + regmap_update_bits_base + regmap_write + regulator_allow_bypass + regulator_bulk_disable + regulator_count_voltages + regulator_disable + regulator_disable_deferred + regulator_enable + regulator_force_disable + regulator_get + regulator_get_drvdata + regulator_get_mode + regulator_get_voltage + regulator_get_voltage_rdev + regulator_is_enabled + regulator_is_supported_voltage + regulator_list_voltage_linear + regulator_notifier_call_chain + regulator_put + regulator_register_notifier + regulator_set_current_limit + regulator_set_load + regulator_set_mode + regulator_set_voltage + regulator_unregister_notifier + release_firmware + release_sock + remap_pfn_range + remove_cpu + remove_memory_subsection + report_iommu_fault + request_any_context_irq + request_firmware + request_firmware_into_buf + request_firmware_nowait + __request_module + __request_percpu_irq + request_threaded_irq + resched_curr + reset_control_assert + reset_control_deassert + resume_cpus + revalidate_disk_size + rfkill_alloc + rfkill_destroy + rfkill_init_sw_state + rfkill_register + rfkill_unregister + rndis_deregister + rndis_free_response + rndis_get_next_response + rndis_msg_parser + rndis_register + rndis_set_host_mac + rndis_set_param_dev + rndis_set_param_medium + rndis_set_param_vendor + rndis_signal_connect + rndis_uninit + root_task_group + round_jiffies_relative + rpmsg_get_signals + rpmsg_poll + rpmsg_register_device + rpmsg_send + rpmsg_set_signals + rpmsg_trysend + rpmsg_unregister_device + rproc_add + rproc_add_subdev + rproc_alloc + rproc_boot + rproc_coredump_add_custom_segment + rproc_coredump_add_segment + rproc_coredump_set_elf_info + rproc_coredump_using_sections + rproc_del + rproc_free + rproc_get_by_child + rproc_get_by_phandle + rproc_put + rproc_remove_subdev + rproc_report_crash + rproc_shutdown + rtc_class_close + rtc_class_open + rtc_read_time + __rtc_register_device + rtc_time64_to_tm + rtc_tm_to_time64 + rtc_update_irq + rtc_valid_tm + runqueues + sched_clock + sched_feat_keys + sched_feat_names + sched_setattr + sched_set_fifo + sched_set_normal + sched_setscheduler + sched_setscheduler_nocheck + sched_uclamp_used + schedule + schedule_timeout + scnprintf + scsi_autopm_get_device + scsi_autopm_put_device + scsi_block_when_processing_errors + scsi_command_size_tbl + scsi_compat_ioctl + scsi_device_get + scsi_device_put + scsi_device_quiesce + scsi_ioctl + scsi_ioctl_block_when_processing_errors + __scsi_iterate_devices + scsi_normalize_sense + __scsi_print_sense + scsi_print_sense_hdr + scsi_register_interface + scsi_remove_device + sdev_prefix_printk + __sdhci_add_host + sdhci_add_host + sdhci_cleanup_host + sdhci_cqe_disable + sdhci_cqe_enable + sdhci_cqe_irq + sdhci_enable_clk + sdhci_get_property + sdhci_pltfm_free + sdhci_pltfm_init + sdhci_remove_host + sdhci_reset + sdhci_set_bus_width + sdhci_set_power_noreg + sdhci_setup_host + seq_buf_printf + seq_lseek + seq_open + seq_printf + seq_putc + seq_puts + seq_read + seq_release + set_cpus_allowed_ptr + set_normalized_timespec64 + set_page_dirty_lock + __SetPageMovable + set_task_cpu + set_user_nice + sg_alloc_table + sg_alloc_table_from_pages + sg_free_table + sg_init_one + sg_init_table + sg_miter_next + sg_miter_start + sg_miter_stop + sg_next + __sg_page_iter_dma_next + __sg_page_iter_next + __sg_page_iter_start + sg_scsi_ioctl + show_regs + sigprocmask + si_meminfo + simple_attr_open + simple_attr_release + simple_open + simple_read_from_buffer + simple_write_to_buffer + single_open + single_release + si_swapinfo + sk_alloc + skb_clone + skb_copy_bits + skb_copy_datagram_iter + skb_dequeue + skb_free_datagram + __skb_pad + skb_push + skb_put + skb_queue_purge + skb_queue_tail + skb_recv_datagram + skb_set_owner_w + skb_store_bits + skb_trim + sk_free + skip_spaces + smp_call_function_single + snd_pcm_format_width + snd_soc_add_component_controls + snd_soc_info_volsw + snd_soc_register_component + snd_soc_unregister_component + snd_usb_enable_audio_stream + snprintf + soc_device_register + soc_device_unregister + sock_alloc_send_skb + sock_create_kern + sock_gettstamp + sock_init_data + sock_no_accept + sock_no_listen + sock_no_mmap + sock_no_sendpage + sock_no_shutdown + sock_no_socketpair + sock_queue_rcv_skb + sock_register + sock_release + sock_setsockopt + sock_unregister + sort + __spi_alloc_controller + spi_register_controller + spi_unregister_controller + spmi_controller_add + spmi_controller_alloc + spmi_controller_remove + __spmi_driver_register + spmi_ext_register_read + spmi_ext_register_readl + spmi_ext_register_write + spmi_ext_register_writel + spmi_register_read + spmi_register_write + spmi_register_zero_write + sprintf + srcu_init_notifier_head + srcu_notifier_call_chain + srcu_notifier_chain_register + srcu_notifier_chain_unregister + __srcu_read_lock + __srcu_read_unlock + sscanf + __stack_chk_fail + __stack_chk_guard + static_key_disable + stop_machine + stop_one_cpu_nowait + strcmp + strcpy + strim + strlcat + strlcpy + strlen + strncasecmp + strnchr + strncmp + strncpy + strncpy_from_user + strnlen + strnstr + strpbrk + strrchr + strscpy + strsep + strstr + __sw_hweight32 + __sw_hweight64 + __sw_hweight8 + sync_file_create + sync_file_get_fence + synchronize_irq + synchronize_rcu + synchronize_srcu + syscon_node_to_regmap + syscon_regmap_lookup_by_phandle + sysctl_sched_features + sysctl_vals + sysfs_add_file_to_group + sysfs_add_link_to_group + sysfs_create_bin_file + sysfs_create_file_ns + sysfs_create_files + sysfs_create_group + sysfs_create_link + sysfs_emit + __sysfs_match_string + sysfs_notify + sysfs_remove_bin_file + sysfs_remove_file_from_group + sysfs_remove_file_ns + sysfs_remove_files + sysfs_remove_group + sysfs_remove_link + sysfs_remove_link_from_group + sysfs_streq + sysrq_mask + system_freezable_wq + system_highpri_wq + system_unbound_wq + system_wq + sys_tz + task_active_pid_ns + __tasklet_hi_schedule + tasklet_init + tasklet_kill + __tasklet_schedule + tasklet_setup + tasklist_lock + task_may_not_preempt + __task_pid_nr_ns + __task_rq_lock + thermal_cooling_device_unregister + thermal_of_cooling_device_register + thermal_pressure + thermal_zone_device_enable + thermal_zone_device_register + thermal_zone_device_unregister + thermal_zone_device_update + thermal_zone_get_slope + thermal_zone_get_temp + thermal_zone_get_zone_by_name + thermal_zone_of_sensor_register + thermal_zone_of_sensor_unregister + tick_nohz_get_sleep_length + time64_to_tm + topology_set_thermal_pressure + total_swapcache_pages + trace_array_get_by_name + trace_array_put + trace_array_set_clr_event + trace_event_buffer_commit + trace_event_buffer_reserve + trace_event_ignore_this_pid + trace_event_raw_init + trace_event_reg + trace_handle_return + __traceiter_android_rvh_account_irq + __traceiter_android_rvh_build_perf_domains + __traceiter_android_rvh_can_migrate_task + __traceiter_android_rvh_check_preempt_wakeup + __traceiter_android_rvh_cpu_cgroup_attach + __traceiter_android_rvh_cpu_cgroup_online + __traceiter_android_rvh_dequeue_task + __traceiter_android_rvh_enqueue_task + __traceiter_android_rvh_find_busiest_queue + __traceiter_android_rvh_find_lowest_rq + __traceiter_android_rvh_flush_task + __traceiter_android_rvh_migrate_queued_task + __traceiter_android_rvh_new_task_stats + __traceiter_android_rvh_replace_next_task_fair + __traceiter_android_rvh_resume_cpus + __traceiter_android_rvh_sched_cpu_dying + __traceiter_android_rvh_sched_cpu_starting + __traceiter_android_rvh_sched_exec + __traceiter_android_rvh_sched_fork + __traceiter_android_rvh_sched_fork_init + __traceiter_android_rvh_sched_newidle_balance + __traceiter_android_rvh_sched_nohz_balancer_kick + __traceiter_android_rvh_sched_setaffinity + __traceiter_android_rvh_schedule + __traceiter_android_rvh_select_task_rq_fair + __traceiter_android_rvh_select_task_rq_rt + __traceiter_android_rvh_set_gfp_zone_flags + __traceiter_android_rvh_set_readahead_gfp_mask + __traceiter_android_rvh_set_skip_swapcache_flags + __traceiter_android_rvh_set_task_cpu + __traceiter_android_rvh_tick_entry + __traceiter_android_rvh_try_to_wake_up + __traceiter_android_rvh_try_to_wake_up_success + __traceiter_android_rvh_ttwu_cond + __traceiter_android_rvh_update_cpu_capacity + __traceiter_android_rvh_update_cpus_allowed + __traceiter_android_rvh_update_misfit_status + __traceiter_android_rvh_wake_up_new_task + __traceiter_android_vh_allow_domain_state + __traceiter_android_vh_binder_restore_priority + __traceiter_android_vh_binder_set_priority + __traceiter_android_vh_binder_wakeup_ilocked + __traceiter_android_vh_cpu_idle_enter + __traceiter_android_vh_cpu_idle_exit + __traceiter_android_vh_ftrace_dump_buffer + __traceiter_android_vh_ftrace_format_check + __traceiter_android_vh_ftrace_oops_enter + __traceiter_android_vh_ftrace_oops_exit + __traceiter_android_vh_ftrace_size_check + __traceiter_android_vh_iommu_setup_dma_ops + __traceiter_android_vh_ipi_stop + __traceiter_android_vh_jiffies_update + __traceiter_android_vh_printk_hotplug + __traceiter_android_vh_scheduler_tick + __traceiter_android_vh_show_max_freq + __traceiter_android_vh_show_resume_epoch_val + __traceiter_android_vh_show_suspend_epoch_val + __traceiter_android_vh_timer_calc_index + __traceiter_android_vh_ufs_check_int_errors + __traceiter_android_vh_ufs_compl_command + __traceiter_android_vh_ufs_send_command + __traceiter_binder_transaction_received + __traceiter_cpu_frequency_limits + __traceiter_cpu_idle + __traceiter_ipi_entry + __traceiter_ipi_raise + __traceiter_rwmmio_post_read + __traceiter_rwmmio_read + __traceiter_rwmmio_write + __traceiter_suspend_resume + __tracepoint_android_rvh_account_irq + __tracepoint_android_rvh_build_perf_domains + __tracepoint_android_rvh_can_migrate_task + __tracepoint_android_rvh_check_preempt_wakeup + __tracepoint_android_rvh_cpu_cgroup_attach + __tracepoint_android_rvh_cpu_cgroup_online + __tracepoint_android_rvh_dequeue_task + __tracepoint_android_rvh_enqueue_task + __tracepoint_android_rvh_find_busiest_queue + __tracepoint_android_rvh_find_lowest_rq + __tracepoint_android_rvh_flush_task + __tracepoint_android_rvh_migrate_queued_task + __tracepoint_android_rvh_new_task_stats + __tracepoint_android_rvh_replace_next_task_fair + __tracepoint_android_rvh_resume_cpus + __tracepoint_android_rvh_sched_cpu_dying + __tracepoint_android_rvh_sched_cpu_starting + __tracepoint_android_rvh_sched_exec + __tracepoint_android_rvh_sched_fork + __tracepoint_android_rvh_sched_fork_init + __tracepoint_android_rvh_sched_newidle_balance + __tracepoint_android_rvh_sched_nohz_balancer_kick + __tracepoint_android_rvh_sched_setaffinity + __tracepoint_android_rvh_schedule + __tracepoint_android_rvh_select_task_rq_fair + __tracepoint_android_rvh_select_task_rq_rt + __tracepoint_android_rvh_set_gfp_zone_flags + __tracepoint_android_rvh_set_readahead_gfp_mask + __tracepoint_android_rvh_set_skip_swapcache_flags + __tracepoint_android_rvh_set_task_cpu + __tracepoint_android_rvh_tick_entry + __tracepoint_android_rvh_try_to_wake_up + __tracepoint_android_rvh_try_to_wake_up_success + __tracepoint_android_rvh_ttwu_cond + __tracepoint_android_rvh_update_cpu_capacity + __tracepoint_android_rvh_update_cpus_allowed + __tracepoint_android_rvh_update_misfit_status + __tracepoint_android_rvh_wake_up_new_task + __tracepoint_android_vh_allow_domain_state + __tracepoint_android_vh_binder_restore_priority + __tracepoint_android_vh_binder_set_priority + __tracepoint_android_vh_binder_wakeup_ilocked + __tracepoint_android_vh_cpu_idle_enter + __tracepoint_android_vh_cpu_idle_exit + __tracepoint_android_vh_ftrace_dump_buffer + __tracepoint_android_vh_ftrace_format_check + __tracepoint_android_vh_ftrace_oops_enter + __tracepoint_android_vh_ftrace_oops_exit + __tracepoint_android_vh_ftrace_size_check + __tracepoint_android_vh_iommu_setup_dma_ops + __tracepoint_android_vh_ipi_stop + __tracepoint_android_vh_jiffies_update + __tracepoint_android_vh_printk_hotplug + __tracepoint_android_vh_scheduler_tick + __tracepoint_android_vh_show_max_freq + __tracepoint_android_vh_show_resume_epoch_val + __tracepoint_android_vh_show_suspend_epoch_val + __tracepoint_android_vh_timer_calc_index + __tracepoint_android_vh_ufs_check_int_errors + __tracepoint_android_vh_ufs_compl_command + __tracepoint_android_vh_ufs_send_command + __tracepoint_binder_transaction_received + __tracepoint_cpu_frequency_limits + __tracepoint_cpu_idle + __tracepoint_ipi_entry + __tracepoint_ipi_raise + tracepoint_probe_register + tracepoint_probe_register_prio + tracepoint_probe_unregister + __tracepoint_rwmmio_post_read + __tracepoint_rwmmio_read + __tracepoint_rwmmio_write + __tracepoint_suspend_resume + trace_print_array_seq + trace_print_flags_seq + trace_print_symbols_seq + trace_raw_output_prep + trace_seq_printf + trace_seq_putc + try_module_get + try_wait_for_completion + tty_flip_buffer_push + __tty_insert_flip_char + tty_insert_flip_string_fixed_flag + uart_add_one_port + uart_console_device + uart_console_write + uart_get_baud_rate + uart_insert_char + uart_parse_options + uart_register_driver + uart_remove_one_port + uart_resume_port + uart_set_options + uart_suspend_port + uart_try_toggle_sysrq + uart_unregister_driver + uart_update_timeout + uart_write_wakeup + uclamp_eff_value + ucsi_connector_change + ucsi_create + ucsi_destroy + ucsi_get_drvdata + ucsi_register + ucsi_set_drvdata + ucsi_unregister + __udelay + ufshcd_auto_hibern8_update + ufshcd_dme_get_attr + ufshcd_dme_set_attr + ufshcd_dump_regs + ufshcd_fixup_dev_quirks + ufshcd_get_local_unipro_ver + ufshcd_pltfrm_init + ufshcd_pltfrm_resume + ufshcd_pltfrm_runtime_idle + ufshcd_pltfrm_runtime_resume + ufshcd_pltfrm_runtime_suspend + ufshcd_pltfrm_suspend + ufshcd_query_attr + ufshcd_query_attr_retry + ufshcd_query_descriptor_retry + ufshcd_query_flag + ufshcd_read_desc_param + ufshcd_remove + ufshcd_shutdown + ufshcd_uic_hibern8_enter + ufshcd_uic_hibern8_exit + __uio_register_device + uio_unregister_device + unlock_page + unregister_blkdev + __unregister_chrdev + unregister_chrdev_region + unregister_console + unregister_die_notifier + unregister_ftrace_export + unregister_kretprobe + unregister_module_notifier + unregister_pm_notifier + unregister_reboot_notifier + unregister_restart_handler + unregister_rpmsg_driver + unregister_shrinker + unregister_syscore_ops + update_devfreq + update_rq_clock + up_read + up_write + usb_add_phy_dev + usb_alloc_coherent + usb_alloc_dev + usb_alloc_urb + usb_assign_descriptors + usb_composite_setup_continue + usb_control_msg + usb_deregister + usb_ep_alloc_request + usb_ep_autoconfig + usb_ep_dequeue + usb_ep_disable + usb_ep_enable + usb_ep_free_request + usb_ep_queue + usb_ep_set_halt + usb_find_common_endpoints + usb_free_all_descriptors + usb_free_coherent + usb_free_urb + usb_function_register + usb_function_unregister + usb_gadget_wakeup + usb_ifnum_to_if + usb_interface_id + usb_phy_set_charger_current + usb_poison_urb + usb_put_dev + usb_put_function_instance + usb_register_driver + usb_register_notify + usb_remove_phy + usb_role_switch_find_by_fwnode + usb_role_switch_get_drvdata + usb_role_switch_register + usb_role_switch_set_role + usb_role_switch_unregister + usb_set_device_state + usb_speed_string + usb_string_id + usb_submit_urb + usb_unregister_notify + __usecs_to_jiffies + usleep_range + v4l2_compat_ioctl32 + v4l2_ctrl_handler_free + v4l2_device_register + v4l2_device_unregister + vabits_actual + vchan_dma_desc_free_list + vchan_find_desc + vchan_init + vchan_tx_desc_free + vchan_tx_submit + vfree + video_devdata + video_device_release_empty + video_ioctl2 + __video_register_device + video_unregister_device + vmalloc + vmalloc_nr_pages + vmalloc_to_page + vmalloc_to_pfn + vmap + vmf_insert_pfn + vm_insert_page + vm_iomap_memory + vm_map_pages + vm_node_stat + vm_zone_stat + vscnprintf + vsnprintf + vunmap + vzalloc + wait_for_completion + wait_for_completion_interruptible + wait_for_completion_interruptible_timeout + wait_for_completion_killable + wait_for_completion_timeout + __wake_up + wake_up_if_idle + wake_up_process + wakeup_source_add + wakeup_source_register + wakeup_source_remove + wakeup_source_unregister + __warn_printk + ww_mutex_lock + ww_mutex_unlock + __xa_alloc + xa_destroy + xa_erase + xa_find + xa_find_after + xa_load + xa_store + xhci_alloc_command + xhci_alloc_erst + xhci_free_command + xhci_get_endpoint_index + xhci_queue_stop_endpoint + xhci_ring_alloc + xhci_ring_cmd_db + xhci_ring_free + xhci_trb_virt_to_dma + zone_watermark_ok_safe diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 index e0ffb8869dc0..3f0266dc84b7 100644 --- a/build.config.gki.aarch64 +++ b/build.config.gki.aarch64 @@ -19,6 +19,7 @@ android/abi_gki_aarch64_exynos android/abi_gki_aarch64_mtk android/abi_gki_aarch64_xiaomi android/abi_gki_aarch64_fips140 +android/abi_gki_aarch64_vivo " FILES="${FILES} From c7c351ab3f6e342d1bae7c19f39fdf7d12da1f9a Mon Sep 17 00:00:00 2001 From: Shaleen Agrawal Date: Wed, 23 Jun 2021 11:10:57 -0700 Subject: [PATCH 35/60] ANDROID: sched: add restricted tracehooks for 32bit execve Pre and post tracepoints in force_compatible_cpus_allowed_ptr() need to be restricted hooks so that they can sleep. The old non-restricted versions need to stay in place temporarily for KMI stability. They will be removed by aosp/1742588. Bug: 187917024 Change-Id: If630554b1c8fa2e8ccb79c89945c55e17756e6a8 Signed-off-by: Shaleen Agrawal --- drivers/android/vendor_hooks.c | 2 ++ include/trace/hooks/sched.h | 7 +++++++ kernel/sched/core.c | 2 ++ 3 files changed, 11 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 2cff702df817..b8fab55cbc16 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -331,3 +331,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sha256); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_expandkey); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_encrypt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_decrypt); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_force_compatible_pre); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_force_compatible_post); diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index 622454f6f8c8..8c2fdd2f76c6 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -378,6 +378,13 @@ DECLARE_HOOK(android_vh_force_compatible_post, TP_PROTO(void *unused), TP_ARGS(unused)); +DECLARE_RESTRICTED_HOOK(android_rvh_force_compatible_pre, + TP_PROTO(void *unused), + TP_ARGS(unused), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_force_compatible_post, + TP_PROTO(void *unused), + TP_ARGS(unused), 1); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_SCHED_H */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 332cfe2e5415..64288d005bb4 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2106,6 +2106,7 @@ void force_compatible_cpus_allowed_ptr(struct task_struct *p) * lock to ensure that the migration succeeds. */ trace_android_vh_force_compatible_pre(NULL); + trace_android_rvh_force_compatible_pre(NULL); cpus_read_lock(); if (!cpumask_available(new_mask)) goto out_set_mask; @@ -2131,6 +2132,7 @@ void force_compatible_cpus_allowed_ptr(struct task_struct *p) out_free_mask: cpus_read_unlock(); trace_android_vh_force_compatible_post(NULL); + trace_android_rvh_force_compatible_post(NULL); free_cpumask_var(new_mask); } From a985701859e4e310ee02dc641a3e0be85bb08e86 Mon Sep 17 00:00:00 2001 From: Shaleen Agrawal Date: Wed, 23 Jun 2021 11:56:41 -0700 Subject: [PATCH 36/60] ANDROID: abi_gki_aarch64_qcom: Add additional symbols for 32bit execve Additional restricted vendor hooks have been added. Leaf changes summary: 4 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 2 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 2 Added variables 2 Added functions: [A] 'function int __traceiter_android_rvh_force_compatible_post(void*, void*)' [A] 'function int __traceiter_android_rvh_force_compatible_pre(void*, void*)' 2 Added variables: [A] 'tracepoint __tracepoint_android_rvh_force_compatible_post' [A] 'tracepoint __tracepoint_android_rvh_force_compatible_pre' Bug: 187917024 Change-Id: Ib9cd475ed63448f3befa581b26bcdfb4a75e8faf Signed-off-by: Shaleen Agrawal --- android/abi_gki_aarch64.xml | 232 +++++++++++++++++++---------------- android/abi_gki_aarch64_qcom | 4 + 2 files changed, 128 insertions(+), 108 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 6f16d3f2df7e..4622189a0ba7 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -247,6 +247,8 @@ + + @@ -4757,6 +4759,8 @@ + + @@ -45711,6 +45715,8 @@ + + @@ -45967,6 +45973,16 @@ + + + + + + + + + + @@ -62619,7 +62635,7 @@ - + @@ -66905,7 +66921,7 @@ - + @@ -74035,7 +74051,7 @@ - + @@ -85485,7 +85501,7 @@ - + @@ -88086,7 +88102,7 @@ - + @@ -88094,7 +88110,7 @@ - + @@ -92124,7 +92140,7 @@ - + @@ -92132,7 +92148,7 @@ - + @@ -92994,7 +93010,7 @@ - + @@ -93387,7 +93403,7 @@ - + @@ -93414,12 +93430,12 @@ - + - + @@ -93427,7 +93443,7 @@ - + @@ -123287,7 +123303,7 @@ - + @@ -151656,44 +151672,44 @@ - - - + + + - - + + - - - - - + + + + + - - - - + + + + - - - + + + - - + + - - + + - - - + + + @@ -153334,25 +153350,25 @@ - + - - - + + + - + - + - - - + + + @@ -153360,7 +153376,7 @@ - + @@ -153370,9 +153386,9 @@ - - - + + + @@ -153431,12 +153447,12 @@ - - + + - - + + @@ -153444,54 +153460,54 @@ - - + + - - - - + + + + - - - - + + + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - - - - + + + + + - - + + @@ -153506,8 +153522,8 @@ - - + + @@ -173435,7 +173451,7 @@ - + @@ -173647,7 +173663,7 @@ - + @@ -173827,7 +173843,7 @@ - + @@ -174027,7 +174043,7 @@ - + @@ -174481,7 +174497,7 @@ - + @@ -174814,7 +174830,7 @@ - + @@ -174945,7 +174961,7 @@ - + @@ -174953,12 +174969,12 @@ - + - + @@ -188119,17 +188135,6 @@ - - - - - - - - - - - @@ -188205,6 +188210,17 @@ + + + + + + + + + + + @@ -194242,6 +194258,6 @@ diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index a12b3668fd7e..b0073d6b7ba8 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -2431,6 +2431,8 @@ __traceiter_android_rvh_find_busiest_queue __traceiter_android_rvh_find_lowest_rq __traceiter_android_rvh_flush_task + __traceiter_android_rvh_force_compatible_post + __traceiter_android_rvh_force_compatible_pre __traceiter_android_rvh_gic_v3_set_affinity __traceiter_android_rvh_irqs_disable __traceiter_android_rvh_irqs_enable @@ -2525,6 +2527,8 @@ __tracepoint_android_rvh_find_busiest_queue __tracepoint_android_rvh_find_lowest_rq __tracepoint_android_rvh_flush_task + __tracepoint_android_rvh_force_compatible_post + __tracepoint_android_rvh_force_compatible_pre __tracepoint_android_rvh_gic_v3_set_affinity __tracepoint_android_rvh_irqs_disable __tracepoint_android_rvh_irqs_enable From b70055f85a9666e36ee5db73b951236996573fb3 Mon Sep 17 00:00:00 2001 From: Guangming Cao Date: Tue, 22 Jun 2021 12:18:08 +0800 Subject: [PATCH 37/60] ANDROID: iommu: Revise vendor hook param for iova free tracking Iova is identified in the alloc vendor hook by its pfn (iova->pfn_lo) and in free vendor hook by its address (iova->pfn_lo << iova_shift(iovad)). Change alloc vendor hook to use address as well for consistency. Bug: 187861158 Change-Id: I8255f3e5899008b80a9f8ed960e2ba948ba13cc2 Signed-off-by: Guangming Cao --- drivers/iommu/dma-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 0a51e7d7bfea..27f74c12bd02 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -487,7 +487,7 @@ static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain, iova = alloc_iova_fast(iovad, iova_len, dma_limit >> shift, true); - trace_android_vh_iommu_alloc_iova(dev, iova, size); + trace_android_vh_iommu_alloc_iova(dev, (dma_addr_t)iova << shift, size); return (dma_addr_t)iova << shift; } From c0e8aae5c5214e7a4716ea8e76d436b3ec5fcf97 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Mon, 14 Jun 2021 22:31:07 -0700 Subject: [PATCH 38/60] ANDROID: qcom: Add xfrm and skb related symbols Add __xfrm_decode_session, xfrm_lookup, xfrm_output and kfree_skb_list which are needed by rmnet modules. Leaf changes summary: 4 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 4 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 4 Added functions: [A] 'function int __xfrm_decode_session(sk_buff*, flowi*, unsigned int, int)' [A] 'function void kfree_skb_list(sk_buff*)' [A] 'function dst_entry* xfrm_lookup(net*, dst_entry*, const flowi*, const sock*, int)' [A] 'function int xfrm_output(sock*, sk_buff*)' Bug: 191435348 Change-Id: Ib61aaf84ed145c3f87015c890f6c9e6d5ae722f6 Signed-off-by: Subash Abhinov Kasiviswanathan --- android/abi_gki_aarch64.xml | 1454 +++++++++++++++++----------------- android/abi_gki_aarch64_qcom | 4 + 2 files changed, 746 insertions(+), 712 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 4622189a0ba7..16cf2ac581a9 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -437,6 +437,7 @@ + @@ -2425,6 +2426,7 @@ + @@ -4689,6 +4691,8 @@ + + @@ -9785,69 +9789,69 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -11757,45 +11761,45 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -12079,24 +12083,24 @@ - + - + - + - + - + - + - + @@ -13458,137 +13462,137 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -15132,7 +15136,7 @@ - + @@ -15589,9 +15593,9 @@ - + - + @@ -15617,127 +15621,127 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -18894,53 +18898,53 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -19478,66 +19482,66 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -21759,66 +21763,66 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -23967,9 +23971,9 @@ - + - + @@ -25744,24 +25748,24 @@ - + - + - + - + - + - + - + @@ -27384,12 +27388,12 @@ - + - + - + @@ -27497,7 +27501,7 @@ - + @@ -28285,137 +28289,137 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -29794,24 +29798,24 @@ - + - + - + - + - + - + - + @@ -35881,24 +35885,24 @@ - + - + - + - + - + - + - + @@ -36733,226 +36737,226 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -37071,178 +37075,178 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -38598,140 +38602,140 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -38752,27 +38756,27 @@ - + - + - + - + - + - + - + - + @@ -38780,109 +38784,109 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -39319,10 +39323,10 @@ - + - + @@ -102727,37 +102731,37 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -130395,14 +130399,6 @@ - - - - - - - - @@ -130422,6 +130418,14 @@ + + + + + + + + @@ -142688,21 +142692,21 @@ - + - + - + - + - + - + @@ -142801,69 +142805,69 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -146717,26 +146721,26 @@ - - - + + + - - - + + + - - - + + + - - - - - + + + + + @@ -150123,12 +150127,6 @@ - - - - - - @@ -150162,69 +150160,75 @@ + + + + + + - - + + - - - + + + - - - + + + - - - + + + - - - - + + + + - - - - + + + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + @@ -150243,8 +150247,8 @@ - - + + @@ -150312,26 +150316,26 @@ - - + + - - - + + + - - - - - - - + + + + + + + @@ -171382,6 +171386,10 @@ + + + + @@ -177877,54 +177885,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -177981,6 +177941,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -178439,62 +178502,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -185516,12 +185524,34 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index b0073d6b7ba8..1f68637ca03d 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -1261,6 +1261,7 @@ kfree_const kfree_sensitive kfree_skb + kfree_skb_list kick_all_cpus_sync kill_anon_super kill_fasync @@ -2916,6 +2917,9 @@ xa_find_after xa_load xa_store + __xfrm_decode_session + xfrm_lookup + xfrm_output xhci_alloc_command xhci_alloc_erst xhci_free_command From cea24faf98681e9a374cc7a77b6ae44f5720b5cf Mon Sep 17 00:00:00 2001 From: Martin Liu Date: Thu, 24 Jun 2021 15:19:02 +0800 Subject: [PATCH 39/60] ANDROID: Update the ABI representation Leaf changes summary: 4 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 2 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 2 Added variables 2 Added functions: [A] 'function int __traceiter_mm_vmscan_direct_reclaim_begin(void*, int, gfp_t)' [A] 'function int __traceiter_mm_vmscan_direct_reclaim_end(void*, unsigned long int)' 2 Added variables: [A] 'tracepoint __tracepoint_mm_vmscan_direct_reclaim_begin' [A] 'tracepoint __tracepoint_mm_vmscan_direct_reclaim_end' Bug: 190795589 Signed-off-by: Martin Liu Change-Id: Ibabb7f6ffdc298ee8ff860457e0fada402ce1a34 --- android/abi_gki_aarch64.xml | 95 +++++++++++++++++++-------------- android/abi_gki_aarch64_generic | 6 +++ 2 files changed, 62 insertions(+), 39 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 16cf2ac581a9..b3cc2315644e 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -402,6 +402,8 @@ + + @@ -4923,6 +4925,8 @@ + + @@ -62639,7 +62643,7 @@ - + @@ -66925,7 +66929,7 @@ - + @@ -74055,7 +74059,7 @@ - + @@ -85505,7 +85509,7 @@ - + @@ -88106,7 +88110,7 @@ - + @@ -88114,7 +88118,7 @@ - + @@ -92144,7 +92148,7 @@ - + @@ -92152,7 +92156,7 @@ - + @@ -93014,7 +93018,7 @@ - + @@ -93407,7 +93411,7 @@ - + @@ -93434,12 +93438,12 @@ - + - + @@ -93447,7 +93451,7 @@ - + @@ -123307,7 +123311,7 @@ - + @@ -168197,12 +168201,25 @@ - - + + + + - - + + + + + + + + + + + + + @@ -173459,7 +173476,7 @@ - + @@ -173671,7 +173688,7 @@ - + @@ -173851,7 +173868,7 @@ - + @@ -174051,7 +174068,7 @@ - + @@ -174505,7 +174522,7 @@ - + @@ -174838,7 +174855,7 @@ - + @@ -174969,7 +174986,7 @@ - + @@ -174977,12 +174994,12 @@ - + - + @@ -188165,6 +188182,17 @@ + + + + + + + + + + + @@ -188240,17 +188268,6 @@ - - - - - - - - - - - @@ -194288,6 +194305,6 @@ diff --git a/android/abi_gki_aarch64_generic b/android/abi_gki_aarch64_generic index 4454bb1dfd17..edfb40d1cdbb 100644 --- a/android/abi_gki_aarch64_generic +++ b/android/abi_gki_aarch64_generic @@ -1733,6 +1733,7 @@ sscanf __stack_chk_fail __stack_chk_guard + static_key_disable static_key_slow_dec static_key_slow_inc stop_machine @@ -1773,6 +1774,7 @@ synchronize_net synchronize_rcu syscon_regmap_lookup_by_phandle + sysctl_sched_features sysctl_sched_latency sysfs_add_file_to_group sysfs_create_file_ns @@ -1891,6 +1893,8 @@ __traceiter_dwc3_readl __traceiter_dwc3_writel __traceiter_gpu_mem_total + __traceiter_mm_vmscan_direct_reclaim_begin + __traceiter_mm_vmscan_direct_reclaim_end __traceiter_pelt_cfs_tp __traceiter_pelt_dl_tp __traceiter_pelt_irq_tp @@ -1958,6 +1962,8 @@ __tracepoint_dwc3_readl __tracepoint_dwc3_writel __tracepoint_gpu_mem_total + __tracepoint_mm_vmscan_direct_reclaim_begin + __tracepoint_mm_vmscan_direct_reclaim_end __tracepoint_pelt_cfs_tp __tracepoint_pelt_dl_tp __tracepoint_pelt_irq_tp From 12902c99962333e1e194fd90f8d63073d6b20f86 Mon Sep 17 00:00:00 2001 From: Martin Liu Date: Wed, 23 Jun 2021 12:20:18 +0800 Subject: [PATCH 40/60] ANDROID: vendor_hooks: Export direct reclaim trace points Get direct reclaim info. Bug: 190795589 Signed-off-by: Martin Liu Change-Id: Ie66a3c87484a364a918c19b8e044c82f1afd6749 --- mm/vmscan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index d23a602e7d15..c5eecab35226 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -66,6 +66,9 @@ #undef CREATE_TRACE_POINTS #include +EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_begin); +EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_end); + struct scan_control { /* How many pages shrink_list() should reclaim */ unsigned long nr_to_reclaim; From eabe9707f264c859d5b0b5b1740a97f8eef97d67 Mon Sep 17 00:00:00 2001 From: zhang chuang Date: Wed, 16 Jun 2021 19:11:38 +0800 Subject: [PATCH 41/60] ANDROID: Add hook to show vendor info for transactions When watchdog or anr occur, we need to read dev/binderfs/binder_logs/proc/pid or dev/binderfs/binder_logs/state node to know the time-consuming information of the binder call. We need to add the time-consuming information of binder transaction. Bug: 190413570 Signed-off-by: zhang chuang Change-Id: I0423d4e821d5cd725a848584133dc7245cbc233a --- drivers/android/binder.c | 1 + drivers/android/vendor_hooks.c | 1 + include/trace/hooks/binder.h | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 3b6d6be5e3b7..fb39c14dd44c 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -5481,6 +5481,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, struct binder_buffer *buffer = t->buffer; spin_lock(&t->lock); + trace_android_vh_binder_print_transaction_info(m, proc, prefix, t); to_proc = t->to_proc; seq_printf(m, "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %d:%d r%d", diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index b8fab55cbc16..9367f3f512d8 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -333,3 +333,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_encrypt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_decrypt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_force_compatible_pre); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_force_compatible_post); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_print_transaction_info); diff --git a/include/trace/hooks/binder.h b/include/trace/hooks/binder.h index ddeb936e8945..afa7b59c5ae2 100644 --- a/include/trace/hooks/binder.h +++ b/include/trace/hooks/binder.h @@ -17,6 +17,7 @@ struct binder_alloc; struct binder_proc; struct binder_thread; struct binder_transaction_data; +struct seq_file; DECLARE_HOOK(android_vh_binder_transaction_init, TP_PROTO(struct binder_transaction *t), TP_ARGS(t)); @@ -65,6 +66,10 @@ DECLARE_HOOK(android_vh_binder_new_ref, DECLARE_HOOK(android_vh_binder_del_ref, TP_PROTO(struct task_struct *proc, uint32_t ref_desc), TP_ARGS(proc, ref_desc)); +DECLARE_HOOK(android_vh_binder_print_transaction_info, + TP_PROTO(struct seq_file *m, struct binder_proc *proc, + const char *prefix, struct binder_transaction *t), + TP_ARGS(m, proc, prefix, t)); /* macro versions of hooks are no longer required */ From d5a092726b54cb7c3fd5546986084bdf2a876c40 Mon Sep 17 00:00:00 2001 From: Huang Yiwei Date: Fri, 25 Jun 2021 20:04:44 +0800 Subject: [PATCH 42/60] ANDROID: GKI: Update abi_gki_aarch64_qcom list for rwsem list add Add the rwsem list add vendor hook symbol which is needed for vendor modules. Bug: 192041655 Signed-off-by: Huang Yiwei Change-Id: I838fbb9d067d940e962eff94e8c875c30e153ee1 --- android/abi_gki_aarch64_qcom | 1 + 1 file changed, 1 insertion(+) diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index 1f68637ca03d..8b4ea28e1073 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -2567,6 +2567,7 @@ __tracepoint_android_rvh_update_misfit_status __tracepoint_android_rvh_wake_up_new_task __tracepoint_android_vh_allow_domain_state + __tracepoint_android_vh_alter_rwsem_list_add __tracepoint_android_vh_binder_restore_priority __tracepoint_android_vh_binder_set_priority __tracepoint_android_vh_binder_transaction_init From 9f8f2ea03ede21d8928793c4be87eeb76d81bc7f Mon Sep 17 00:00:00 2001 From: Thierry Strudel Date: Thu, 24 Jun 2021 17:53:28 -0700 Subject: [PATCH 43/60] ANDROID: power: wakeup_reason: change abort log Logging callback symbolic name is generating too many different messages making Abort analysis miss big trends. Stick to console reported message providing sufficient information. Bug: 120445600 Signed-off-by: Thierry Strudel Change-Id: Ic0ea662a60919454060e3a085aeabd8a4099e0b4 --- drivers/base/power/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index d3c863c0b1b2..2c7250eb1d67 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1234,8 +1234,8 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a error = dpm_run_callback(callback, dev, state, info); if (error) { async_error = error; - log_suspend_abort_reason("Callback failed on %s in %pS returned %d", - dev_name(dev), callback, error); + log_suspend_abort_reason("Device %s failed to %s noirq: error %d", + dev_name(dev), pm_verb(state.event), error); goto Complete; } @@ -1428,8 +1428,8 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as error = dpm_run_callback(callback, dev, state, info); if (error) { async_error = error; - log_suspend_abort_reason("Callback failed on %s in %pS returned %d", - dev_name(dev), callback, error); + log_suspend_abort_reason("Device %s failed to %s late: error %d", + dev_name(dev), pm_verb(state.event), error); goto Complete; } dpm_propagate_wakeup_to_parent(dev); @@ -1701,8 +1701,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) dpm_propagate_wakeup_to_parent(dev); dpm_clear_superiors_direct_complete(dev); } else { - log_suspend_abort_reason("Callback failed on %s in %pS returned %d", - dev_name(dev), callback, error); + log_suspend_abort_reason("Device %s failed to %s: error %d", + dev_name(dev), pm_verb(state.event), error); } device_unlock(dev); From 83d653257a55b8aa8ec3b1f49eaf6a507701a0a3 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 25 Jun 2021 15:48:11 -0700 Subject: [PATCH 44/60] Revert "FROMGIT: scsi: ufs: Utilize Transfer Request List Completion Notification Register" This reverts commit ae618c699cd79a1ec9c3a1c6b379ffb62f1222df. It causes early device being stuck. Bug: 192088222 Signed-off-by: Jaegeuk Kim Change-Id: I5117e7f8aaa9433b74f1531619cdc1b687d02b41 --- drivers/scsi/ufs/ufshcd.c | 52 +++++++++++---------------------------- drivers/scsi/ufs/ufshcd.h | 5 ---- drivers/scsi/ufs/ufshci.h | 1 - 3 files changed, 15 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 12060ccc15de..99fb33f8acb3 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2078,6 +2078,7 @@ static inline void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) { struct ufshcd_lrb *lrbp = &hba->lrb[task_tag]; + unsigned long flags; lrbp->issue_time_stamp = ktime_get(); lrbp->compl_time_stamp = ktime_set(0, 0); @@ -2087,19 +2088,10 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) ufshcd_clk_scaling_start_busy(hba); if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ufshcd_start_monitor(hba, lrbp); - if (ufshcd_has_utrlcnr(hba)) { - set_bit(task_tag, &hba->outstanding_reqs); - ufshcd_writel(hba, 1 << task_tag, - REG_UTP_TRANSFER_REQ_DOOR_BELL); - } else { - unsigned long flags; - - spin_lock_irqsave(hba->host->host_lock, flags); - set_bit(task_tag, &hba->outstanding_reqs); - ufshcd_writel(hba, 1 << task_tag, - REG_UTP_TRANSFER_REQ_DOOR_BELL); - spin_unlock_irqrestore(hba->host->host_lock, flags); - } + spin_lock_irqsave(hba->host->host_lock, flags); + set_bit(task_tag, &hba->outstanding_reqs); + ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); + spin_unlock_irqrestore(hba->host->host_lock, flags); /* Make sure that doorbell is committed immediately */ wmb(); } @@ -5206,17 +5198,17 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, } /** - * ufshcd_trc_handler - handle transfer requests completion + * ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance - * @use_utrlcnr: get completed requests from UTRLCNR * * Returns * IRQ_HANDLED - If interrupt is valid * IRQ_NONE - If invalid interrupt */ -static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr) +static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) { - unsigned long completed_reqs = 0; + unsigned long completed_reqs, flags; + u32 tr_doorbell; /* Resetting interrupt aggregation counters first and reading the * DOOR_BELL afterward allows us to handle all the completed requests. @@ -5229,24 +5221,10 @@ static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr) !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR)) ufshcd_reset_intr_aggr(hba); - if (use_utrlcnr) { - u32 utrlcnr; - - utrlcnr = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_LIST_COMPL); - if (utrlcnr) { - ufshcd_writel(hba, utrlcnr, - REG_UTP_TRANSFER_REQ_LIST_COMPL); - completed_reqs = utrlcnr; - } - } else { - unsigned long flags; - u32 tr_doorbell; - - spin_lock_irqsave(hba->host->host_lock, flags); - tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); - completed_reqs = tr_doorbell ^ hba->outstanding_reqs; - spin_unlock_irqrestore(hba->host->host_lock, flags); - } + spin_lock_irqsave(hba->host->host_lock, flags); + tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); + completed_reqs = tr_doorbell ^ hba->outstanding_reqs; + spin_unlock_irqrestore(hba->host->host_lock, flags); if (completed_reqs) { __ufshcd_transfer_req_compl(hba, completed_reqs); @@ -5755,7 +5733,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) /* Complete requests that have door-bell cleared */ static void ufshcd_complete_requests(struct ufs_hba *hba) { - ufshcd_trc_handler(hba, false); + ufshcd_transfer_req_compl(hba); ufshcd_tmc_handler(hba); } @@ -6392,7 +6370,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) retval |= ufshcd_tmc_handler(hba); if (intr_status & UTP_TRANSFER_REQ_COMPL) - retval |= ufshcd_trc_handler(hba, ufshcd_has_utrlcnr(hba)); + retval |= ufshcd_transfer_req_compl(hba); return retval; } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 8714b62682a0..0c70f8a8c158 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1166,11 +1166,6 @@ static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba) return ufshcd_readl(hba, REG_UFS_VERSION); } -static inline bool ufshcd_has_utrlcnr(struct ufs_hba *hba) -{ - return (hba->ufs_version >= ufshci_version(3, 0)); -} - static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba, bool up, enum ufs_notify_change_status status) { diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 757727dbab81..79ba211c1e59 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -39,7 +39,6 @@ enum { REG_UTP_TRANSFER_REQ_DOOR_BELL = 0x58, REG_UTP_TRANSFER_REQ_LIST_CLEAR = 0x5C, REG_UTP_TRANSFER_REQ_LIST_RUN_STOP = 0x60, - REG_UTP_TRANSFER_REQ_LIST_COMPL = 0x64, REG_UTP_TASK_REQ_LIST_BASE_L = 0x70, REG_UTP_TASK_REQ_LIST_BASE_H = 0x74, REG_UTP_TASK_REQ_DOOR_BELL = 0x78, From 46575badbb5237f6db49d61f4d644c88d8a3b62b Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 25 Jun 2021 16:06:54 -0700 Subject: [PATCH 45/60] Revert "BACKPORT: FROMGIT: scsi: ufs: Optimize host lock on transfer requests send/compl paths" This reverts commit 7613068f95fb3295893d9c12e50b56be74b75d11. Call trace: __switch_to+0x16c/0x2f8 __schedule+0x4d0/0x94c schedule+0x80/0x100 schedule_timeout+0x94/0x140 io_schedule_timeout+0x48/0x70 wait_for_common_io+0x80/0x108 wait_for_completion_io_timeout+0x14/0x24 blk_execute_rq+0xac/0x104 __scsi_execute+0x104/0x1c8 ufshcd_clear_ua_wlun+0x128/0x1cc ufshcd_err_handling_unprepare+0xd8/0x178 ufshcd_err_handler+0x7d8/0x9d0 process_one_work+0x218/0x634 worker_thread+0x34c/0x588 kthread+0x158/0x1b0 ret_from_fork+0x10/0 Bug: 192095860 Signed-off-by: Jaegeuk Kim Change-Id: Ifaa166902daa9dbd340fab68987200c5bf3009d9 --- drivers/scsi/ufs/ufshcd.c | 263 +++++++++++++++++++------------------- drivers/scsi/ufs/ufshcd.h | 2 + 2 files changed, 137 insertions(+), 128 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 99fb33f8acb3..c2b862f81d2b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -730,7 +730,7 @@ static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos) */ static inline void ufshcd_outstanding_req_clear(struct ufs_hba *hba, int tag) { - clear_bit(tag, &hba->outstanding_reqs); + __clear_bit(tag, &hba->outstanding_reqs); } /** @@ -1956,19 +1956,15 @@ static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) { bool queue_resume_work = false; ktime_t curr_t = ktime_get(); - unsigned long flags; if (!ufshcd_is_clkscaling_supported(hba)) return; - spin_lock_irqsave(hba->host->host_lock, flags); if (!hba->clk_scaling.active_reqs++) queue_resume_work = true; - if (!hba->clk_scaling.is_enabled || hba->pm_op_in_progress) { - spin_unlock_irqrestore(hba->host->host_lock, flags); + if (!hba->clk_scaling.is_enabled || hba->pm_op_in_progress) return; - } if (queue_resume_work) queue_work(hba->clk_scaling.workq, @@ -1984,26 +1980,21 @@ static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) hba->clk_scaling.busy_start_t = curr_t; hba->clk_scaling.is_busy_started = true; } - spin_unlock_irqrestore(hba->host->host_lock, flags); } static void ufshcd_clk_scaling_update_busy(struct ufs_hba *hba) { struct ufs_clk_scaling *scaling = &hba->clk_scaling; - unsigned long flags; if (!ufshcd_is_clkscaling_supported(hba)) return; - spin_lock_irqsave(hba->host->host_lock, flags); - hba->clk_scaling.active_reqs--; if (!hba->outstanding_reqs && scaling->is_busy_started) { scaling->tot_busy_t += ktime_to_us(ktime_sub(ktime_get(), scaling->busy_start_t)); scaling->busy_start_t = 0; scaling->is_busy_started = false; } - spin_unlock_irqrestore(hba->host->host_lock, flags); } static inline int ufshcd_monitor_opcode2dir(u8 opcode) @@ -2029,20 +2020,15 @@ static inline bool ufshcd_should_inform_monitor(struct ufs_hba *hba, static void ufshcd_start_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd); - unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); if (dir >= 0 && hba->monitor.nr_queued[dir]++ == 0) hba->monitor.busy_start_ts[dir] = ktime_get(); - spin_unlock_irqrestore(hba->host->host_lock, flags); } static void ufshcd_update_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd); - unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); if (dir >= 0 && hba->monitor.nr_queued[dir] > 0) { struct request *req = lrbp->cmd->request; struct ufs_hba_monitor *m = &hba->monitor; @@ -2066,7 +2052,6 @@ static void ufshcd_update_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) /* Push forward the busy start of monitor */ m->busy_start_ts[dir] = now; } - spin_unlock_irqrestore(hba->host->host_lock, flags); } /** @@ -2078,7 +2063,6 @@ static inline void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) { struct ufshcd_lrb *lrbp = &hba->lrb[task_tag]; - unsigned long flags; lrbp->issue_time_stamp = ktime_get(); lrbp->compl_time_stamp = ktime_set(0, 0); @@ -2086,12 +2070,10 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) trace_android_vh_ufs_send_command(hba, lrbp); ufshcd_add_command_trace(hba, task_tag, "send"); ufshcd_clk_scaling_start_busy(hba); + __set_bit(task_tag, &hba->outstanding_reqs); if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ufshcd_start_monitor(hba, lrbp); - spin_lock_irqsave(hba->host->host_lock, flags); - set_bit(task_tag, &hba->outstanding_reqs); ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); - spin_unlock_irqrestore(hba->host->host_lock, flags); /* Make sure that doorbell is committed immediately */ wmb(); } @@ -2655,6 +2637,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) { struct ufshcd_lrb *lrbp; struct ufs_hba *hba; + unsigned long flags; int tag; int err = 0; @@ -2671,43 +2654,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (!down_read_trylock(&hba->clk_scaling_lock)) return SCSI_MLQUEUE_HOST_BUSY; - switch (hba->ufshcd_state) { - case UFSHCD_STATE_OPERATIONAL: - case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: - break; - case UFSHCD_STATE_EH_SCHEDULED_FATAL: - /* - * pm_runtime_get_sync() is used at error handling preparation - * stage. If a scsi cmd, e.g. the SSU cmd, is sent from hba's - * PM ops, it can never be finished if we let SCSI layer keep - * retrying it, which gets err handler stuck forever. Neither - * can we let the scsi cmd pass through, because UFS is in bad - * state, the scsi cmd may eventually time out, which will get - * err handler blocked for too long. So, just fail the scsi cmd - * sent from PM ops, err handler can recover PM error anyways. - */ - if (hba->pm_op_in_progress) { - hba->force_reset = true; - set_host_byte(cmd, DID_BAD_TARGET); - cmd->scsi_done(cmd); - goto out; - } - fallthrough; - case UFSHCD_STATE_RESET: - err = SCSI_MLQUEUE_HOST_BUSY; - goto out; - case UFSHCD_STATE_ERROR: - set_host_byte(cmd, DID_ERROR); - cmd->scsi_done(cmd); - goto out; - default: - dev_WARN_ONCE(hba->dev, 1, "%s: invalid state %d\n", - __func__, hba->ufshcd_state); - set_host_byte(cmd, DID_BAD_TARGET); - cmd->scsi_done(cmd); - goto out; - } - hba->req_abort_count = 0; err = ufshcd_hold(hba, true); @@ -2718,7 +2664,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) WARN_ON(ufshcd_is_clkgating_allowed(hba) && (hba->clk_gating.state != CLKS_ON)); - if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { + lrbp = &hba->lrb[tag]; + if (unlikely(lrbp->in_use)) { if (hba->pm_op_in_progress) set_host_byte(cmd, DID_BAD_TARGET); else @@ -2727,7 +2674,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) goto out; } - lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); lrbp->cmd = cmd; lrbp->sense_bufflen = UFS_SENSE_SIZE; @@ -2758,7 +2704,51 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) /* Make sure descriptors are ready before ringing the doorbell */ wmb(); + spin_lock_irqsave(hba->host->host_lock, flags); + switch (hba->ufshcd_state) { + case UFSHCD_STATE_OPERATIONAL: + case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: + break; + case UFSHCD_STATE_EH_SCHEDULED_FATAL: + /* + * pm_runtime_get_sync() is used at error handling preparation + * stage. If a scsi cmd, e.g. the SSU cmd, is sent from hba's + * PM ops, it can never be finished if we let SCSI layer keep + * retrying it, which gets err handler stuck forever. Neither + * can we let the scsi cmd pass through, because UFS is in bad + * state, the scsi cmd may eventually time out, which will get + * err handler blocked for too long. So, just fail the scsi cmd + * sent from PM ops, err handler can recover PM error anyways. + */ + if (hba->pm_op_in_progress) { + hba->force_reset = true; + set_host_byte(cmd, DID_BAD_TARGET); + goto out_compl_cmd; + } + fallthrough; + case UFSHCD_STATE_RESET: + err = SCSI_MLQUEUE_HOST_BUSY; + goto out_compl_cmd; + case UFSHCD_STATE_ERROR: + set_host_byte(cmd, DID_ERROR); + goto out_compl_cmd; + default: + dev_WARN_ONCE(hba->dev, 1, "%s: invalid state %d\n", + __func__, hba->ufshcd_state); + set_host_byte(cmd, DID_BAD_TARGET); + goto out_compl_cmd; + } ufshcd_send_command(hba, tag); + spin_unlock_irqrestore(hba->host->host_lock, flags); + goto out; + +out_compl_cmd: + scsi_dma_unmap(lrbp->cmd); + lrbp->cmd = NULL; + spin_unlock_irqrestore(hba->host->host_lock, flags); + ufshcd_release(hba); + if (!err) + cmd->scsi_done(cmd); out: up_read(&hba->clk_scaling_lock); return err; @@ -2913,6 +2903,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, int err; int tag; struct completion wait; + unsigned long flags; down_read(&hba->clk_scaling_lock); @@ -2932,30 +2923,34 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, req->timeout = msecs_to_jiffies(2 * timeout); blk_mq_start_request(req); - if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { + init_completion(&wait); + lrbp = &hba->lrb[tag]; + if (unlikely(lrbp->in_use)) { err = -EBUSY; goto out; } - init_completion(&wait); - lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag); if (unlikely(err)) - goto out; + goto out_put_tag; hba->dev_cmd.complete = &wait; ufshcd_add_query_upiu_trace(hba, tag, "query_send"); /* Make sure descriptors are ready before ringing the doorbell */ wmb(); - + spin_lock_irqsave(hba->host->host_lock, flags); ufshcd_send_command(hba, tag); + spin_unlock_irqrestore(hba->host->host_lock, flags); + err = ufshcd_wait_for_dev_cmd(hba, lrbp, timeout); + +out: ufshcd_add_query_upiu_trace(hba, tag, err ? "query_complete_err" : "query_complete"); -out: +out_put_tag: blk_put_request(req); out_unlock: up_read(&hba->clk_scaling_lock); @@ -5088,24 +5083,6 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) return result; } -static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, - u32 intr_mask) -{ - if (!ufshcd_is_auto_hibern8_supported(hba) || - !ufshcd_is_auto_hibern8_enabled(hba)) - return false; - - if (!(intr_mask & UFSHCD_UIC_HIBERN8_MASK)) - return false; - - if (hba->active_uic_cmd && - (hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_ENTER || - hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_EXIT)) - return false; - - return true; -} - /** * ufshcd_uic_cmd_compl - handle completion of uic command * @hba: per adapter instance @@ -5119,10 +5096,6 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) { irqreturn_t retval = IRQ_NONE; - spin_lock(hba->host->host_lock); - if (ufshcd_is_auto_hibern8_error(hba, intr_status)) - hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); - if ((intr_status & UIC_COMMAND_COMPL) && hba->active_uic_cmd) { hba->active_uic_cmd->argument2 |= ufshcd_get_uic_cmd_result(hba); @@ -5143,7 +5116,6 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) if (retval == IRQ_HANDLED) ufshcd_add_uic_command_trace(hba, hba->active_uic_cmd, "complete"); - spin_unlock(hba->host->host_lock); return retval; } @@ -5162,9 +5134,8 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, bool update_scaling = false; for_each_set_bit(index, &completed_reqs, hba->nutrs) { - if (!test_and_clear_bit(index, &hba->outstanding_reqs)) - continue; lrbp = &hba->lrb[index]; + lrbp->in_use = false; lrbp->compl_time_stamp = ktime_get(); cmd = lrbp->cmd; if (cmd) { @@ -5180,7 +5151,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, lrbp->cmd = NULL; /* Do not touch lrbp after scsi done */ cmd->scsi_done(cmd); - ufshcd_release(hba); + __ufshcd_release(hba); update_scaling = true; } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE || lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) { @@ -5192,9 +5163,14 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, update_scaling = true; } } - if (update_scaling) - ufshcd_clk_scaling_update_busy(hba); + if (ufshcd_is_clkscaling_supported(hba) && update_scaling) + hba->clk_scaling.active_reqs--; } + + /* clear corresponding bits of completed commands */ + hba->outstanding_reqs ^= completed_reqs; + + ufshcd_clk_scaling_update_busy(hba); } /** @@ -5207,7 +5183,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, */ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) { - unsigned long completed_reqs, flags; + unsigned long completed_reqs; u32 tr_doorbell; /* Resetting interrupt aggregation counters first and reading the @@ -5221,10 +5197,8 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR)) ufshcd_reset_intr_aggr(hba); - spin_lock_irqsave(hba->host->host_lock, flags); tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); completed_reqs = tr_doorbell ^ hba->outstanding_reqs; - spin_unlock_irqrestore(hba->host->host_lock, flags); if (completed_reqs) { __ufshcd_transfer_req_compl(hba, completed_reqs); @@ -5982,11 +5956,13 @@ static void ufshcd_err_handler(struct work_struct *work) ufshcd_set_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_err_handling_prepare(hba); - /* Complete requests that have door-bell cleared by h/w */ - ufshcd_complete_requests(hba); spin_lock_irqsave(hba->host->host_lock, flags); if (hba->ufshcd_state != UFSHCD_STATE_ERROR) hba->ufshcd_state = UFSHCD_STATE_RESET; + + /* Complete requests that have door-bell cleared by h/w */ + ufshcd_complete_requests(hba); + /* * A full reset and restore might have happened after preparation * is finished, double check whether we should stop. @@ -6069,11 +6045,12 @@ static void ufshcd_err_handler(struct work_struct *work) } lock_skip_pending_xfer_clear: + spin_lock_irqsave(hba->host->host_lock, flags); + /* Complete the requests that are cleared by s/w */ ufshcd_complete_requests(hba); - - spin_lock_irqsave(hba->host->host_lock, flags); hba->silence_err_logs = false; + if (err_xfer || err_tm) { needs_reset = true; goto do_reset; @@ -6223,23 +6200,37 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba) return retval; } +static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, + u32 intr_mask) +{ + if (!ufshcd_is_auto_hibern8_supported(hba) || + !ufshcd_is_auto_hibern8_enabled(hba)) + return false; + + if (!(intr_mask & UFSHCD_UIC_HIBERN8_MASK)) + return false; + + if (hba->active_uic_cmd && + (hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_ENTER || + hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_EXIT)) + return false; + + return true; +} + /** * ufshcd_check_errors - Check for errors that need s/w attention * @hba: per-adapter instance - * @intr_status: interrupt status generated by the controller * * Returns * IRQ_HANDLED - If interrupt is valid * IRQ_NONE - If invalid interrupt */ -static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) +static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) { bool queue_eh_work = false; irqreturn_t retval = IRQ_NONE; - spin_lock(hba->host->host_lock); - hba->errors |= UFSHCD_ERROR_MASK & intr_status; - if (hba->errors & INT_FATAL_ERRORS) { ufshcd_update_evt_hist(hba, UFS_EVT_FATAL_ERR, hba->errors); @@ -6296,9 +6287,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) * itself without s/w intervention or errors that will be * handled by the SCSI core layer. */ - hba->errors = 0; - hba->uic_error = 0; - spin_unlock(hba->host->host_lock); return retval; } @@ -6333,17 +6321,13 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) */ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) { - unsigned long flags; struct request_queue *q = hba->tmf_queue; struct ctm_info ci = { .hba = hba, + .pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL), }; - spin_lock_irqsave(hba->host->host_lock, flags); - ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); - spin_unlock_irqrestore(hba->host->host_lock, flags); - return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; } @@ -6360,12 +6344,17 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) { irqreturn_t retval = IRQ_NONE; + hba->errors = UFSHCD_ERROR_MASK & intr_status; + + if (ufshcd_is_auto_hibern8_error(hba, intr_status)) + hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); + + if (hba->errors) + retval |= ufshcd_check_errors(hba); + if (intr_status & UFSHCD_UIC_MASK) retval |= ufshcd_uic_cmd_compl(hba, intr_status); - if (intr_status & UFSHCD_ERROR_MASK || hba->errors) - retval |= ufshcd_check_errors(hba, intr_status); - if (intr_status & UTP_TASK_REQ_COMPL) retval |= ufshcd_tmc_handler(hba); @@ -6391,6 +6380,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) struct ufs_hba *hba = __hba; int retries = hba->nutrs; + spin_lock(hba->host->host_lock); intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); hba->ufs_stats.last_intr_status = intr_status; hba->ufs_stats.last_intr_ts = ktime_get(); @@ -6422,6 +6412,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: "); } + spin_unlock(hba->host->host_lock); return retval; } @@ -6598,6 +6589,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, int err = 0; int tag; struct completion wait; + unsigned long flags; u8 upiu_flags; down_read(&hba->clk_scaling_lock); @@ -6610,13 +6602,13 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, tag = req->tag; WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); - if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { + init_completion(&wait); + lrbp = &hba->lrb[tag]; + if (unlikely(lrbp->in_use)) { err = -EBUSY; goto out; } - init_completion(&wait); - lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); lrbp->cmd = NULL; lrbp->sense_bufflen = 0; @@ -6654,8 +6646,10 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, /* Make sure descriptors are ready before ringing the doorbell */ wmb(); - + spin_lock_irqsave(hba->host->host_lock, flags); ufshcd_send_command(hba, tag); + spin_unlock_irqrestore(hba->host->host_lock, flags); + /* * ignore the returning value here - ufshcd_check_query_response is * bound to fail since dev_cmd.query and dev_cmd.type were left empty. @@ -6774,6 +6768,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) u32 pos; int err; u8 resp = 0xF, lun; + unsigned long flags; host = cmd->device->host; hba = shost_priv(host); @@ -6792,9 +6787,11 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) err = ufshcd_clear_cmd(hba, pos); if (err) break; - __ufshcd_transfer_req_compl(hba, pos); } } + spin_lock_irqsave(host->host_lock, flags); + ufshcd_transfer_req_compl(hba); + spin_unlock_irqrestore(host->host_lock, flags); out: hba->req_abort_count = 0; @@ -6970,16 +6967,20 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) * will fail, due to spec violation, scsi err handling next step * will be to send LU reset which, again, is a spec violation. * To avoid these unnecessary/illegal steps, first we clean up - * the lrb taken by this cmd and re-set it in outstanding_reqs, - * then queue the eh_work and bail. + * the lrb taken by this cmd and mark the lrb as in_use, then + * queue the eh_work and bail. */ if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun); - __ufshcd_transfer_req_compl(hba, (1UL << tag)); - set_bit(tag, &hba->outstanding_reqs); spin_lock_irqsave(host->host_lock, flags); - hba->force_reset = true; - ufshcd_schedule_eh_work(hba); + if (lrbp->cmd) { + __ufshcd_transfer_req_compl(hba, (1UL << tag)); + __set_bit(tag, &hba->outstanding_reqs); + lrbp->in_use = true; + hba->force_reset = true; + ufshcd_schedule_eh_work(hba); + } + spin_unlock_irqrestore(host->host_lock, flags); goto out; } @@ -6992,7 +6993,9 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) if (!err) { cleanup: + spin_lock_irqsave(host->host_lock, flags); __ufshcd_transfer_req_compl(hba, (1UL << tag)); + spin_unlock_irqrestore(host->host_lock, flags); out: err = SUCCESS; } else { @@ -7022,15 +7025,19 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) { int err; + unsigned long flags; /* * Stop the host controller and complete the requests * cleared by h/w */ ufshcd_hba_stop(hba); + + spin_lock_irqsave(hba->host->host_lock, flags); hba->silence_err_logs = true; ufshcd_complete_requests(hba); hba->silence_err_logs = false; + spin_unlock_irqrestore(hba->host->host_lock, flags); /* scale up clocks to max frequency before full reinitialization */ ufshcd_set_clk_freq(hba, true); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 0c70f8a8c158..9ce98969446c 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -188,6 +188,7 @@ struct ufs_pm_lvl_states { * @crypto_key_slot: the key slot to use for inline crypto (-1 if none) * @data_unit_num: the data unit number for the first block for inline crypto * @req_abort_skip: skip request abort task flag + * @in_use: indicates that this lrb is still in use */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; @@ -217,6 +218,7 @@ struct ufshcd_lrb { #endif bool req_abort_skip; + bool in_use; }; /** From 850f11aa85f055dd914928b7aea2e99319800459 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 25 Jun 2021 23:22:54 -0700 Subject: [PATCH 46/60] Revert "KMI: BACKPORT: FROMGIT: scsi: ufs: Optimize host lock on transfer requests send/compl paths" This patch avoids KMI, so later should be reverted to sync with upstream in next KMI update. Bug: 192095860 Signed-off-by: Jaegeuk Kim Change-Id: If861ecde381f23b5d5f18005063ec55356673fdb --- drivers/scsi/ufs/ufshcd.c | 15 ++++++--------- drivers/scsi/ufs/ufshcd.h | 2 -- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c2b862f81d2b..6656c98c7cd2 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2665,7 +2665,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) (hba->clk_gating.state != CLKS_ON)); lrbp = &hba->lrb[tag]; - if (unlikely(lrbp->in_use)) { + if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { if (hba->pm_op_in_progress) set_host_byte(cmd, DID_BAD_TARGET); else @@ -2925,7 +2925,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, init_completion(&wait); lrbp = &hba->lrb[tag]; - if (unlikely(lrbp->in_use)) { + if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { err = -EBUSY; goto out; } @@ -5134,8 +5134,9 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, bool update_scaling = false; for_each_set_bit(index, &completed_reqs, hba->nutrs) { + if (!test_and_clear_bit(index, &hba->outstanding_reqs)) + continue; lrbp = &hba->lrb[index]; - lrbp->in_use = false; lrbp->compl_time_stamp = ktime_get(); cmd = lrbp->cmd; if (cmd) { @@ -5167,9 +5168,6 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, hba->clk_scaling.active_reqs--; } - /* clear corresponding bits of completed commands */ - hba->outstanding_reqs ^= completed_reqs; - ufshcd_clk_scaling_update_busy(hba); } @@ -6603,11 +6601,11 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); init_completion(&wait); - lrbp = &hba->lrb[tag]; - if (unlikely(lrbp->in_use)) { + if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { err = -EBUSY; goto out; } + lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); lrbp->cmd = NULL; @@ -6976,7 +6974,6 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) if (lrbp->cmd) { __ufshcd_transfer_req_compl(hba, (1UL << tag)); __set_bit(tag, &hba->outstanding_reqs); - lrbp->in_use = true; hba->force_reset = true; ufshcd_schedule_eh_work(hba); } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 9ce98969446c..0c70f8a8c158 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -188,7 +188,6 @@ struct ufs_pm_lvl_states { * @crypto_key_slot: the key slot to use for inline crypto (-1 if none) * @data_unit_num: the data unit number for the first block for inline crypto * @req_abort_skip: skip request abort task flag - * @in_use: indicates that this lrb is still in use */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; @@ -218,7 +217,6 @@ struct ufshcd_lrb { #endif bool req_abort_skip; - bool in_use; }; /** From b007e43692c462a4df72f8c86e37c15828ad96ba Mon Sep 17 00:00:00 2001 From: Faiyaz Mohammed Date: Wed, 23 Jun 2021 10:50:06 +0530 Subject: [PATCH 47/60] FROMGIT: mm: slub: fix the leak of alloc/free traces debugfs interface Fix the leak of alloc/free traces debugfs interface, reported by kmemleak like below, unreferenced object 0xffff00091ae1b540 (size 64): comm "lsbug", pid 1607, jiffies 4294958291 (age 1476.340s) hex dump (first 32 bytes): 02 00 00 00 00 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b ........kkkkkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk backtrace: [] slab_post_alloc_hook+0xa0/0x418 [] kmem_cache_alloc_trace+0x1e4/0x378 [] slab_debugfs_start+0x30/0x50 slab_debugfs_start at mm/slub.c:5831 [] seq_read_iter+0x214/0xd50 [] seq_read+0x28c/0x418 [] full_proxy_read+0xdc/0x148 [] vfs_read+0x104/0x340 [] ksys_read+0xf8/0x1e0 [] __arm64_sys_read+0x74/0xa8 Link: https://lkml.kernel.org/r/1624248060-30286-1-git-send-email-faiyazm@codeaurora.org Fixes: 3589836402ca ("mm: slub: move sysfs slab alloc/free interfaces to debugfs") Link: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/mm/slub.c?h=next-20210617&id=84a2bdb1b458fc968d6d9e07dab388dc679bd747 Signed-off-by: Faiyaz Mohammed Cc: Vlastimil Babka Cc: Greg Kroah-Hartman Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton BUG: 176858818 (cherry picked from commit 29d055e7966b5beae75db7980df78f99344f74ae https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/mm/slub.c?h=next-20210624&id=29d055e7966b5beae75db7980df78f99344f74ae) Change-Id: I26fd4285b3e8f2a48f7c1320adceb0208e0fbc45 Signed-off-by: Faiyaz Mohammed --- mm/slub.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 46d14749cfba..9dde49d6deb9 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -5749,31 +5749,23 @@ static int slab_debugfs_show(struct seq_file *seq, void *v) static void slab_debugfs_stop(struct seq_file *seq, void *v) { - kfree(v); } static void *slab_debugfs_next(struct seq_file *seq, void *v, loff_t *ppos) { - loff_t *spos = v; struct loc_track *t = seq->private; - if (*ppos < t->count) { - *ppos = ++*spos; - return spos; - } - *ppos = ++*spos; + v = ppos; + ++*ppos; + if (*ppos <= t->count) + return v; + return NULL; } static void *slab_debugfs_start(struct seq_file *seq, loff_t *ppos) { - loff_t *spos = kmalloc(sizeof(loff_t), GFP_KERNEL); - - if (!spos) - return NULL; - - *spos = *ppos; - return spos; + return ppos; } static const struct seq_operations slab_debugfs_sops = { From ea53c24cb060b6aae8c7c60ba46f9cd7530419aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Wed, 16 Jun 2021 17:09:51 -0700 Subject: [PATCH 48/60] FROMGIT: bpf: Do not change gso_size during bpf_skb_change_proto() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is technically a backwards incompatible change in behaviour, but I'm going to argue that it is very unlikely to break things, and likely to fix *far* more then it breaks. In no particular order, various reasons follow: (a) I've long had a bug assigned to myself to debug a super rare kernel crash on Android Pixel phones which can (per stacktrace) be traced back to BPF clat IPv6 to IPv4 protocol conversion causing some sort of ugly failure much later on during transmit deep in the GSO engine, AFAICT precisely because of this change to gso_size, though I've never been able to manually reproduce it. I believe it may be related to the particular network offload support of attached USB ethernet dongle being used for tethering off of an IPv6-only cellular connection. The reason might be we end up with more segments than max permitted, or with a GSO packet with only one segment... (either way we break some assumption and hit a BUG_ON) (b) There is no check that the gso_size is > 20 when reducing it by 20, so we might end up with a negative (or underflowing) gso_size or a gso_size of 0. This can't possibly be good. Indeed this is probably somehow exploitable (or at least can result in a kernel crash) by delivering crafted packets and perhaps triggering an infinite loop or a divide by zero... As a reminder: gso_size (MSS) is related to MTU, but not directly derived from it: gso_size/MSS may be significantly smaller then one would get by deriving from local MTU. And on some NICs (which do loose MTU checking on receive, it may even potentially be larger, for example my work pc with 1500 MTU can receive 1520 byte frames [and sometimes does due to bugs in a vendor plat46 implementation]). Indeed even just going from 21 to 1 is potentially problematic because it increases the number of segments by a factor of 21 (think DoS, or some other crash due to too many segments). (c) It's always safe to not increase the gso_size, because it doesn't result in the max packet size increasing. So the skb_increase_gso_size() call was always unnecessary for correctness (and outright undesirable, see later). As such the only part which is potentially dangerous (ie. could cause backwards compatibility issues) is the removal of the skb_decrease_gso_size() call. (d) If the packets are ultimately destined to the local device, then there is absolutely no benefit to playing around with gso_size. It only matters if the packets will egress the device. ie. we're either forwarding, or transmitting from the device. (e) This logic only triggers for packets which are GSO. It does not trigger for skbs which are not GSO. It will not convert a non-GSO MTU sized packet into a GSO packet (and you don't even know what the MTU is, so you can't even fix it). As such your transmit path must *already* be able to handle an MTU 20 bytes larger then your receive path (for IPv4 to IPv6 translation) - and indeed 28 bytes larger due to IPv4 fragments. Thus removing the skb_decrease_gso_size() call doesn't actually increase the size of the packets your transmit side must be able to handle. ie. to handle non-GSO max-MTU packets, the IPv4/IPv6 device/ route MTUs must already be set correctly. Since for example with an IPv4 egress MTU of 1500, IPv4 to IPv6 translation will already build 1520 byte IPv6 frames, so you need a 1520 byte device MTU. This means if your IPv6 device's egress MTU is 1280, your IPv4 route must be 1260 (and actually 1252, because of the need to handle fragments). This is to handle normal non-GSO packets. Thus the reduction is simply not needed for GSO packets, because when they're correctly built, they will already be the right size. (f) TSO/GSO should be able to exactly undo GRO: the number of packets (TCP segments) should not be modified, so that TCP's MSS counting works correctly (this matters for congestion control). If protocol conversion changes the gso_size, then the number of TCP segments may increase or decrease. Packet loss after protocol conversion can result in partial loss of MSS segments that the sender sent. How's the sending TCP stack going to react to receiving ACKs/SACKs in the middle of the segments it sent? (g) skb_{decrease,increase}_gso_size() are already no-ops for GSO_BY_FRAGS case (besides triggering WARN_ON_ONCE). This means you already cannot guarantee that gso_size (and thus resulting packet MTU) is changed. ie. you must assume it won't be changed. (h) changing gso_size is outright buggy for UDP GSO packets, where framing matters (I believe that's also the case for SCTP, but it's already excluded by [g]). So the only remaining case is TCP, which also doesn't want it (see [f]). (i) see also the reasoning on the previous attempt at fixing this (commit fa7b83bf3b156c767f3e4a25bbf3817b08f3ff8e) which shows that the current behaviour causes TCP packet loss: In the forwarding path GRO -> BPF 6 to 4 -> GSO for TCP traffic, the coalesced packet payload can be > MSS, but < MSS + 20. bpf_skb_proto_6_to_4() will upgrade the MSS and it can be > the payload length. After then tcp_gso_segment checks for the payload length if it is <= MSS. The condition is causing the packet to be dropped. tcp_gso_segment(): [...] mss = skb_shinfo(skb)->gso_size; if (unlikely(skb->len <= mss)) goto out; [...] Thus changing the gso_size is simply a very bad idea. Increasing is unnecessary and buggy, and decreasing can go negative. Fixes: 6578171a7ff0 ("bpf: add bpf_skb_change_proto helper") Signed-off-by: Maciej Żenczykowski Signed-off-by: Daniel Borkmann Cc: Dongseok Yi Cc: Willem de Bruijn Link: https://lore.kernel.org/bpf/CANP3RGfjLikQ6dg=YpBU0OeHvyv7JOki7CyOUS9modaXAi-9vQ@mail.gmail.com Link: https://lore.kernel.org/bpf/20210617000953.2787453-2-zenczykowski@gmail.com (cherry picked from commit 364745fbe981a4370f50274475da4675661104df https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=364745fbe981a4370f50274475da4675661104df ) Test: builds, TreeHugger Bug: 188690383 Signed-off-by: Maciej Żenczykowski Change-Id: I0ef3174cbd3caaa42d5779334a9c0bfdc9ab81f5 --- net/core/filter.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index ef6bdbb63ecb..7ea752af7894 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3266,8 +3266,6 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) shinfo->gso_type |= SKB_GSO_TCPV6; } - /* Due to IPv6 header, MSS needs to be downgraded. */ - skb_decrease_gso_size(shinfo, len_diff); /* Header must be checked, and gso_segs recomputed. */ shinfo->gso_type |= SKB_GSO_DODGY; shinfo->gso_segs = 0; @@ -3307,8 +3305,6 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) shinfo->gso_type |= SKB_GSO_TCPV4; } - /* Due to IPv4 header, MSS can be upgraded. */ - skb_increase_gso_size(shinfo, len_diff); /* Header must be checked, and gso_segs recomputed. */ shinfo->gso_type |= SKB_GSO_DODGY; shinfo->gso_segs = 0; From c6857771051a5f63835406f2445cced849575113 Mon Sep 17 00:00:00 2001 From: Jone Chou Date: Sat, 26 Jun 2021 02:25:57 +0800 Subject: [PATCH 49/60] ANDROID: kernel: add module info for debug_kinfo Backup module range for bootloader usage Bug: 191677481 Bug: 191767613 Signed-off-by: Jone Chou Change-Id: I4f11c5d44b454aff604670d40b1981172a14159c --- drivers/staging/android/debug_kinfo.c | 9 ++++++++- drivers/staging/android/debug_kinfo.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/debug_kinfo.c b/drivers/staging/android/debug_kinfo.c index ca10756a040f..0a8d4deeb6dc 100644 --- a/drivers/staging/android/debug_kinfo.c +++ b/drivers/staging/android/debug_kinfo.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "debug_kinfo.h" /* @@ -162,7 +163,13 @@ static int debug_kinfo_probe(struct platform_device *pdev) info->mod_core_layout_offset = offsetof(struct module, core_layout); info->mod_init_layout_offset = offsetof(struct module, init_layout); info->mod_kallsyms_offset = offsetof(struct module, kallsyms); - +#if defined(CONFIG_MODULES) && defined(MODULES_VADDR) + info->module_start_va = MODULES_VADDR; + info->module_end_va = MODULES_END; +#else + info->module_start_va = VMALLOC_START; + info->module_end_va = VMALLOC_END; +#endif update_kernel_all_info(all_info); return 0; diff --git a/drivers/staging/android/debug_kinfo.h b/drivers/staging/android/debug_kinfo.h index 1af4ace4796c..921f140ce027 100644 --- a/drivers/staging/android/debug_kinfo.h +++ b/drivers/staging/android/debug_kinfo.h @@ -58,6 +58,8 @@ struct kernel_info { __u32 mod_core_layout_offset; __u32 mod_init_layout_offset; __u32 mod_kallsyms_offset; + __u64 module_start_va; + __u64 module_end_va; } __packed; struct kernel_all_info { From e7cf28a1a416b2a3e2ba0d66621c271d03a30159 Mon Sep 17 00:00:00 2001 From: Chun-Hung Wu Date: Mon, 28 Jun 2021 23:13:49 +0800 Subject: [PATCH 50/60] ANDROID: Update symbol list for mtk 1. Generated with: BUILD_CONFIG=out/build.config OUT_DIR=out ./build/build_abi.sh --update Leaf changes summary: 3 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 3 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 3 Added functions: [A] 'function regmap* rdev_get_regmap(regulator_dev*)' [A] 'function int regulator_set_active_discharge_regmap(regulator_dev*, bool)' [A] 'function void ufshcd_hba_stop(ufs_hba*)' Bug: 191726929 Signed-off-by: Chun-Hung Wu Change-Id: I2fe2e077cdd575bc3b89f4d0d8b08842f432c276 --- android/abi_gki_aarch64.xml | 710 ++++++++++++++++++------------------ android/abi_gki_aarch64_mtk | 20 +- 2 files changed, 381 insertions(+), 349 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index b3cc2315644e..a948f4d3aeba 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -3284,6 +3284,7 @@ + @@ -3384,6 +3385,7 @@ + @@ -4222,6 +4224,7 @@ + @@ -27505,7 +27508,7 @@ - + @@ -45725,10 +45728,10 @@ - - - - + + + + @@ -46773,28 +46776,28 @@ - - - - - + + + + + - - - - + + + + - - - - + + + + - - - + + + @@ -48869,12 +48872,12 @@ - + - + - + @@ -50349,18 +50352,18 @@ - + - + - + - + - + @@ -50392,70 +50395,70 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -50482,18 +50485,18 @@ - + - + - + - + - + @@ -50588,12 +50591,12 @@ - + - + - + @@ -50724,18 +50727,18 @@ - + - + - + - + - + @@ -50987,18 +50990,18 @@ - + - + - + - + - + @@ -111119,6 +111122,10 @@ + + + + @@ -111286,6 +111293,11 @@ + + + + + @@ -114415,84 +114427,84 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -114677,18 +114689,18 @@ - + - + - + - + - + @@ -114790,7 +114802,7 @@ - + @@ -114861,41 +114873,41 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -115353,48 +115365,48 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -115523,23 +115535,23 @@ - - - - - - + + + + + + - - - - - + + + + + - - + + @@ -115549,12 +115561,12 @@ - - + + - - + + @@ -115562,105 +115574,109 @@ - - - + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - - + + + + + + - - - - - - - + + + + + + + - - + + - - - - - - - - + + + + + + + + - - + + - - + + - - + + - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - + + + + - - + + - - - + + + @@ -115668,23 +115684,23 @@ - - + + - - - + + + - - - + + + - - - + + + @@ -130403,6 +130419,14 @@ + + + + + + + + @@ -130422,14 +130446,6 @@ - - - - - - - - @@ -177902,6 +177918,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -177958,109 +178022,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -178519,7 +178480,62 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -188182,17 +188198,6 @@ - - - - - - - - - - - @@ -188268,6 +188273,17 @@ + + + + + + + + + + + diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk index ad5297958f00..d6dbaba3e1fd 100644 --- a/android/abi_gki_aarch64_mtk +++ b/android/abi_gki_aarch64_mtk @@ -363,8 +363,10 @@ devm_extcon_register_notifier devm_free_irq devm_fwnode_pwm_get + devm_gpiochip_add_data_with_key devm_gpiod_get devm_gpiod_get_index + devm_gpiod_get_optional devm_gpiod_put devm_gpio_free devm_gpio_request @@ -770,6 +772,7 @@ gpiod_set_debounce gpiod_set_raw_value gpiod_set_value + gpiod_set_value_cansleep gpiod_to_irq gpio_free gpio_request @@ -1197,6 +1200,7 @@ of_get_next_parent of_get_parent of_get_property + of_get_regulator_init_data of_graph_get_next_endpoint of_graph_get_remote_node of_graph_get_remote_port_parent @@ -1297,7 +1301,6 @@ pinctrl_utils_free_map pinctrl_utils_reserve_map pin_user_pages_fast - pin_user_pages_remote platform_bus_type platform_device_add platform_device_add_data @@ -1379,9 +1382,11 @@ raw_notifier_chain_unregister _raw_read_lock _raw_read_lock_bh + _raw_read_lock_irqsave _raw_read_trylock _raw_read_unlock _raw_read_unlock_bh + _raw_read_unlock_irqrestore _raw_spin_lock _raw_spin_lock_bh _raw_spin_lock_irq @@ -1410,6 +1415,7 @@ rdev_get_dev rdev_get_drvdata rdev_get_id + rdev_get_regmap refcount_warn_saturate __refrigerator regcache_cache_only @@ -1462,9 +1468,11 @@ regulator_list_voltage_linear_range regulator_list_voltage_table regulator_map_voltage_iterate + regulator_map_voltage_linear regulator_map_voltage_linear_range regulator_notifier_call_chain regulator_put + regulator_set_active_discharge_regmap regulator_set_current_limit regulator_set_current_limit_regmap regulator_set_mode @@ -1805,6 +1813,7 @@ __traceiter_android_vh_finish_update_load_avg_se __traceiter_android_vh_iommu_alloc_iova __traceiter_android_vh_iommu_free_iova + __traceiter_android_vh_logbuf __traceiter_android_vh_override_creds __traceiter_android_vh_prepare_update_load_avg_se __traceiter_android_vh_revert_creds @@ -1861,6 +1870,7 @@ __tracepoint_android_vh_finish_update_load_avg_se __tracepoint_android_vh_iommu_alloc_iova __tracepoint_android_vh_iommu_free_iova + __tracepoint_android_vh_logbuf __tracepoint_android_vh_override_creds __tracepoint_android_vh_prepare_update_load_avg_se __tracepoint_android_vh_revert_creds @@ -1938,6 +1948,7 @@ ufshcd_fixup_dev_quirks ufshcd_get_pwr_dev_param ufshcd_hba_enable + ufshcd_hba_stop ufshcd_link_recovery ufshcd_make_hba_operational ufshcd_pltfrm_init @@ -1951,7 +1962,6 @@ ufshcd_uic_hibern8_exit unlock_page unmap_mapping_range - unpin_user_page unpin_user_pages unregister_blkdev __unregister_chrdev @@ -1995,6 +2005,8 @@ usb_ep_queue usb_ep_set_halt usb_ep_set_maxpacket_limit + usb_function_register + usb_function_unregister usb_gadget_giveback_request usb_gadget_map_request usb_gadget_set_state @@ -2175,6 +2187,8 @@ woken_wake_function work_busy work_on_cpu + ww_mutex_lock + ww_mutex_unlock xhci_add_endpoint xhci_check_bandwidth xhci_drop_endpoint @@ -2193,7 +2207,9 @@ debugfs_create_u8 devm_of_pwm_get led_classdev_unregister + pin_user_pages_remote send_sig_info syscore_resume syscore_suspend + unpin_user_page v4l2_m2m_buf_remove_by_buf From 8943a2e7a33e33fd89614ac83b33b30f8d8c6b96 Mon Sep 17 00:00:00 2001 From: Liujie Xie Date: Mon, 28 Jun 2021 21:06:23 +0800 Subject: [PATCH 51/60] ANDROID: android: Export symbols for invoking cpufreq_update_util() In order to update cpufreq, vendor modules invoke cpufreq_update_util(), but when we build our modules, report error: ERROR: modpost: "cpufreq_update_util_data" [xxx.ko] undefined! Bug: 192218676 Signed-off-by: Liujie Xie Change-Id: Ib1da70229f04b08d8d812d065021dec0bf891e0e --- kernel/sched/cpufreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sched/cpufreq.c b/kernel/sched/cpufreq.c index 3d5f5a80b401..17fa9566e705 100644 --- a/kernel/sched/cpufreq.c +++ b/kernel/sched/cpufreq.c @@ -10,6 +10,7 @@ #include "sched.h" DEFINE_PER_CPU(struct update_util_data __rcu *, cpufreq_update_util_data); +EXPORT_PER_CPU_SYMBOL_GPL(cpufreq_update_util_data); /** * cpufreq_add_update_util_hook - Populate the CPU's update_util_data pointer. From 1093a9bfdbd2ec8f4eab207d2ecc33efd84c4b83 Mon Sep 17 00:00:00 2001 From: Stephen Dickey Date: Fri, 25 Jun 2021 18:31:30 -0700 Subject: [PATCH 52/60] ANDROID: sched: select fallback rq must check for allowed cpus select_fallback_rq() must return a cpu that is valid for the task. However, when nid is not -1, it skips checking for task_cpu_possible_mask(). This causes a problem when execve-ing 32 bit apps on an asymmetric system where not all cpus are 32 bit capable. During execve-ing the task is marked as 32 bit long before its affinity mask is restricted. If the cpu goes offline during this time, select_fallback_rq() could return a 64 bit only cpu, which __migrate_tasks()/ is_cpu_allowed() rejects. migrate_tasks() will therefore continue to pick the same task repeatedly, where __migrate_tasks() rejects the cpu chosen by select_fallback_rq() every time, leading to an infinite loop. Correct the issue by updating select_fallback_rq() for the case where nid is not -1, ensuring that the returned cpu is always valid for this task. Bug: 192050156 Change-Id: Ia073a8395a02485f6d1c1daa0f3ce9e2029cb1f4 Signed-off-by: Stephen Dickey --- kernel/sched/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 64288d005bb4..46a113c8bc2e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2482,9 +2482,7 @@ static int select_fallback_rq(int cpu, struct task_struct *p) /* Look for allowed, online CPU in same node. */ for_each_cpu(dest_cpu, nodemask) { - if (!cpu_active(dest_cpu)) - continue; - if (cpumask_test_cpu(dest_cpu, p->cpus_ptr)) + if (is_cpu_allowed(p, dest_cpu)) return dest_cpu; } } From ba085dd70a3fb9dc9a3fdb4824e43f3a1c8f9b5b Mon Sep 17 00:00:00 2001 From: Siddharth Gupta Date: Tue, 22 Jun 2021 15:11:24 -0700 Subject: [PATCH 53/60] FROMLIST: remoteproc: core: Export the rproc coredump APIs The remoteproc coredump APIs are currently only part of the internal remoteproc header. This prevents the remoteproc platform drivers from using these APIs when needed. This change moves the rproc_coredump() and rproc_coredump_cleanup() APIs to the linux header and marks them as exported symbols. Signed-off-by: Siddharth Gupta Bug: 188764827 Link: https://lore.kernel.org/linux-remoteproc/1623722930-29354-2-git-send-email-sidgup@codeaurora.org/ Change-Id: I8333774acb748fae10e0fd5146b747c4cf2ea6c7 Signed-off-by: Siddharth Gupta --- drivers/remoteproc/remoteproc_coredump.c | 2 ++ drivers/remoteproc/remoteproc_internal.h | 4 ---- include/linux/remoteproc.h | 4 ++++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/remoteproc/remoteproc_coredump.c b/drivers/remoteproc/remoteproc_coredump.c index aee657cc08c6..aa45b68c224b 100644 --- a/drivers/remoteproc/remoteproc_coredump.c +++ b/drivers/remoteproc/remoteproc_coredump.c @@ -32,6 +32,7 @@ void rproc_coredump_cleanup(struct rproc *rproc) kfree(entry); } } +EXPORT_SYMBOL(rproc_coredump_cleanup); /** * rproc_coredump_add_segment() - add segment of device memory to coredump @@ -327,6 +328,7 @@ void rproc_coredump(struct rproc *rproc) */ wait_for_completion(&dump_state.dump_done); } +EXPORT_SYMBOL(rproc_coredump); /** * rproc_coredump_using_sections() - perform coredump using section headers diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index 9ea37aa687d2..b8bd681c6547 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -49,10 +49,6 @@ extern struct class rproc_class; int rproc_init_sysfs(void); void rproc_exit_sysfs(void); -/* from remoteproc_coredump.c */ -void rproc_coredump_cleanup(struct rproc *rproc); -void rproc_coredump(struct rproc *rproc); - #ifdef CONFIG_REMOTEPROC_CDEV void rproc_init_cdev(void); void rproc_exit_cdev(void); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 04951e2b335f..25621ffdb99b 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -658,6 +658,10 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, int rproc_boot(struct rproc *rproc); void rproc_shutdown(struct rproc *rproc); void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); + +/* from remoteproc_coredump.c */ +void rproc_coredump_cleanup(struct rproc *rproc); +void rproc_coredump(struct rproc *rproc); void rproc_coredump_using_sections(struct rproc *rproc); int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); int rproc_coredump_add_custom_segment(struct rproc *rproc, From 3cd04ea95afb5f9059ff3604dcea389b49691443 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Fri, 25 Jun 2021 06:12:34 -0700 Subject: [PATCH 54/60] ANDROID: lib: Export show_mem() for vendor module usage There are debugging modules that monitor the memory usage of tasks and report memory parameters in some situations (such as OOM). Bug: 189595202 Change-Id: I6cc405b0f4cbe1706857fc3b2f8da83ea981818d Signed-off-by: Georgi Djakov --- lib/show_mem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/show_mem.c b/lib/show_mem.c index 663e312814cb..3d8d609bbf54 100644 --- a/lib/show_mem.c +++ b/lib/show_mem.c @@ -43,3 +43,4 @@ void show_mem(unsigned int filter, nodemask_t *nodemask) #endif trace_android_vh_show_mem(filter, nodemask); } +EXPORT_SYMBOL_GPL(show_mem); From 01f2392e13dbdb17d7a22290fba48207059a7f5a Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Sun, 27 Jun 2021 15:26:40 +0530 Subject: [PATCH 55/60] ANDROID: logbuf: Add new logbuf vendor hook to support pr_cont() Add new logbuf vendor hook android_vh_logbuf_pr_cont() to capture pr_cont logs. Bug: 185182649 Change-Id: I76b310fc9caac71b344b6cc25ea36f7f81cb7148 Signed-off-by: Mukesh Ojha --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/logbuf.h | 4 ++++ kernel/printk/printk.c | 2 ++ 3 files changed, 7 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 9367f3f512d8..416938977b4e 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -271,6 +271,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_post_init_entity_util_avg); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpm_get_timer); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpm_adj_current_limit); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_logbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_logbuf_pr_cont); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_scan_type); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_swappiness); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_slab_bypass); diff --git a/include/trace/hooks/logbuf.h b/include/trace/hooks/logbuf.h index a599bf8c2cbf..7af9122af8ad 100644 --- a/include/trace/hooks/logbuf.h +++ b/include/trace/hooks/logbuf.h @@ -17,6 +17,10 @@ struct printk_record; DECLARE_HOOK(android_vh_logbuf, TP_PROTO(struct printk_ringbuffer *rb, struct printk_record *r), TP_ARGS(rb, r)) + +DECLARE_HOOK(android_vh_logbuf_pr_cont, + TP_PROTO(struct printk_record *r, size_t text_len), + TP_ARGS(r, text_len)) #else #define trace_android_vh_logbuf(rb, r) #endif diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 09b63b9aea9c..de278ccc3940 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1958,6 +1958,8 @@ static size_t log_output(int facility, int level, enum log_flags lflags, } else { prb_commit(&e); } + + trace_android_vh_logbuf_pr_cont(&r, text_len); return text_len; } } From 961be311783c62509236a43f51fba9c668a63fdd Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Mon, 28 Jun 2021 10:49:56 +0900 Subject: [PATCH 56/60] ANDROID: GKI: initial upload list for exynosauto soc This patch adds to upload initial symbol list for Exynosauto SoC. To find what has updated from GKI symbol easily, this list does not include full list of symbol. So, nothing has added to GKI ABI symbols. Bug: 192103187 Signed-off-by: Chanho Park Change-Id: Iae46da79e06d1081199a8db014b892c74887cbf8 --- android/abi_gki_aarch64_exynosauto | 1347 ++++++++++++++++++++++++++++ build.config.gki.aarch64 | 1 + 2 files changed, 1348 insertions(+) create mode 100644 android/abi_gki_aarch64_exynosauto diff --git a/android/abi_gki_aarch64_exynosauto b/android/abi_gki_aarch64_exynosauto new file mode 100644 index 000000000000..8335604d5c49 --- /dev/null +++ b/android/abi_gki_aarch64_exynosauto @@ -0,0 +1,1347 @@ +[abi_symbol_list] +# commonly used symbols + add_wait_queue + alloc_chrdev_region + __alloc_pages_nodemask + alloc_workqueue + __arch_copy_from_user + __arch_copy_to_user + arm64_const_caps_ready + arm64_use_ng_mappings + __arm_smccc_smc + atomic_notifier_chain_register + blocking_notifier_call_chain + blocking_notifier_chain_register + blocking_notifier_chain_unregister + bpf_trace_run2 + bpf_trace_run4 + cancel_delayed_work_sync + cancel_work_sync + capable + cdev_add + cdev_del + cdev_init + __cfi_slowpath + __check_object_size + __class_create + class_destroy + clk_disable + clk_enable + clk_get + clk_get_rate + __clk_is_enabled + clk_prepare + clk_put + clk_register + clk_set_rate + clk_unprepare + clk_unregister + cma_alloc + cma_release + complete + complete_all + complete_and_exit + __const_udelay + cpu_bit_bitmap + cpu_hwcap_keys + cpu_hwcaps + cpumask_next + cpu_number + __cpu_online_mask + crc32_le + __crypto_memneq + debugfs_create_dir + debugfs_create_file + debugfs_create_u32 + debugfs_remove + default_llseek + delayed_work_timer_fn + del_timer + del_timer_sync + destroy_workqueue + dev_driver_string + _dev_err + device_create + device_create_file + device_destroy + device_initialize + device_init_wakeup + device_remove_file + _dev_info + devm_clk_get + devm_free_irq + devm_gpiod_get_optional + devm_gpio_request_one + devm_i2c_new_dummy_device + devm_ioremap + devm_ioremap_resource + devm_kasprintf + devm_kfree + devm_kmalloc + devm_kmemdup + __devm_of_phy_provider_register + devm_phy_create + devm_phy_get + devm_pinctrl_get + devm_platform_ioremap_resource + __devm_regmap_init_i2c + devm_regulator_bulk_get + __devm_request_region + devm_request_threaded_irq + devm_rtc_device_register + devm_snd_soc_register_card + devm_snd_soc_register_component + _dev_notice + devres_add + devres_alloc_node + dev_set_name + _dev_warn + disable_irq + disable_irq_nosync + dma_alloc_attrs + dma_buf_attach + dma_buf_begin_cpu_access + dma_buf_detach + dma_buf_end_cpu_access + dma_buf_export + dma_buf_get + dma_buf_map_attachment + dma_buf_mmap + dma_buf_put + dma_buf_unmap_attachment + dma_buf_vmap + dma_buf_vunmap + dma_fence_add_callback + dma_fence_context_alloc + dma_fence_default_wait + dma_fence_init + dma_fence_release + dma_fence_remove_callback + dma_fence_signal + dma_free_attrs + dma_heap_buffer_alloc + dma_heap_find + dma_heap_put + dma_map_page_attrs + dma_map_sg_attrs + dma_release_channel + dma_request_chan + dma_set_coherent_mask + dma_set_mask + dma_sync_sg_for_cpu + dma_sync_sg_for_device + dma_sync_single_for_cpu + dma_sync_single_for_device + dma_unmap_page_attrs + dma_unmap_sg_attrs + down_interruptible + down_read + drm_add_edid_modes + drm_atomic_helper_connector_destroy_state + drm_atomic_helper_connector_duplicate_state + drm_atomic_helper_connector_reset + drm_bridge_add + drm_bridge_remove + drm_connector_attach_encoder + drm_connector_cleanup + drm_connector_init + drm_connector_register + drm_connector_update_edid_property + __drm_err + drm_helper_probe_single_connector_modes + drm_kms_helper_hotplug_event + drm_mode_copy + drm_mode_create + drm_mode_probed_add + drm_mode_vrefresh + dump_stack + enable_irq + event_triggers_call + fd_install + find_next_bit + find_vma + finish_wait + flush_delayed_work + flush_work + flush_workqueue + fput + frame_vector_to_pages + free_irq + __free_pages + free_pages + freezing_slow_path + generic_file_llseek + generic_handle_irq + gen_pool_add_owner + gen_pool_alloc_algo_owner + gen_pool_free_owner + get_device + __get_free_pages + get_random_bytes + get_task_mm + get_unused_fd_flags + gic_nonsecure_priorities + gpiod_direction_input + gpiod_direction_output_raw + gpiod_get_raw_value + gpiod_set_raw_value + gpiod_set_value_cansleep + gpiod_to_irq + gpio_free + gpio_request + gpio_request_one + gpio_to_desc + handle_edge_irq + handle_level_irq + handle_nested_irq + i2c_add_numbered_adapter + i2c_del_driver + i2c_register_driver + i2c_transfer + i2c_unregister_device + __init_rwsem + __init_swait_queue_head + init_timer_key + init_wait_entry + __init_waitqueue_head + iomem_resource + iommu_get_domain_for_dev + iommu_register_device_fault_handler + iommu_unregister_device_fault_handler + __ioremap + iounmap + __irq_alloc_descs + __irq_domain_add + irq_domain_remove + irq_find_mapping + irq_get_irq_data + irq_modify_status + irq_of_parse_and_map + irq_set_affinity_hint + irq_set_chip_and_handler_name + irq_set_chip_data + irq_set_irq_wake + is_vmalloc_addr + jiffies + kasan_flag_enabled + kasprintf + kfree + kimage_voffset + __kmalloc + kmalloc_caches + kmalloc_order_trace + kmem_cache_alloc_trace + kmemdup + kobject_create_and_add + kobject_get + kobject_init_and_add + kobject_put + krealloc + kstrdup + kstrtoint + kstrtou8 + kstrtouint + kstrtoull + kthread_create_on_node + __kthread_init_worker + kthread_queue_work + kthread_stop + kthread_worker_fn + ktime_get + ktime_get_mono_fast_ns + ktime_get_raw_ts64 + ktime_get_real_ts64 + ktime_get_ts64 + kvfree + kvmalloc_node + __list_add_valid + __list_del_entry_valid + __log_post_read_mmio + __log_read_mmio + __log_write_mmio + loops_per_jiffy + memcpy + memdup_user + memset + memstart_addr + mfd_add_devices + mfd_remove_devices + mipi_dsi_attach + mipi_dsi_detach + mipi_dsi_device_register_full + mipi_dsi_device_unregister + mipi_dsi_driver_register_full + mipi_dsi_driver_unregister + misc_deregister + misc_register + mmput + mod_timer + module_layout + __msecs_to_jiffies + msleep + __mutex_init + mutex_lock + mutex_lock_interruptible + mutex_unlock + no_llseek + nonseekable_open + noop_llseek + nr_cpu_ids + ns_to_timespec64 + __num_online_cpus + of_address_to_resource + of_alias_get_id + of_clk_add_provider + of_clk_del_provider + of_clk_get + of_count_phandle_with_args + of_device_get_match_data + of_device_is_available + of_device_is_compatible + of_find_compatible_node + of_find_device_by_node + of_find_matching_node_and_match + of_find_mipi_dsi_host_by_node + of_find_node_by_name + of_find_node_opts_by_path + of_find_property + of_get_child_by_name + of_get_named_gpio_flags + of_get_next_child + of_get_property + of_get_regulator_init_data + of_graph_get_remote_node + of_iomap + of_match_device + of_match_node + of_parse_phandle + of_platform_populate + of_property_count_elems_of_size + of_property_read_string + of_property_read_string_helper + of_property_read_u32_index + of_property_read_variable_u32_array + of_property_read_variable_u8_array + of_prop_next_string + of_reserved_mem_device_init_by_idx + of_reserved_mem_lookup + of_root + panic + panic_notifier_list + param_ops_bool + param_ops_int + param_ops_uint + PDE_DATA + perf_trace_buf_alloc + perf_trace_run_bpf_submit + phy_power_off + phy_power_on + pinctrl_lookup_state + pinctrl_select_state + platform_bus_type + platform_device_unregister + __platform_driver_register + platform_driver_unregister + platform_get_irq + platform_get_resource + platform_get_resource_byname + pm_power_off + __pm_runtime_disable + pm_runtime_enable + __pm_runtime_idle + __pm_runtime_resume + pm_runtime_set_autosuspend_delay + __pm_runtime_suspend + __pm_runtime_use_autosuspend + pm_wakeup_dev_event + pm_wakeup_ws_event + preempt_schedule + preempt_schedule_notrace + prepare_to_wait_event + print_hex_dump + printk + proc_create_data + put_device + __put_task_struct + put_unused_fd + queue_delayed_work_on + queue_work_on + ___ratelimit + _raw_spin_lock + _raw_spin_lock_irq + _raw_spin_lock_irqsave + _raw_spin_unlock + _raw_spin_unlock_irq + _raw_spin_unlock_irqrestore + __rcu_read_lock + __rcu_read_unlock + rdev_get_drvdata + rdev_get_id + refcount_warn_saturate + __refrigerator + regcache_mark_dirty + regcache_sync + __register_chrdev + register_pm_notifier + register_reboot_notifier + register_restart_handler + register_syscore_ops + regmap_read + regmap_update_bits_base + regmap_write + regulator_bulk_disable + regulator_bulk_enable + regulator_disable + regulator_enable + regulator_get_optional + regulator_list_voltage_linear + regulator_map_voltage_linear + regulator_put + regulator_register + regulator_unregister + release_firmware + __release_region + remove_proc_entry + request_firmware + __request_region + request_threaded_irq + sched_clock + schedule + schedule_timeout + scnprintf + seq_lseek + seq_printf + seq_putc + seq_puts + seq_read + seq_release + set_cpus_allowed_ptr + set_page_dirty_lock + sg_alloc_table + sg_alloc_table_from_pages + sg_free_table + sg_init_table + sg_next + __sg_page_iter_next + __sg_page_iter_start + simple_attr_open + simple_attr_read + simple_attr_release + simple_attr_write + simple_open + simple_read_from_buffer + simple_strtoul + simple_write_to_buffer + single_open + single_release + snd_pcm_format_width + snd_soc_component_update_bits + snd_soc_component_write + snd_soc_dai_set_fmt + snd_soc_dai_set_tdm_slot + snd_soc_info_volsw + snd_soc_of_get_dai_link_codecs + snd_soc_of_get_dai_name + snd_soc_of_parse_audio_routing + snd_soc_of_put_dai_link_codecs + snd_soc_pm_ops + snprintf + sort + split_page + sprintf + sscanf + __stack_chk_fail + __stack_chk_guard + strcasecmp + strcmp + strcpy + strcspn + strlcat + strlcpy + strlen + strncmp + strncpy + strnlen + strstr + sync_file_create + sync_file_get_fence + synchronize_irq + syscon_regmap_lookup_by_phandle + sysfs_create_file_ns + sysfs_create_group + sysfs_remove_file_ns + sysfs_remove_group + system_freezing_cnt + system_wq + tasklet_kill + __tasklet_schedule + _totalram_pages + trace_event_buffer_commit + trace_event_buffer_reserve + trace_event_ignore_this_pid + trace_event_raw_init + trace_event_reg + trace_handle_return + __traceiter_rwmmio_post_read + __traceiter_rwmmio_read + __traceiter_rwmmio_write + tracepoint_probe_register + __tracepoint_rwmmio_post_read + __tracepoint_rwmmio_read + __tracepoint_rwmmio_write + trace_raw_output_prep + trace_seq_printf + __udelay + __unregister_chrdev + unregister_chrdev_region + unregister_pm_notifier + unregister_reboot_notifier + up + up_read + __usecs_to_jiffies + usleep_range + v4l2_device_register + v4l2_device_unregister + v4l2_fh_add + v4l2_fh_del + v4l2_fh_exit + v4l2_fh_init + v4l2_subdev_init + vabits_actual + vb2_buffer_done + vb2_dqbuf + vb2_mmap + vb2_plane_cookie + vb2_plane_vaddr + vb2_poll + vb2_qbuf + vb2_querybuf + vb2_queue_init + vb2_queue_release + vb2_reqbufs + vb2_streamoff + vb2_streamon + vfree + video_devdata + video_device_alloc + video_device_release + video_ioctl2 + __video_register_device + video_unregister_device + vmalloc + vmalloc_to_page + vmap + vsnprintf + vunmap + vzalloc + wait_for_completion + wait_for_completion_interruptible_timeout + wait_for_completion_timeout + __wake_up + wake_up_process + wakeup_source_unregister + __warn_printk + work_busy + +# required by adv7511.ko + cec_s_phys_addr + cec_s_phys_addr_from_edid + cec_unregister_adapter + drm_bridge_hpd_notify + drm_detect_hdmi_monitor + drm_do_get_edid + hdmi_avi_infoframe_init + hdmi_avi_infoframe_pack + i2c_new_ancillary_device + regmap_bulk_write + regmap_register_patch + +# required by bts-exynos.ko + strpbrk + +# required by bufq.ko + kstrndup + +# required by clk_exynos.ko + __clk_get_hw + clk_hw_get_parent + clk_register_clkdev + clk_register_fixed_factor + clk_register_fixed_rate + of_clk_src_onecell_get + +# required by cmupmucal.ko + debugfs_create_x32 + kernel_kobj + +# required by dss.ko + __alloc_percpu + android_debug_symbol + arch_timer_read_counter + atomic_notifier_call_chain + __cpu_possible_mask + _dev_emerg + dump_backtrace + init_task + input_close_device + input_open_device + input_register_handle + input_register_handler + input_unregister_handle + irq_to_desc + kmsg_dump_rewind + kstat + nr_irqs + __per_cpu_offset + proc_create + register_die_notifier + return_address + rtc_time64_to_tm + smp_call_function + sysfs_create_groups + sys_tz + time64_to_tm + __traceiter_android_vh_ipi_stop + __traceiter_android_vh_logbuf + __traceiter_cpu_idle + __traceiter_device_pm_callback_end + __traceiter_device_pm_callback_start + __traceiter_hrtimer_expire_entry + __traceiter_hrtimer_expire_exit + __traceiter_irq_handler_entry + __traceiter_irq_handler_exit + __traceiter_sched_switch + __traceiter_suspend_resume + __traceiter_workqueue_execute_end + __traceiter_workqueue_execute_start + __tracepoint_android_vh_ipi_stop + __tracepoint_android_vh_logbuf + __tracepoint_cpu_idle + __tracepoint_device_pm_callback_end + __tracepoint_device_pm_callback_start + __tracepoint_hrtimer_expire_entry + __tracepoint_hrtimer_expire_exit + __tracepoint_irq_handler_entry + __tracepoint_irq_handler_exit + __tracepoint_sched_switch + __tracepoint_suspend_resume + __tracepoint_workqueue_execute_end + __tracepoint_workqueue_execute_start + +# required by dwc3-exynosauto-usb.ko + device_for_each_child + device_property_present + devm_regulator_get + phy_exit + phy_init + platform_device_add + platform_device_add_properties + platform_device_add_resources + platform_device_alloc + platform_device_del + platform_device_put + platform_get_irq_byname_optional + __pm_relax + pm_runtime_allow + pm_runtime_forbid + __pm_runtime_set_status + __pm_stay_awake + __traceiter_dwc3_readl + __traceiter_dwc3_writel + __tracepoint_dwc3_readl + __tracepoint_dwc3_writel + usb_gadget_set_state + usb_otg_state_string + +# required by exynos-chipid_v2.ko + soc_device_register + subsys_system_register + +# required by exynos-pd.ko + of_genpd_add_provider_simple + pm_genpd_add_subdomain + pm_genpd_init + +# required by exynos9drm.ko + bus_find_device + component_add + component_bind_all + component_del + component_master_add_with_match + component_master_del + component_unbind_all + console_trylock + console_unlock + debugfs_lookup + device_rename + drm_atomic_helper_check + drm_atomic_helper_cleanup_planes + drm_atomic_helper_commit + drm_atomic_helper_commit_modeset_disables + drm_atomic_helper_commit_planes + drm_atomic_helper_crtc_destroy_state + drm_atomic_helper_crtc_duplicate_state + drm_atomic_helper_crtc_reset + drm_atomic_helper_disable_plane + drm_atomic_helper_fake_vblank + drm_atomic_helper_page_flip + __drm_atomic_helper_plane_destroy_state + __drm_atomic_helper_plane_duplicate_state + drm_atomic_helper_set_config + drm_atomic_helper_shutdown + drm_atomic_helper_update_plane + drm_atomic_helper_wait_for_vblanks + drm_atomic_normalize_zpos + drm_bridge_attach + drm_compat_ioctl + drm_connector_list_iter_begin + drm_connector_list_iter_end + drm_connector_list_iter_next + drm_connector_unregister + drm_crtc_arm_vblank_event + drm_crtc_cleanup + __drm_crtc_commit_free + drm_crtc_handle_vblank + drm_crtc_init_with_planes + drm_crtc_send_vblank_event + drm_crtc_vblank_count + drm_crtc_vblank_get + drm_crtc_vblank_off + drm_crtc_vblank_on + drm_crtc_vblank_put + __drm_dbg + drm_debugfs_create_files + drm_dev_alloc + drm_dev_dbg + drm_dev_printk + drm_dev_put + drm_dev_register + drm_dev_unregister + drm_display_mode_to_videomode + drm_dp_aux_register + drm_dp_aux_unregister + drm_dp_bw_code_to_link_rate + drm_dp_channel_eq_ok + drm_dp_clock_recovery_ok + drm_dp_dpcd_read + drm_dp_dpcd_read_link_status + drm_dp_dpcd_write + drm_dp_get_adjust_request_pre_emphasis + drm_dp_get_adjust_request_voltage + drm_dp_link_train_channel_eq_delay + drm_dp_link_train_clock_recovery_delay + drm_encoder_cleanup + drm_encoder_init + drm_flip_work_cleanup + drm_flip_work_commit + drm_flip_work_init + drm_flip_work_queue + drm_framebuffer_cleanup + drm_framebuffer_init + drm_gem_create_mmap_offset + drm_gem_handle_create + drm_gem_mmap + drm_gem_object_free + drm_gem_object_lookup + drm_gem_object_release + drm_gem_prime_fd_to_handle + drm_gem_prime_handle_to_fd + drm_gem_private_object_init + drm_gem_vm_close + drm_gem_vm_open + drm_get_connector_status_name + drm_get_edid + drm_get_format_info + drm_helper_connector_dpms + drm_helper_hpd_irq_event + drm_helper_mode_fill_fb_struct + drm_ioctl + drm_kms_helper_poll_fini + drm_kms_helper_poll_init + drmm_mode_config_init + drm_mode_config_cleanup + drm_mode_config_helper_resume + drm_mode_config_helper_suspend + drm_mode_config_reset + drm_mode_object_get + drm_mode_object_put + drm_of_component_match_add + drm_of_find_possible_crtcs + drm_open + drm_panel_disable + drm_panel_enable + drm_panel_get_modes + drm_panel_prepare + drm_panel_unprepare + drm_plane_cleanup + drm_plane_create_alpha_property + drm_plane_create_blend_mode_property + drm_plane_create_zpos_property + drm_poll + drm_prime_gem_destroy + drm_read + drm_release + drm_universal_plane_init + drm_vblank_init + kstrtobool + mipi_dsi_host_register + mipi_dsi_host_unregister + of_drm_find_bridge + of_drm_find_panel + of_graph_get_endpoint_by_regs + of_graph_get_next_endpoint + of_graph_get_remote_port + of_graph_get_remote_port_parent + of_graph_parse_endpoint + of_phandle_iterator_init + of_phandle_iterator_next + platform_find_device_by_driver + seq_hex_dump + strnstr + +# required by exynos_mfc.ko + iommu_dma_reserve_iova + iommu_map_sg + iommu_unmap + +# required by exynos_pm_qos.ko + kstrtoint_from_user + _raw_read_lock_irqsave + _raw_read_unlock_irqrestore + _raw_write_lock_irqsave + _raw_write_unlock_irqrestore + +# required by exynos_tty.ko + dma_get_slave_caps + do_SAK + handle_sysrq + register_console + sysrq_mask + tty_flip_buffer_push + tty_insert_flip_string_fixed_flag + tty_kref_put + tty_port_tty_get + uart_add_one_port + uart_console_write + uart_get_baud_rate + uart_parse_options + uart_register_driver + uart_remove_one_port + uart_resume_port + uart_set_options + uart_suspend_port + uart_try_toggle_sysrq + uart_unregister_driver + uart_update_timeout + uart_write_wakeup + +# required by g2d.ko + add_timer + cancel_delayed_work + device_get_dma_attr + dma_fence_signal_locked + frame_vector_create + frame_vector_destroy + get_vaddr_frames + mod_delayed_work_on + put_vaddr_frames + +# required by i2c-exynosauto.ko + i2c_del_adapter + +# required by lt8912.ko + drm_mode_duplicate + +# required by mali_kbase.ko + anon_inode_getfd + __arch_clear_user + __bitmap_weight + bpf_trace_run1 + bpf_trace_run3 + bpf_trace_run5 + cache_line_size + clear_page + __close_fd + debugfs_create_bool + dev_pm_opp_of_add_table + dev_pm_opp_of_remove_table + dev_pm_opp_put_regulators + dev_pm_opp_set_regulators + dma_fence_get_status + down + downgrade_write + down_trylock + down_write + failure_tracking + __get_task_comm + get_user_pages + get_user_pages_fast + get_user_pages_remote + hrtimer_active + hrtimer_cancel + hrtimer_forward + hrtimer_init + hrtimer_start_range_ns + kstrtobool_from_user + ktime_get_raw + kvfree_call_rcu + __mmdrop + module_put + of_machine_is_compatible + __page_pinner_migration_failed + param_ops_byte + __put_page + rb_erase + rb_first + rb_insert_color + rb_next + rb_prev + rb_replace_node + register_shrinker + remap_pfn_range + remap_vmalloc_range + seq_open + seq_write + static_key_slow_dec + static_key_slow_inc + strncasecmp + __sw_hweight32 + __sw_hweight64 + synchronize_rcu + sysfs_streq + system_highpri_wq + __traceiter_gpu_mem_total + trace_output_call + __tracepoint_gpu_mem_total + trace_print_array_seq + trace_print_flags_seq + trace_print_symbols_seq + try_module_get + unmap_mapping_range + unregister_shrinker + up_write + vmalloc_user + vmf_insert_pfn_prot + +# required by mcDrvModule.ko + crypto_alloc_shash + crypto_destroy_tfm + crypto_shash_final + crypto_shash_update + d_path + get_task_exe_file + get_zeroed_page + kstrtol_from_user + kstrtouint_from_user + pin_user_pages + release_pages + sg_miter_next + sg_miter_start + sg_miter_stop + unpin_user_page + wait_for_completion_interruptible + wait_for_completion_killable + +# required by panel-samsung-dummy.ko + drm_panel_add + drm_panel_init + drm_panel_remove + +# required by pcie-exynos-dw-ep.ko + +# required by pcie-exynos-dw-rc.ko + bitmap_find_free_region + bitmap_release_region + dw_pcie_host_init + dw_pcie_msi_init + dw_pcie_own_conf_map_bus + dw_pcie_read + dw_pcie_setup_rc + dw_pcie_write + irq_chip_ack_parent + irq_chip_mask_parent + irq_chip_unmask_parent + irq_domain_get_irq_data + irq_domain_set_info + irq_domain_update_bus_token + pcie_get_mps + pci_find_bus + pci_generic_config_read + pci_generic_config_write + pci_get_device + pci_load_saved_state + pci_msi_create_irq_domain + pci_msi_mask_irq + pci_msi_unmask_irq + pci_rescan_bus + pci_restore_state + pci_save_state + pci_store_saved_state + +# required by pcs-xpcs.ko + +# required by pinctrl-samsung-core.ko + devm_gpiochip_add_data_with_key + devm_pinctrl_register + gpiochip_generic_free + gpiochip_generic_request + gpiochip_get_data + gpiochip_lock_as_irq + gpiochip_unlock_as_irq + irq_create_mapping_affinity + irq_domain_xlate_twocell + irq_set_chained_handler_and_data + of_node_name_eq + pinctrl_add_gpio_range + pinctrl_dev_get_drvdata + pinctrl_remove_gpio_range + +# required by pl330.ko + amba_driver_register + amba_driver_unregister + dev_err_probe + __devm_reset_control_get + dma_async_device_register + dma_async_device_unregister + dma_async_tx_descriptor_init + dmaengine_unmap_put + dma_get_slave_channel + dma_map_resource + dma_unmap_resource + of_dma_controller_free + of_dma_controller_register + pm_runtime_force_resume + pm_runtime_force_suspend + pm_runtime_irq_safe + reset_control_assert + reset_control_deassert + tasklet_setup + +# required by pps_core.ko + fasync_helper + idr_alloc + idr_get_next + idr_remove + kill_fasync + +# required by ptp.ko + ida_alloc_range + ida_destroy + ida_free + kthread_cancel_delayed_work_sync + kthread_create_worker + kthread_delayed_work_timer_fn + kthread_destroy_worker + kthread_mod_delayed_work + kthread_queue_delayed_work + +# required by reboot-mode.ko + devres_free + devres_release + kfree_const + kstrdup_const + +# required by rtc-s2vps01.ko + rtc_update_irq + rtc_valid_tm + +# required by s3c2410_wdt.ko + watchdog_init_timeout + watchdog_register_device + watchdog_set_restart_priority + watchdog_unregister_device + +# required by sam-is.ko + atomic_notifier_chain_unregister + get_task_pid + i2c_get_adapter + i2c_new_client_device + jiffies_to_msecs + kobject_del + kstrtou16 + kthread_flush_work + kthread_flush_worker + ktime_get_with_offset + param_ops_string + phy_configure + pm_relax + pm_stay_awake + regulator_get_voltage + regulator_is_enabled + regulator_set_voltage + sched_set_fifo + tasklet_init + v4l2_device_register_subdev + v4l2_device_unregister_subdev + v4l2_subdev_call_wrappers + +# required by samsung-iommu-group.ko + iommu_group_alloc + iommu_group_set_name + +# required by samsung-secure-iova.ko + gen_pool_avail + gen_pool_create + gen_pool_destroy + gen_pool_first_fit_align + gen_pool_size + +# required by samsung-seqos.ko + alloc_etherdev_mqs + __bitmap_andnot + consume_skb + dev_close + device_set_wakeup_capable + device_set_wakeup_enable + __dev_kfree_skb_any + dev_open + eth_mac_addr + ethtool_op_get_link + ethtool_op_get_ts_info + eth_type_trans + free_netdev + in4_pton + in6_pton + jiffies_to_usecs + mdiobus_alloc_size + mdiobus_free + __mdiobus_register + mdiobus_unregister + napi_complete_done + napi_disable + napi_gro_receive + __napi_schedule + napi_schedule_prep + __netdev_alloc_skb + netdev_err + netdev_info + netdev_update_features + netdev_warn + netif_carrier_off + netif_device_attach + netif_device_detach + netif_napi_add + __netif_napi_del + netif_schedule_queue + netif_set_real_num_rx_queues + netif_set_real_num_tx_queues + netif_tx_wake_queue + net_ratelimit + phy_disconnect + phy_ethtool_nway_reset + phy_stop + pinctrl_pm_select_default_state + pinctrl_pm_select_sleep_state + platform_get_irq_byname + _raw_spin_lock_bh + _raw_spin_unlock_bh + register_netdev + rtnl_lock + rtnl_unlock + skb_pull + skb_put + skb_tstamp_tx + synchronize_net + unregister_netdev + +# required by samsung_dma_heap.ko + anon_inode_getfile + deferred_free + devm_add_action + devm_gen_pool_create + dmabuf_page_pool_alloc + dmabuf_page_pool_create + dmabuf_page_pool_destroy + dmabuf_page_pool_free + dma_heap_add + dma_heap_get_dev + dma_heap_get_drvdata + dma_heap_get_name + is_dma_buf_file + iterate_fd + mutex_trylock + of_reserved_mem_device_release + vm_insert_page + +# required by samsung_iommu.ko + bus_set_iommu + device_link_add + device_link_del + iommu_attach_group + iommu_device_register + iommu_device_sysfs_add + iommu_device_sysfs_remove + iommu_device_unlink + iommu_device_unregister + iommu_domain_alloc + iommu_fwspec_add_ids + iommu_fwspec_free + iommu_get_dma_cookie + iommu_group_for_each_dev + iommu_group_get + iommu_group_get_iommudata + iommu_group_set_iommudata + iommu_put_dma_cookie + iommu_report_device_fault + kmem_cache_alloc + kmem_cache_create + kmem_cache_destroy + kmem_cache_free + of_get_dma_window + pfn_valid + +# required by scaler.ko + clk_set_parent + dma_heap_buffer_free + v4l2_ctrl_handler_free + v4l2_ctrl_handler_init_class + v4l2_ctrl_handler_setup + v4l2_ctrl_new_custom + v4l2_ctrl_new_std + v4l2_m2m_buf_queue + v4l2_m2m_buf_remove + v4l2_m2m_ctx_init + v4l2_m2m_ctx_release + v4l2_m2m_dqbuf + v4l2_m2m_get_curr_priv + v4l2_m2m_get_vq + v4l2_m2m_init + v4l2_m2m_job_finish + v4l2_m2m_mmap + v4l2_m2m_next_buf + v4l2_m2m_poll + v4l2_m2m_qbuf + v4l2_m2m_release + v4l2_m2m_reqbufs + v4l2_m2m_streamoff + v4l2_m2m_streamon + v4l2_m2m_try_schedule + v4l_bound_align_image + +# required by snd-soc-s3c-dma.ko + devm_snd_dmaengine_pcm_register + snd_dmaengine_pcm_prepare_slave_config + +# required by snd-soc-samsung-abox-core.ko + devm_iounmap + __devm_regmap_init + __devm_regmap_init_mmio_clk + dma_mmap_attrs + __platform_register_drivers + platform_unregister_drivers + pm_runtime_no_callbacks + snd_pcm_hw_constraint_integer + snd_pcm_lib_free_pages + snd_pcm_lib_malloc_pages + snd_pcm_lib_preallocate_free_for_all + snd_pcm_lib_preallocate_pages + snd_pcm_period_elapsed + snd_soc_component_init_regmap + snd_soc_component_read + snd_soc_dapm_add_routes + snd_soc_dapm_get_enum_double + snd_soc_dapm_new_control + snd_soc_dapm_new_controls + snd_soc_dapm_put_enum_double + snd_soc_info_enum_double + snd_soc_set_runtime_hwparams + snd_soc_unregister_component + +# required by snd-soc-tas6424.ko + _dev_crit + regcache_cache_only + snd_soc_get_volsw + snd_soc_put_volsw + +# required by spi-exynosauto.ko + __spi_alloc_controller + spi_controller_resume + spi_controller_suspend + spi_delay_exec + spi_finalize_current_message + spi_register_controller + spi_unregister_controller + +# required by spidev.ko + driver_unregister + find_next_zero_bit + __spi_register_driver + spi_setup + spi_sync + stream_open + +# required by syscon-reboot-mode.ko + syscon_node_to_regmap + +# required by ufs-exynosauto-core.ko + of_property_read_variable_u16_array + __traceiter_android_vh_ufs_fill_prdt + __tracepoint_android_vh_ufs_fill_prdt + ufshcd_alloc_host + ufshcd_config_pwr_mode + ufshcd_dme_get_attr + ufshcd_dme_set_attr + ufshcd_link_recovery + ufshcd_pltfrm_init + ufshcd_remove + ufshcd_shutdown + ufshcd_system_resume + ufshcd_system_suspend + +# required by vbpipe-module.ko + wakeup_source_register + +# required by vbufq-be-module.ko + drain_workqueue + radix_tree_delete + radix_tree_insert + radix_tree_lookup + radix_tree_next_chunk + +# required by vdriver-lib-module.ko + kset_create_and_add + +# required by vevdev-fe-module.ko + input_alloc_absinfo + input_allocate_device + input_event + input_free_device + input_mt_init_slots + input_register_device + input_unregister_device + +# required by videobuf2-dma-sg.ko + vb2_common_vm_ops + vb2_create_framevec + vb2_destroy_framevec + vm_map_pages + vm_map_ram + vm_unmap_ram + +# required by vlx-clk-ctrl-common-module.ko + vscnprintf + +# required by vlx-hyp-module.ko + ioremap_cache + irq_create_of_mapping + irq_dispose_mapping + irq_find_matching_fwspec + of_irq_find_parent + proc_mkdir + +# required by vlx-last-kmsg-module.ko + proc_set_size + +# required by vlx-prop-module.ko + kobject_uevent + sysfs_create_bin_file + sysfs_remove_bin_file + +# required by vlx-vipc-module.ko + sigprocmask + +# required by vlx-vmq-module.ko + remove_wait_queue + +# required by vrpc-module.ko + current_work diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 index 3f0266dc84b7..39558289bee5 100644 --- a/build.config.gki.aarch64 +++ b/build.config.gki.aarch64 @@ -16,6 +16,7 @@ android/abi_gki_aarch64_virtual_device android/abi_gki_aarch64_hikey960 android/abi_gki_aarch64_generic android/abi_gki_aarch64_exynos +android/abi_gki_aarch64_exynosauto android/abi_gki_aarch64_mtk android/abi_gki_aarch64_xiaomi android/abi_gki_aarch64_fips140 From 5b1baee639f3aec7fe2f86cb4b29c64c026c66ec Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Mon, 28 Jun 2021 12:29:30 +0900 Subject: [PATCH 57/60] ANDROID: GKI: update allowed symbols for exynosauto soc This patch updates ABI allowed symbol list for exynosauto soc. Notable changes: - *drm* and *display* symbols are required for DRM display vendor module. - blk_ksm_init_passthrough: use passthrough mode of keyslot manager - kmsg_dump_get_line to dump kmsg as line by line Leaf changes summary: 28 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 27 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 1 Added variable 27 Added functions: [A] 'function int __bitmap_and(unsigned long int*, const unsigned long int*, const unsigned long int*, unsigned int)' [A] 'function void __drm_atomic_helper_plane_reset(drm_plane*, drm_plane_state*)' [A] 'function int __traceiter_android_vh_show_mem(void*, unsigned int, nodemask_t*)' [A] 'function void blk_ksm_init_passthrough(blk_keyslot_manager*)' [A] 'function int default_wake_function(wait_queue_entry_t*, unsigned int, int, void*)' [A] 'function void display_timings_release(display_timings*)' [A] 'function void drm_atomic_bridge_chain_enable(drm_bridge*, drm_atomic_state*)' [A] 'function void drm_atomic_bridge_chain_pre_enable(drm_bridge*, drm_atomic_state*)' [A] 'function void drm_atomic_helper_disable_planes_on_crtc(drm_crtc_state*, bool)' [A] 'function wait_queue_head_t* drm_crtc_vblank_waitqueue(drm_crtc*)' [A] 'function void drm_display_mode_from_videomode(const videomode*, drm_display_mode*)' [A] 'function void drm_dp_downstream_debug(seq_file*, const u8*, const u8*, const edid*, drm_dp_aux*)' [A] 'function u8 drm_dp_dsc_sink_line_buf_depth(const u8*)' [A] 'function u8 drm_dp_dsc_sink_max_slice_count(const u8*, bool)' [A] 'function void drm_dp_mst_dump_topology(seq_file*, drm_dp_mst_topology_mgr*)' [A] 'function int drm_dsc_compute_rc_parameters(drm_dsc_config*)' [A] 'function void drm_dsc_pps_payload_pack(drm_dsc_picture_parameter_set*, const drm_dsc_config*)' [A] 'function uint32_t drm_of_crtc_port_mask(drm_device*, device_node*)' [A] 'function int drm_plane_create_zpos_immutable_property(drm_plane*, unsigned int)' [A] 'function void iommu_group_remove_device(device*)' [A] 'function bool kmsg_dump_get_line(kmsg_dumper*, bool, char*, size_t, size_t*)' [A] 'function void kset_unregister(kset*)' [A] 'function display_timings* of_get_display_timings(const device_node*)' [A] 'function int of_get_drm_display_mode(device_node*, drm_display_mode*, u32*, int)' [A] 'function device_node* of_graph_get_port_by_id(device_node*, u32)' [A] 'function int v4l2_m2m_querybuf(file*, v4l2_m2m_ctx*, v4l2_buffer*)' [A] 'function int videomode_from_timings(const display_timings*, videomode*, unsigned int)' 1 Added variable: [A] 'tracepoint __tracepoint_android_vh_show_mem' Bug: 192103187 Signed-off-by: Chanho Park Change-Id: I1a2697c61f31aa857ea2cbff46ead13719918db1 --- android/abi_gki_aarch64.xml | 1145 ++++++++++++++++++++-------- android/abi_gki_aarch64_exynosauto | 28 + 2 files changed, 842 insertions(+), 331 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index a948f4d3aeba..f08312c5a7ea 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -17,6 +17,7 @@ + @@ -81,6 +82,7 @@ + @@ -364,6 +366,7 @@ + @@ -591,6 +594,7 @@ + @@ -1040,6 +1044,7 @@ + @@ -1320,6 +1325,7 @@ + @@ -1442,6 +1448,8 @@ + + @@ -1475,6 +1483,7 @@ + @@ -1556,6 +1565,7 @@ + @@ -1572,6 +1582,7 @@ + @@ -1584,9 +1595,12 @@ + + + @@ -1597,6 +1611,7 @@ + @@ -1609,6 +1624,8 @@ + + @@ -1754,6 +1771,7 @@ + @@ -1768,6 +1786,7 @@ + @@ -2323,6 +2342,7 @@ + @@ -2445,6 +2465,7 @@ + @@ -2461,6 +2482,7 @@ + @@ -2856,7 +2878,9 @@ + + @@ -2866,6 +2890,7 @@ + @@ -4494,6 +4519,7 @@ + @@ -4556,6 +4582,7 @@ + @@ -4890,6 +4917,7 @@ + @@ -42621,6 +42649,10 @@ + + + + @@ -45761,6 +45793,7 @@ + @@ -46557,6 +46590,12 @@ + + + + + + @@ -46834,6 +46873,7 @@ + @@ -57981,8 +58021,6 @@ - - @@ -58196,6 +58234,7 @@ + @@ -58223,6 +58262,7 @@ + @@ -62646,7 +62686,7 @@ - + @@ -63029,7 +63069,6 @@ - @@ -63069,7 +63108,6 @@ - @@ -63176,6 +63214,7 @@ + @@ -63203,6 +63242,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -63731,6 +63802,17 @@ + + + + + + + + + + + @@ -63755,6 +63837,22 @@ + + + + + + + + + + + + + + + + @@ -67587,6 +67685,11 @@ + + + + + @@ -67945,6 +68048,11 @@ + + + + + @@ -68449,6 +68557,11 @@ + + + + + @@ -68459,6 +68572,16 @@ + + + + + + + + + + @@ -73676,6 +73799,15 @@ + + + + + + + + + @@ -73695,6 +73827,14 @@ + + + + + + + + @@ -75272,6 +75412,11 @@ + + + + + @@ -75383,6 +75528,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -76489,12 +76943,6 @@ - - - - - - @@ -76582,149 +77030,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -77050,58 +77355,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - @@ -77127,6 +77385,18 @@ + + + + + + + + + + + + @@ -77184,6 +77454,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -77271,6 +77574,11 @@ + + + + + @@ -77801,6 +78109,10 @@ + + + + @@ -83904,6 +84216,10 @@ + + + + @@ -84636,6 +84952,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -96548,6 +96891,12 @@ + + + + + + @@ -106752,6 +107101,11 @@ + + + + + @@ -121911,32 +122265,10 @@ - - - - - - - - - - - - - - - - - - - - - - @@ -122024,11 +122356,6 @@ - - - - - @@ -123327,7 +123654,7 @@ - + @@ -128615,6 +128942,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -129067,6 +129473,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -151945,6 +152402,14 @@ + + + + + + + + @@ -153333,6 +153798,22 @@ + + + + + + + + + + + + + + + + @@ -153348,6 +153829,7 @@ + @@ -153357,6 +153839,8 @@ + + @@ -153374,25 +153858,25 @@ - + - - - + + + - + - + - - - + + + @@ -153400,7 +153884,7 @@ - + @@ -153471,12 +153955,12 @@ - - + + - - + + @@ -153484,43 +153968,43 @@ - - + + - - - - + + + + - - - - + + + + - - - + + + - - - + + + - - - + + + - - + + - - + + @@ -153530,10 +154014,17 @@ - - + + + + + + + + + @@ -153546,8 +154037,8 @@ - - + + @@ -153572,6 +154063,13 @@ + + + + + + + @@ -153848,18 +154346,18 @@ - - + + - - + + - - - - + + + + @@ -154089,25 +154587,6 @@ - - - - - - - - - - - - - - - - - - - @@ -154195,13 +154674,6 @@ - - - - - - - @@ -164105,6 +164577,13 @@ + + + + + + + @@ -164936,6 +165415,10 @@ + + + + @@ -167888,9 +168371,9 @@ - - - + + + @@ -170222,23 +170705,23 @@ - - + + - - - - + + + + - - - - + + + + - + @@ -188198,6 +188681,17 @@ + + + + + + + + + + + @@ -188273,17 +188767,6 @@ - - - - - - - - - - - diff --git a/android/abi_gki_aarch64_exynosauto b/android/abi_gki_aarch64_exynosauto index 8335604d5c49..1b6b49c30e41 100644 --- a/android/abi_gki_aarch64_exynosauto +++ b/android/abi_gki_aarch64_exynosauto @@ -10,6 +10,7 @@ arm64_use_ng_mappings __arm_smccc_smc atomic_notifier_chain_register + __bitmap_and blocking_notifier_call_chain blocking_notifier_chain_register blocking_notifier_chain_unregister @@ -98,6 +99,7 @@ _dev_warn disable_irq disable_irq_nosync + display_timings_release dma_alloc_attrs dma_buf_attach dma_buf_begin_cpu_access @@ -147,6 +149,7 @@ drm_connector_init drm_connector_register drm_connector_update_edid_property + drm_display_mode_from_videomode __drm_err drm_helper_probe_single_connector_modes drm_kms_helper_hotplug_event @@ -237,6 +240,7 @@ kobject_init_and_add kobject_put krealloc + kset_unregister kstrdup kstrtoint kstrtou8 @@ -306,6 +310,7 @@ of_find_node_opts_by_path of_find_property of_get_child_by_name + of_get_display_timings of_get_named_gpio_flags of_get_next_child of_get_property @@ -526,6 +531,7 @@ video_device_alloc video_device_release video_ioctl2 + videomode_from_timings __video_register_device video_unregister_device vmalloc @@ -589,6 +595,7 @@ input_register_handler input_unregister_handle irq_to_desc + kmsg_dump_get_line kmsg_dump_rewind kstat nr_irqs @@ -674,6 +681,8 @@ console_unlock debugfs_lookup device_rename + drm_atomic_bridge_chain_enable + drm_atomic_bridge_chain_pre_enable drm_atomic_helper_check drm_atomic_helper_cleanup_planes drm_atomic_helper_commit @@ -683,10 +692,12 @@ drm_atomic_helper_crtc_duplicate_state drm_atomic_helper_crtc_reset drm_atomic_helper_disable_plane + drm_atomic_helper_disable_planes_on_crtc drm_atomic_helper_fake_vblank drm_atomic_helper_page_flip __drm_atomic_helper_plane_destroy_state __drm_atomic_helper_plane_duplicate_state + __drm_atomic_helper_plane_reset drm_atomic_helper_set_config drm_atomic_helper_shutdown drm_atomic_helper_update_plane @@ -709,6 +720,7 @@ drm_crtc_vblank_off drm_crtc_vblank_on drm_crtc_vblank_put + drm_crtc_vblank_waitqueue __drm_dbg drm_debugfs_create_files drm_dev_alloc @@ -723,13 +735,19 @@ drm_dp_bw_code_to_link_rate drm_dp_channel_eq_ok drm_dp_clock_recovery_ok + drm_dp_downstream_debug drm_dp_dpcd_read drm_dp_dpcd_read_link_status drm_dp_dpcd_write + drm_dp_dsc_sink_line_buf_depth + drm_dp_dsc_sink_max_slice_count drm_dp_get_adjust_request_pre_emphasis drm_dp_get_adjust_request_voltage drm_dp_link_train_channel_eq_delay drm_dp_link_train_clock_recovery_delay + drm_dp_mst_dump_topology + drm_dsc_compute_rc_parameters + drm_dsc_pps_payload_pack drm_encoder_cleanup drm_encoder_init drm_flip_work_cleanup @@ -766,6 +784,7 @@ drm_mode_object_get drm_mode_object_put drm_of_component_match_add + drm_of_crtc_port_mask drm_of_find_possible_crtcs drm_open drm_panel_disable @@ -776,6 +795,7 @@ drm_plane_cleanup drm_plane_create_alpha_property drm_plane_create_blend_mode_property + drm_plane_create_zpos_immutable_property drm_plane_create_zpos_property drm_poll drm_prime_gem_destroy @@ -790,6 +810,7 @@ of_drm_find_panel of_graph_get_endpoint_by_regs of_graph_get_next_endpoint + of_graph_get_port_by_id of_graph_get_remote_port of_graph_get_remote_port_parent of_graph_parse_endpoint @@ -851,6 +872,7 @@ # required by lt8912.ko drm_mode_duplicate + of_get_drm_display_mode # required by mali_kbase.ko anon_inode_getfd @@ -1161,6 +1183,8 @@ iterate_fd mutex_trylock of_reserved_mem_device_release + __traceiter_android_vh_show_mem + __tracepoint_android_vh_show_mem vm_insert_page # required by samsung_iommu.ko @@ -1180,6 +1204,7 @@ iommu_group_for_each_dev iommu_group_get iommu_group_get_iommudata + iommu_group_remove_device iommu_group_set_iommudata iommu_put_dma_cookie iommu_report_device_fault @@ -1211,6 +1236,7 @@ v4l2_m2m_next_buf v4l2_m2m_poll v4l2_m2m_qbuf + v4l2_m2m_querybuf v4l2_m2m_release v4l2_m2m_reqbufs v4l2_m2m_streamoff @@ -1274,6 +1300,7 @@ syscon_node_to_regmap # required by ufs-exynosauto-core.ko + blk_ksm_init_passthrough of_property_read_variable_u16_array __traceiter_android_vh_ufs_fill_prdt __tracepoint_android_vh_ufs_fill_prdt @@ -1341,6 +1368,7 @@ sigprocmask # required by vlx-vmq-module.ko + default_wake_function remove_wait_queue # required by vrpc-module.ko From 2e289f3641a9c37ad054f9e84398533ccd930c8f Mon Sep 17 00:00:00 2001 From: Weilun Du Date: Thu, 6 May 2021 11:05:29 -0700 Subject: [PATCH 58/60] FROMGIT: mac80211_hwsim: add concurrent channels scanning support over virtio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixed the crash when setting channels to 2 or more when communicating over virtio. Signed-off-by: Weilun Du Link: https://lore.kernel.org/r/20210506180530.3418576-1-wdu@google.com Signed-off-by: Johannes Berg (cherry picked from commit 626c30f9e77354301ff9162c3bdddaf92d9b5cf3 https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=626c30f9e77354301ff9162c3bdddaf92d9b5cf3) Bug: 182576217 Signed-off-by: Weilun Du Signed-off-by: Maciej Żenczykowski Change-Id: Ia9be6c1d962b941a92f4e1be41e874dbe08024e5 --- drivers/net/wireless/mac80211_hwsim.c | 48 +++++++++++++++++++++------ 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index c966069845f4..31e21d8f2972 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -561,6 +561,7 @@ struct mac80211_hwsim_data { u32 ciphers[ARRAY_SIZE(hwsim_ciphers)]; struct mac_address addresses[2]; + struct ieee80211_chanctx_conf *chanctx; int channels, idx; bool use_chanctx; bool destroy_on_close; @@ -1191,7 +1192,8 @@ static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate) static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, struct sk_buff *my_skb, - int dst_portid) + int dst_portid, + struct ieee80211_channel *channel) { struct sk_buff *skb; struct mac80211_hwsim_data *data = hw->priv; @@ -1246,7 +1248,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags)) goto nla_put_failure; - if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq)) + if (nla_put_u32(skb, HWSIM_ATTR_FREQ, channel->center_freq)) goto nla_put_failure; /* We get the tx control (rate and retries) info*/ @@ -1593,7 +1595,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, _portid = READ_ONCE(data->wmediumd); if (_portid || hwsim_virtio_enabled) - return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); + return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel); /* NO wmediumd detected, perfect medium simulation */ data->tx_pkts++; @@ -1704,7 +1706,7 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, mac80211_hwsim_monitor_rx(hw, skb, chan); if (_pid || hwsim_virtio_enabled) - return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); + return mac80211_hwsim_tx_frame_nl(hw, skb, _pid, chan); mac80211_hwsim_tx_frame_no_nl(hw, skb, chan); dev_kfree_skb(skb); @@ -2443,6 +2445,11 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw, static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + hwsim->chanctx = ctx; + mutex_unlock(&hwsim->mutex); hwsim_set_chanctx_magic(ctx); wiphy_dbg(hw->wiphy, "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", @@ -2454,6 +2461,11 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + hwsim->chanctx = NULL; + mutex_unlock(&hwsim->mutex); wiphy_dbg(hw->wiphy, "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", ctx->def.chan->center_freq, ctx->def.width, @@ -2466,6 +2478,11 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx, u32 changed) { + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + hwsim->chanctx = ctx; + mutex_unlock(&hwsim->mutex); hwsim_check_chanctx_magic(ctx); wiphy_dbg(hw->wiphy, "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", @@ -3060,6 +3077,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, hw->wiphy->max_remain_on_channel_duration = 1000; data->if_combination.radar_detect_widths = 0; data->if_combination.num_different_channels = data->channels; + data->chanctx = NULL; } else { data->if_combination.num_different_channels = 1; data->if_combination.radar_detect_widths = @@ -3567,6 +3585,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, int frame_data_len; void *frame_data; struct sk_buff *skb = NULL; + struct ieee80211_channel *channel = NULL; if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || !info->attrs[HWSIM_ATTR_FRAME] || @@ -3593,6 +3612,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, if (!data2) goto out; + if (data2->use_chanctx) { + if (data2->tmp_chan) + channel = data2->tmp_chan; + else if (data2->chanctx) + channel = data2->chanctx->def.chan; + } else { + channel = data2->channel; + } + if (!channel) + goto out; + if (!hwsim_virtio_enabled) { if (hwsim_net_get_netgroup(genl_info_net(info)) != data2->netgroup) @@ -3604,7 +3634,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, /* check if radio is configured properly */ - if (data2->idle || !data2->started) + if ((data2->idle && !data2->tmp_chan) || !data2->started) goto out; /* A frame is received from user space */ @@ -3617,18 +3647,16 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, mutex_lock(&data2->mutex); rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]); - if (rx_status.freq != data2->channel->center_freq && - (!data2->tmp_chan || - rx_status.freq != data2->tmp_chan->center_freq)) { + if (rx_status.freq != channel->center_freq) { mutex_unlock(&data2->mutex); goto out; } mutex_unlock(&data2->mutex); } else { - rx_status.freq = data2->channel->center_freq; + rx_status.freq = channel->center_freq; } - rx_status.band = data2->channel->band; + rx_status.band = channel->band; rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); From 3b6916b4d499de947cbcfeada39bf9aacffdf87d Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Tue, 22 Jun 2021 12:05:36 -0700 Subject: [PATCH 59/60] ANDROID: iommu/io-pgtable-arm: Add IOMMU_CACHE_ICACHE_OCACHE_NWA Allow io-coherent devices to use a inner writeback read/write allocate, outer writeback read allocate, no-write allocate cache policy. The outer cache policy affects the behavior of a system cache, at least on qcom boards which have one. The rational follows that of IOMMU_SYS_CACHE_ONLY_NWA. Certain gpu usecases perform better when using a no-write allocate policy. Rename the IOMMU_SYS_CACHE_* flags to better reflect that they are not exclusive with IOMMU_CACHE. Bug: 191811876 Change-Id: Ic91616a148f39fead008a5b87a54ffd781fee734 Signed-off-by: Patrick Daly --- drivers/iommu/dma-iommu.c | 4 ++-- drivers/iommu/io-pgtable-arm.c | 38 ++++++++++++++++++++-------------- include/linux/iommu.h | 17 +++++++-------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 27f74c12bd02..7bbccb680c2b 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -434,9 +434,9 @@ static int dma_info_to_prot(enum dma_data_direction dir, bool coherent, if (attrs & DMA_ATTR_PRIVILEGED) prot |= IOMMU_PRIV; if (attrs & DMA_ATTR_SYS_CACHE_ONLY) - prot |= IOMMU_SYS_CACHE_ONLY; + prot |= IOMMU_SYS_CACHE; if (attrs & DMA_ATTR_SYS_CACHE_ONLY_NWA) - prot |= IOMMU_SYS_CACHE_ONLY_NWA; + prot |= IOMMU_SYS_CACHE_NWA; switch (dir) { case DMA_BIDIRECTIONAL: diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 0d7bb004e587..ec31966b4f6f 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -112,18 +112,20 @@ #define ARM_LPAE_VTCR_PS_SHIFT 16 #define ARM_LPAE_VTCR_PS_MASK 0x7 -#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3) -#define ARM_LPAE_MAIR_ATTR_MASK 0xff -#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04ULL -#define ARM_LPAE_MAIR_ATTR_NC 0x44ULL -#define ARM_LPAE_MAIR_ATTR_INC_OWBRANWA 0xe4ULL -#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA 0xf4ULL -#define ARM_LPAE_MAIR_ATTR_WBRWA 0xffULL -#define ARM_LPAE_MAIR_ATTR_IDX_NC 0 -#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1 -#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2 -#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE 3 -#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA 4 +#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3) +#define ARM_LPAE_MAIR_ATTR_MASK 0xff +#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04ULL +#define ARM_LPAE_MAIR_ATTR_NC 0x44ULL +#define ARM_LPAE_MAIR_ATTR_INC_OWBRANWA 0xe4ULL +#define ARM_LPAE_MAIR_ATTR_IWBRWA_OWBRANWA 0xefULL +#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA 0xf4ULL +#define ARM_LPAE_MAIR_ATTR_WBRWA 0xffULL +#define ARM_LPAE_MAIR_ATTR_IDX_NC 0 +#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1 +#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2 +#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE 3 +#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA 4 +#define ARM_LPAE_MAIR_ATTR_IDX_ICACHE_OCACHE_NWA 5 #define ARM_MALI_LPAE_TTBR_ADRMODE_TABLE (3u << 0) #define ARM_MALI_LPAE_TTBR_READ_INNER BIT(2) @@ -435,13 +437,17 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, if (prot & IOMMU_MMIO) pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV << ARM_LPAE_PTE_ATTRINDX_SHIFT); + else if ((prot & IOMMU_CACHE) && (prot & IOMMU_SYS_CACHE_NWA)) + pte |= (ARM_LPAE_MAIR_ATTR_IDX_ICACHE_OCACHE_NWA + << ARM_LPAE_PTE_ATTRINDX_SHIFT); + /* IOMMU_CACHE + IOMMU_SYS_CACHE equivalent to IOMMU_CACHE */ else if (prot & IOMMU_CACHE) pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE << ARM_LPAE_PTE_ATTRINDX_SHIFT); - else if (prot & IOMMU_SYS_CACHE_ONLY) + else if (prot & IOMMU_SYS_CACHE) pte |= (ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE << ARM_LPAE_PTE_ATTRINDX_SHIFT); - else if (prot & IOMMU_SYS_CACHE_ONLY_NWA) + else if (prot & IOMMU_SYS_CACHE_NWA) pte |= (ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA << ARM_LPAE_PTE_ATTRINDX_SHIFT); } @@ -904,7 +910,9 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) (ARM_LPAE_MAIR_ATTR_INC_OWBRWA << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE)) | (ARM_LPAE_MAIR_ATTR_INC_OWBRANWA - << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA)); + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA)) | + (ARM_LPAE_MAIR_ATTR_IWBRWA_OWBRANWA + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_ICACHE_OCACHE_NWA)); cfg->arm_lpae_s1_cfg.mair = reg; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 8417233a11a5..f7f6ada34836 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -32,18 +32,17 @@ */ #define IOMMU_PRIV (1 << 5) /* - * Non-coherent masters can use this page protection flag to set cacheable - * memory attributes for only a transparent outer level of cache, also known as - * the last-level or system cache. + * Allow caching in a transparent outer level of cache, also known as + * the last-level or system cache, with a read/write allocation policy. + * Does not depend on IOMMU_CACHE. Incompatible with IOMMU_SYS_CACHE_NWA. */ -#define IOMMU_SYS_CACHE_ONLY (1 << 6) +#define IOMMU_SYS_CACHE (1 << 6) /* - * Non-coherent masters can use this page protection flag to set cacheable - * memory attributes with a no write allocation cache policy for only a - * transparent outer level of cache, also known as the last-level or system - * cache. + * Allow caching in a transparent outer level of cache, also known as + * the last-level or system cache, with a read allocation policy. + * Does not depend on IOMMU_CACHE. Incompatible with IOMMU_SYS_CACHE. */ -#define IOMMU_SYS_CACHE_ONLY_NWA (1 << 7) +#define IOMMU_SYS_CACHE_NWA (1 << 7) struct iommu_ops; struct iommu_group; From de1a0ea81182525e905d2bb1924a42da51357571 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 29 Jun 2021 21:39:26 -0700 Subject: [PATCH 60/60] ANDROID: logbuf: Remove if directive for vendor hooks When CONFIG_TRACEPOINTS or CONFIG_ANDROID_VENDOR_HOOKS is not set, there is a build error after commit 01f2392e13db ("ANDROID: logbuf: Add new logbuf vendor hook to support pr_cont()"): kernel/printk/printk.c:1962:4: error: implicit declaration of function 'trace_android_vh_logbuf_pr_cont' [-Werror,-Wimplicit-function-declaration] trace_android_vh_logbuf_pr_cont(&r, text_len); ^ 1 error generated. Remove the #if directive so that this code always builds properly, which is possible after commit ba75b92fefa9 ("ANDROID: simplify vendor hooks for non-GKI builds"). Change-Id: Icc7f55af1becab5a8833b0651402845559b6b56f Fixes: 01f2392e13db ("ANDROID: logbuf: Add new logbuf vendor hook to support pr_cont()") Link: https://github.com/ClangBuiltLinux/continuous-integration2/runs/2948254099 Suggested-by: Todd Kjos Signed-off-by: Nathan Chancellor --- include/trace/hooks/logbuf.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/trace/hooks/logbuf.h b/include/trace/hooks/logbuf.h index 7af9122af8ad..f73ad597fc64 100644 --- a/include/trace/hooks/logbuf.h +++ b/include/trace/hooks/logbuf.h @@ -10,7 +10,6 @@ #include #include -#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS) struct printk_ringbuffer; struct printk_record; @@ -21,9 +20,6 @@ DECLARE_HOOK(android_vh_logbuf, DECLARE_HOOK(android_vh_logbuf_pr_cont, TP_PROTO(struct printk_record *r, size_t text_len), TP_ARGS(r, text_len)) -#else -#define trace_android_vh_logbuf(rb, r) -#endif #endif /* _TRACE_HOOK_LOGBUF_H */ /* This part must be outside protection */