Merge branch 'android14-6.1' into android14-6.1-lts

Catch the lts branch up with changes made in the normal one.  Commits
include in here are:

* a624f97c9a Merge tag 'android14-6.1.128_r00' into android14-6.1
* 52a41f0bf1 ANDROID: usb: typec: tcpci: Combine the parameters of set_auto_vbus_discharge_threshold
* f84d5a5fad FROMGIT: usb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR PPS
* a5f88b6529 UPSTREAM: f2fs: Optimize f2fs_truncate_data_blocks_range()
* 8171ecc314 BACKPORT: f2fs: add parameter @len to f2fs_invalidate_blocks()
* 2e7c1f7a45 UPSTREAM: f2fs: update_sit_entry_for_release() supports consecutive blocks.
* 80b35f89f0 BACKPORT: f2fs: introduce update_sit_entry_for_release/alloc()
* 600d7eac27 BACKPORT: f2fs: add parameter @len to f2fs_invalidate_internal_cache()
* 187a48cb98 UPSTREAM: f2fs: expand f2fs_invalidate_compress_page() to f2fs_invalidate_compress_pages_range()
* edcfc793f8 UPSTREAM: f2fs: fix to truncate meta inode pages forcely
* 3812bc69b2 BACKPORT: f2fs: introduce f2fs_invalidate_internal_cache() for cleanup
* ccc9157843 ANDROID: cma: Add restrict_cma_redirect boot parameter
* 34a86330cc FROMLIST: KVM: arm64: Fix alignment of kvm_hyp_memcache allocations
* c93dcf3b53 UPSTREAM: binder: log transaction code on failure
* 4e534b8a58 ANDROID: GKI: Galaxy android14-6.1 update symbol for alsa audio device
* 1ac09f5c05 ANDROID: GKI: Update symbol list for arg
* e5f309b277 ANDROID: dm-bow: Protect Ranges fetched and erased from the RB tree
* 09717ac61c ANDROID: Update the ABI symbol list
* 3031fa1817 ANDROID: Adding an Android vendor LMK event
* 7658169f5f BACKPORT: usb: xhci: Fix NULL pointer dereference on certain command aborts
* 4033df202b ANDROID: OPP: Fix incorrectly backported logic in _set_opp_level()
* 1cf6be7092 UPSTREAM: io_uring: fix waiters missing wake ups
* 2055772ead UPSTREAM: f2fs: avoid trying to get invalid block address
* 554eb9d61a ANDROID: KABI macros to release excess KABI fields for use with backports
* 773ad7ab13 ANDROID: GKI: Add new symbol list for arg

Change-Id: I71e368853a486e3893c0cc5b964b8fc3c390a4e9
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-02-22 10:42:06 +00:00
26 changed files with 3025 additions and 138 deletions

View File

@@ -99,6 +99,7 @@ filegroup(
name = "aarch64_additional_kmi_symbol_lists",
srcs = [
# keep sorted
"android/abi_gki_aarch64_arg",
"android/abi_gki_aarch64_asr",
"android/abi_gki_aarch64_asus",
"android/abi_gki_aarch64_bcmstb",

View File

@@ -314436,6 +314436,12 @@ function {
parameter_id: 0x4585663f
parameter_id: 0x1bf16028
}
function {
id: 0x915108e4
return_type_id: 0x6720d32f
parameter_id: 0x33f8b54b
parameter_id: 0x0bf1a65b
}
function {
id: 0x91523c59
return_type_id: 0x6720d32f
@@ -324321,6 +324327,13 @@ function {
parameter_id: 0x00c72527
parameter_id: 0xf435685e
}
function {
id: 0x9a1f3564
return_type_id: 0x6720d32f
parameter_id: 0x18bd6530
parameter_id: 0x6720d32f
parameter_id: 0xb0312d5a
}
function {
id: 0x9a20634b
return_type_id: 0x6720d32f
@@ -346769,6 +346782,15 @@ elf_symbol {
type_id: 0x9bdbdcc4
full_name: "__traceiter_android_rvh_wake_up_new_task"
}
elf_symbol {
id: 0xfd00ed2d
name: "__traceiter_android_trigger_vendor_lmk_kill"
is_defined: true
symbol_type: FUNCTION
crc: 0x867c2cff
type_id: 0x9a1f3564
full_name: "__traceiter_android_trigger_vendor_lmk_kill"
}
elf_symbol {
id: 0xa3af7947
name: "__traceiter_android_vh_account_process_tick_gran"
@@ -351782,6 +351804,15 @@ elf_symbol {
type_id: 0x18ccbd2c
full_name: "__tracepoint_android_rvh_wake_up_new_task"
}
elf_symbol {
id: 0xb59c7c3f
name: "__tracepoint_android_trigger_vendor_lmk_kill"
is_defined: true
symbol_type: OBJECT
crc: 0xb3afb377
type_id: 0x18ccbd2c
full_name: "__tracepoint_android_trigger_vendor_lmk_kill"
}
elf_symbol {
id: 0x4f980315
name: "__tracepoint_android_vh_account_process_tick_gran"
@@ -379633,6 +379664,33 @@ elf_symbol {
type_id: 0x16bab633
full_name: "iio_device_unregister"
}
elf_symbol {
id: 0xe5481ec8
name: "iio_enum_available_read"
is_defined: true
symbol_type: FUNCTION
crc: 0xcb388b01
type_id: 0x13641115
full_name: "iio_enum_available_read"
}
elf_symbol {
id: 0x2bfd6710
name: "iio_enum_read"
is_defined: true
symbol_type: FUNCTION
crc: 0x1972438f
type_id: 0x13641115
full_name: "iio_enum_read"
}
elf_symbol {
id: 0xbd0b946f
name: "iio_enum_write"
is_defined: true
symbol_type: FUNCTION
crc: 0xafda2d93
type_id: 0x1364c655
full_name: "iio_enum_write"
}
elf_symbol {
id: 0xef661661
name: "iio_format_value"
@@ -402467,6 +402525,15 @@ elf_symbol {
type_id: 0x91d0f233
full_name: "snd_ctl_remove"
}
elf_symbol {
id: 0x6095200b
name: "snd_ctl_remove_id"
is_defined: true
symbol_type: FUNCTION
crc: 0x8e2ca218
type_id: 0x915108e4
full_name: "snd_ctl_remove_id"
}
elf_symbol {
id: 0xe3942db0
name: "snd_device_free"
@@ -417752,6 +417819,7 @@ interface {
symbol_id: 0x915194c4
symbol_id: 0xdb6d278a
symbol_id: 0xebcd0234
symbol_id: 0xfd00ed2d
symbol_id: 0xa3af7947
symbol_id: 0x86527a4e
symbol_id: 0xf71b3e6c
@@ -418309,6 +418377,7 @@ interface {
symbol_id: 0xd1be5d26
symbol_id: 0xe1b78c30
symbol_id: 0xdcf22716
symbol_id: 0xb59c7c3f
symbol_id: 0x4f980315
symbol_id: 0xe1489e0c
symbol_id: 0x8f23a62a
@@ -421402,6 +421471,9 @@ interface {
symbol_id: 0x49e3dfdd
symbol_id: 0x7a6b0e4c
symbol_id: 0xe0909072
symbol_id: 0xe5481ec8
symbol_id: 0x2bfd6710
symbol_id: 0xbd0b946f
symbol_id: 0xef661661
symbol_id: 0x83815ff1
symbol_id: 0x01f28688
@@ -423939,6 +424011,7 @@ interface {
symbol_id: 0x6b08a95c
symbol_id: 0x238c5442
symbol_id: 0x20fc506b
symbol_id: 0x6095200b
symbol_id: 0xe3942db0
symbol_id: 0xb87d5cd6
symbol_id: 0x74d92df1

2565
android/abi_gki_aarch64_arg Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -289,6 +289,7 @@
smpboot_register_percpu_thread
smpboot_unregister_percpu_thread
snd_card_ref
snd_ctl_remove_id
snd_soc_add_card_controls
snd_soc_find_dai
snd_soc_info_volsw_sx

View File

@@ -2399,6 +2399,7 @@
__traceiter_android_rvh_util_fits_cpu
__traceiter_android_rvh_vmscan_kswapd_done
__traceiter_android_rvh_vmscan_kswapd_wake
__traceiter_android_trigger_vendor_lmk_kill
__traceiter_android_vh_arch_set_freq_scale
__traceiter_android_vh_audio_usb_offload_connect
__traceiter_android_vh_binder_proc_transaction_finish
@@ -2538,6 +2539,7 @@
__tracepoint_android_rvh_util_fits_cpu
__tracepoint_android_rvh_vmscan_kswapd_done
__tracepoint_android_rvh_vmscan_kswapd_wake
__tracepoint_android_trigger_vendor_lmk_kill
__tracepoint_android_vh_arch_set_freq_scale
__tracepoint_android_vh_audio_usb_offload_connect
__tracepoint_android_vh_binder_proc_transaction_finish

View File

@@ -91,7 +91,7 @@ static inline void push_hyp_memcache(struct kvm_hyp_memcache *mc,
static inline void *pop_hyp_memcache(struct kvm_hyp_memcache *mc,
void *(*to_va)(phys_addr_t phys))
{
phys_addr_t *p = to_va(mc->head);
phys_addr_t *p = to_va(mc->head & PAGE_MASK);
if (!mc->nr_pages)
return NULL;

View File

@@ -4023,13 +4023,13 @@ err_invalid_target_handle:
}
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
"%d:%d transaction %s to %d:%d failed %d/%d/%d, size %lld-%lld line %d\n",
"%d:%d transaction %s to %d:%d failed %d/%d/%d, code %u size %lld-%lld line %d\n",
proc->pid, thread->pid, reply ? "reply" :
(tr->flags & TF_ONE_WAY ? "async" : "call"),
target_proc ? target_proc->pid : 0,
target_thread ? target_thread->pid : 0,
t_debug_id, return_error, return_error_param,
(u64)tr->data_size, (u64)tr->offsets_size,
tr->code, (u64)tr->data_size, (u64)tr->offsets_size,
return_error_line);
if (target_thread)

View File

@@ -75,6 +75,7 @@
#include <trace/hooks/usb.h>
#include <trace/hooks/sound.h>
#include <trace/hooks/fuse.h>
#include <trace/events/android_vendor_lmk.h>
/*
* Export tracepoints that act as a bare tracehook (ie: have no trace event
@@ -470,3 +471,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_blk_reset);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_attach_sd);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sdhci_get_cd);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_gpio_cd_irqt);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_trigger_vendor_lmk_kill);

View File

@@ -612,6 +612,7 @@ static void dm_bow_dtr(struct dm_target *ti)
wait_for_completion(dm_get_completion_from_kobject(kobj));
}
mutex_lock(&bc->ranges_lock);
while (rb_first(&bc->ranges)) {
struct bow_range *br = container_of(rb_first(&bc->ranges),
struct bow_range, node);
@@ -619,6 +620,7 @@ static void dm_bow_dtr(struct dm_target *ti)
rb_erase(&br->node, &bc->ranges);
kfree(br);
}
mutex_unlock(&bc->ranges_lock);
mutex_destroy(&bc->ranges_lock);
kfree(bc->log_sector);
@@ -1191,6 +1193,7 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result,
return;
}
mutex_lock(&bc->ranges_lock);
for (i = rb_first(&bc->ranges); i; i = rb_next(i)) {
struct bow_range *br = container_of(i, struct bow_range, node);
@@ -1198,11 +1201,11 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result,
readable_type[br->type],
(unsigned long long)br->sector);
if (result >= end)
return;
goto unlock;
result += scnprintf(result, end - result, "\n");
if (result >= end)
return;
goto unlock;
if (br->type == TRIMMED)
++trimmed_range_count;
@@ -1224,19 +1227,22 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result,
if (!rb_next(i)) {
scnprintf(result, end - result,
"\nERROR: Last range not of type TOP");
return;
goto unlock;
}
if (br->sector > range_top(br)) {
scnprintf(result, end - result,
"\nERROR: sectors out of order");
return;
goto unlock;
}
}
if (trimmed_range_count != trimmed_list_length)
scnprintf(result, end - result,
"\nERROR: not all trimmed ranges in trimmed list");
unlock:
mutex_unlock(&bc->ranges_lock);
}
static void dm_bow_status(struct dm_target *ti, status_type_t type,

View File

@@ -1024,11 +1024,18 @@ static int _set_opp_level(struct device *dev, struct opp_table *opp_table,
level = opp->level;
}
/* Request a new performance state through the device's PM domain. */
ret = dev_pm_genpd_set_performance_state(dev, level);
if (ret)
dev_err(dev, "Failed to set performance state %u (%d)\n", level,
ret);
/*
* This function should be a nop for devices without a PM domain. However,
* dev_pm_genpd_set_performance_state() returns an error for devices without a PM domain
* instead of returning immediately.
*/
if (dev->pm_domain) {
/* Request a new performance state through the device's PM domain. */
ret = dev_pm_genpd_set_performance_state(dev, level);
if (ret)
dev_err(dev, "Failed to set performance state %u (%d)\n", level,
ret);
}
return ret;
}

View File

@@ -380,7 +380,8 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) &&
!(xhci->xhc_state & XHCI_STATE_DYING)) {
xhci->current_cmd = cur_cmd;
xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
if (cur_cmd)
xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
xhci_ring_cmd_db(xhci);
}
}

View File

@@ -27,6 +27,7 @@
#define VPPS_NEW_MIN_PERCENT 95
#define VPPS_VALID_MIN_MV 100
#define VSINKDISCONNECT_PD_MIN_PERCENT 90
#define VPPS_SHUTDOWN_MIN_PERCENT 85
struct tcpci {
struct device *dev;
@@ -362,9 +363,12 @@ static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum ty
threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV;
} else if (mode == TYPEC_PWR_MODE_PD) {
if (pps_active)
threshold = ((VPPS_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) -
VSINKPD_MIN_IR_DROP_MV - VPPS_VALID_MIN_MV) *
VSINKDISCONNECT_PD_MIN_PERCENT / 100;
/*
* To prevent disconnect when the source is in Current Limit Mode.
* Set the threshold to the lowest possible voltage vPpsShutdown (min)
*/
threshold = VPPS_SHUTDOWN_MIN_PERCENT * requested_vbus_voltage_mv / 100 -
VSINKPD_MIN_IR_DROP_MV;
else
threshold = ((VSRC_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) -
VSINKPD_MIN_IR_DROP_MV - VSRC_VALID_MIN_MV) *

View File

@@ -2342,16 +2342,22 @@ static int tcpm_set_auto_vbus_discharge_threshold(struct tcpm_port *port,
enum typec_pwr_opmode mode, bool pps_active,
u32 requested_vbus_voltage)
{
u32 voltage;
int ret;
if (!port->tcpc->set_auto_vbus_discharge_threshold)
return 0;
ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, mode, pps_active,
requested_vbus_voltage);
if (mode == TYPEC_PWR_MODE_PD && pps_active)
voltage = port->pps_data.min_volt;
else
voltage = requested_vbus_voltage;
ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, mode, pps_active, voltage);
tcpm_log_force(port,
"set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u ret:%d",
mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ret);
"set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u pps_apdo_min_volt:%u ret:%d",
mode, pps_active ? 'y' : 'n', requested_vbus_voltage,
port->pps_data.min_volt, ret);
return ret;
}

View File

@@ -1598,8 +1598,9 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
*/
if (f2fs_sb_has_encrypt(sbi) || f2fs_sb_has_verity(sbi) ||
f2fs_sb_has_compression(sbi))
invalidate_mapping_pages(META_MAPPING(sbi),
MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1);
f2fs_bug_on(sbi,
invalidate_inode_pages2_range(META_MAPPING(sbi),
MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1));
f2fs_release_ino_entry(sbi, false);

View File

@@ -1381,7 +1381,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
if (blkaddr == COMPRESS_ADDR)
fio.compr_blocks++;
if (__is_valid_data_blkaddr(blkaddr))
f2fs_invalidate_blocks(sbi, blkaddr);
f2fs_invalidate_blocks(sbi, blkaddr, 1);
f2fs_update_data_blkaddr(&dn, COMPRESS_ADDR);
goto unlock_continue;
}
@@ -1391,7 +1391,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
if (i > cc->valid_nr_cpages) {
if (__is_valid_data_blkaddr(blkaddr)) {
f2fs_invalidate_blocks(sbi, blkaddr);
f2fs_invalidate_blocks(sbi, blkaddr, 1);
f2fs_update_data_blkaddr(&dn, NEW_ADDR);
}
goto unlock_continue;
@@ -1916,11 +1916,12 @@ 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)
void f2fs_invalidate_compress_pages_range(struct f2fs_sb_info *sbi,
block_t blkaddr, unsigned int len)
{
if (!sbi->compress_inode)
return;
invalidate_mapping_pages(COMPRESS_MAPPING(sbi), blkaddr, blkaddr);
invalidate_mapping_pages(COMPRESS_MAPPING(sbi), blkaddr, blkaddr + len - 1);
}
void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page,

View File

@@ -1490,11 +1490,8 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
if (err)
return err;
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 (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
f2fs_invalidate_internal_cache(sbi, old_blkaddr, 1);
f2fs_update_data_blkaddr(dn, dn->data_blkaddr);
return 0;

View File

@@ -3635,7 +3635,8 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino);
int f2fs_create_flush_cmd_control(struct f2fs_sb_info *sbi);
int f2fs_flush_device_cache(struct f2fs_sb_info *sbi);
void f2fs_destroy_flush_cmd_control(struct f2fs_sb_info *sbi, bool free);
void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr,
unsigned int len);
bool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
int f2fs_start_discard_thread(struct f2fs_sb_info *sbi);
void f2fs_drop_discard_cmd(struct f2fs_sb_info *sbi);
@@ -4287,7 +4288,8 @@ 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_invalidate_compress_pages_range(struct f2fs_sb_info *sbi,
block_t blkaddr, unsigned int len);
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,
@@ -4342,8 +4344,8 @@ static inline int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { return
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_invalidate_compress_pages_range(struct f2fs_sb_info *sbi,
block_t blkaddr, unsigned int len) { }
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,
@@ -4606,6 +4608,39 @@ static inline bool f2fs_is_readonly(struct f2fs_sb_info *sbi)
return f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb);
}
static inline void f2fs_truncate_meta_inode_pages(struct f2fs_sb_info *sbi,
block_t blkaddr, unsigned int cnt)
{
bool need_submit = false;
int i = 0;
do {
struct page *page;
page = find_get_page(META_MAPPING(sbi), blkaddr + i);
if (page) {
if (PageWriteback(page))
need_submit = true;
f2fs_put_page(page, 0);
}
} while (++i < cnt && !need_submit);
if (need_submit)
f2fs_submit_merged_write_cond(sbi, sbi->meta_inode,
NULL, 0, DATA);
truncate_inode_pages_range(META_MAPPING(sbi),
F2FS_BLK_TO_BYTES((loff_t)blkaddr),
F2FS_BLK_END_BYTES((loff_t)(blkaddr + cnt - 1)));
}
static inline void f2fs_invalidate_internal_cache(struct f2fs_sb_info *sbi,
block_t blkaddr, unsigned int len)
{
f2fs_truncate_meta_inode_pages(sbi, blkaddr, len);
f2fs_invalidate_compress_pages_range(sbi, blkaddr, len);
}
#define EFSBADCRC EBADMSG /* Bad CRC detected */
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */

View File

@@ -621,8 +621,11 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
int cluster_index = 0, valid_blocks = 0;
int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
bool released = !atomic_read(&F2FS_I(dn->inode)->i_compr_blocks);
block_t blkstart;
int blklen = 0;
addr = get_dnode_addr(dn->inode, dn->node_page) + ofs;
blkstart = le32_to_cpu(*addr);
/* Assumption: truncation starts with cluster */
for (; count > 0; count--, addr++, dn->ofs_in_node++, cluster_index++) {
@@ -638,28 +641,46 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
}
if (blkaddr == NULL_ADDR)
continue;
goto next;
f2fs_set_data_blkaddr(dn, NULL_ADDR);
if (__is_valid_data_blkaddr(blkaddr)) {
if (time_to_inject(sbi, FAULT_BLKADDR_CONSISTENCE))
continue;
goto next;
if (!f2fs_is_valid_blkaddr_raw(sbi, blkaddr,
DATA_GENERIC_ENHANCE)) {
f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
continue;
goto next;
}
if (compressed_cluster)
valid_blocks++;
}
f2fs_invalidate_blocks(sbi, blkaddr);
if (blkstart + blklen == blkaddr) {
blklen++;
} else {
f2fs_invalidate_blocks(sbi, blkstart, blklen);
blkstart = blkaddr;
blklen = 1;
}
if (!released || blkaddr != COMPRESS_ADDR)
nr_free++;
continue;
next:
if (blklen)
f2fs_invalidate_blocks(sbi, blkstart, blklen);
blkstart = le32_to_cpu(*(addr + 1));
blklen = 0;
}
if (blklen)
f2fs_invalidate_blocks(sbi, blkstart, blklen);
if (compressed_cluster)
f2fs_i_compr_blocks_update(dn->inode, valid_blocks, false);
@@ -1300,7 +1321,7 @@ static int __roll_back_blkaddrs(struct inode *inode, block_t *blkaddr,
ret = f2fs_get_dnode_of_data(&dn, off + i, LOOKUP_NODE_RA);
if (ret) {
dec_valid_block_count(sbi, inode, 1);
f2fs_invalidate_blocks(sbi, *blkaddr);
f2fs_invalidate_blocks(sbi, *blkaddr, 1);
} else {
f2fs_update_data_blkaddr(&dn, *blkaddr);
}
@@ -1549,7 +1570,7 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start,
break;
}
f2fs_invalidate_blocks(sbi, dn->data_blkaddr);
f2fs_invalidate_blocks(sbi, dn->data_blkaddr, 1);
f2fs_set_data_blkaddr(dn, NEW_ADDR);
}

View File

@@ -1389,9 +1389,8 @@ static int move_data_block(struct inode *inode, block_t bidx,
memcpy(page_address(fio.encrypted_page),
page_address(mpage), PAGE_SIZE);
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);
f2fs_invalidate_internal_cache(fio.sbi, fio.old_blkaddr, 1);
set_page_dirty(fio.encrypted_page);
if (clear_page_dirty_for_io(fio.encrypted_page))

View File

@@ -325,6 +325,7 @@ fail_drop:
trace_f2fs_new_inode(inode, err);
dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
make_bad_inode(inode);
if (nid_free)
set_inode_flag(inode, FI_FREE_NID);
clear_nlink(inode);

View File

@@ -906,7 +906,7 @@ static int truncate_node(struct dnode_of_data *dn)
return err;
/* Deallocate node address */
f2fs_invalidate_blocks(sbi, ni.blk_addr);
f2fs_invalidate_blocks(sbi, ni.blk_addr, 1);
dec_valid_node_count(sbi, dn->inode, dn->nid == dn->inode->i_ino);
set_node_addr(sbi, &ni, NULL_ADDR, false);
@@ -2723,7 +2723,7 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
if (err)
return err;
f2fs_invalidate_blocks(sbi, ni.blk_addr);
f2fs_invalidate_blocks(sbi, ni.blk_addr, 1);
dec_valid_node_count(sbi, inode, false);
set_node_addr(sbi, &ni, NULL_ADDR, false);

View File

@@ -245,7 +245,7 @@ retry:
if (!__is_valid_data_blkaddr(new_addr)) {
if (new_addr == NULL_ADDR)
dec_valid_block_count(sbi, inode, 1);
f2fs_invalidate_blocks(sbi, dn.data_blkaddr);
f2fs_invalidate_blocks(sbi, dn.data_blkaddr, 1);
f2fs_update_data_blkaddr(&dn, new_addr);
} else {
f2fs_replace_block(sbi, &dn, dn.data_blkaddr,
@@ -2304,15 +2304,117 @@ static void update_segment_mtime(struct f2fs_sb_info *sbi, block_t blkaddr,
SIT_I(sbi)->max_mtime = ctime;
}
/*
* NOTE: when updating multiple blocks at the same time, please ensure
* that the consecutive input blocks belong to the same segment.
*/
static int update_sit_entry_for_release(struct f2fs_sb_info *sbi, struct seg_entry *se,
block_t blkaddr, unsigned int offset, int del)
{
bool exist;
#ifdef CONFIG_F2FS_CHECK_FS
bool mir_exist;
#endif
int i;
int del_count = -del;
f2fs_bug_on(sbi, GET_SEGNO(sbi, blkaddr) != GET_SEGNO(sbi, blkaddr + del_count - 1));
for (i = 0; i < del_count; i++) {
exist = f2fs_test_and_clear_bit(offset + i, se->cur_valid_map);
#ifdef CONFIG_F2FS_CHECK_FS
mir_exist = f2fs_test_and_clear_bit(offset + i,
se->cur_valid_map_mir);
if (unlikely(exist != mir_exist)) {
f2fs_err(sbi, "Inconsistent error when clearing bitmap, blk:%u, old bit:%d",
blkaddr + i, exist);
f2fs_bug_on(sbi, 1);
}
#endif
if (unlikely(!exist)) {
f2fs_err(sbi, "Bitmap was wrongly cleared, blk:%u", blkaddr + i);
f2fs_bug_on(sbi, 1);
se->valid_blocks++;
del += 1;
} else if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
/*
* If checkpoints are off, we must not reuse data that
* was used in the previous checkpoint. If it was used
* before, we must track that to know how much space we
* really have.
*/
if (f2fs_test_bit(offset + i, se->ckpt_valid_map)) {
spin_lock(&sbi->stat_lock);
sbi->unusable_block_count++;
spin_unlock(&sbi->stat_lock);
}
}
if (f2fs_block_unit_discard(sbi) &&
f2fs_test_and_clear_bit(offset + i, se->discard_map))
sbi->discard_blks++;
if (!f2fs_test_bit(offset + i, se->ckpt_valid_map))
se->ckpt_valid_blocks -= 1;
}
return del;
}
static int update_sit_entry_for_alloc(struct f2fs_sb_info *sbi, struct seg_entry *se,
block_t blkaddr, unsigned int offset, int del)
{
bool exist;
#ifdef CONFIG_F2FS_CHECK_FS
bool mir_exist;
#endif
exist = f2fs_test_and_set_bit(offset, se->cur_valid_map);
#ifdef CONFIG_F2FS_CHECK_FS
mir_exist = f2fs_test_and_set_bit(offset,
se->cur_valid_map_mir);
if (unlikely(exist != mir_exist)) {
f2fs_err(sbi, "Inconsistent error when setting bitmap, blk:%u, old bit:%d",
blkaddr, exist);
f2fs_bug_on(sbi, 1);
}
#endif
if (unlikely(exist)) {
f2fs_err(sbi, "Bitmap was wrongly set, blk:%u", blkaddr);
f2fs_bug_on(sbi, 1);
se->valid_blocks--;
del = 0;
}
if (f2fs_block_unit_discard(sbi) &&
!f2fs_test_and_set_bit(offset, se->discard_map))
sbi->discard_blks--;
/*
* SSR should never reuse block which is checkpointed
* or newly invalidated.
*/
if (!is_sbi_flag_set(sbi, SBI_CP_DISABLED)) {
if (!f2fs_test_and_set_bit(offset, se->ckpt_valid_map))
se->ckpt_valid_blocks++;
}
if (!f2fs_test_bit(offset, se->ckpt_valid_map))
se->ckpt_valid_blocks += del;
return del;
}
/*
* If releasing blocks, this function supports updating multiple consecutive blocks
* at one time, but please note that these consecutive blocks need to belong to the
* same segment.
*/
static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
{
struct seg_entry *se;
unsigned int segno, offset;
long int new_vblocks;
bool exist;
#ifdef CONFIG_F2FS_CHECK_FS
bool mir_exist;
#endif
segno = GET_SEGNO(sbi, blkaddr);
if (segno == NULL_SEGNO)
@@ -2329,73 +2431,10 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
/* Update valid block bitmap */
if (del > 0) {
exist = f2fs_test_and_set_bit(offset, se->cur_valid_map);
#ifdef CONFIG_F2FS_CHECK_FS
mir_exist = f2fs_test_and_set_bit(offset,
se->cur_valid_map_mir);
if (unlikely(exist != mir_exist)) {
f2fs_err(sbi, "Inconsistent error when setting bitmap, blk:%u, old bit:%d",
blkaddr, exist);
f2fs_bug_on(sbi, 1);
}
#endif
if (unlikely(exist)) {
f2fs_err(sbi, "Bitmap was wrongly set, blk:%u",
blkaddr);
f2fs_bug_on(sbi, 1);
se->valid_blocks--;
del = 0;
}
if (f2fs_block_unit_discard(sbi) &&
!f2fs_test_and_set_bit(offset, se->discard_map))
sbi->discard_blks--;
/*
* SSR should never reuse block which is checkpointed
* or newly invalidated.
*/
if (!is_sbi_flag_set(sbi, SBI_CP_DISABLED)) {
if (!f2fs_test_and_set_bit(offset, se->ckpt_valid_map))
se->ckpt_valid_blocks++;
}
del = update_sit_entry_for_alloc(sbi, se, blkaddr, offset, del);
} else {
exist = f2fs_test_and_clear_bit(offset, se->cur_valid_map);
#ifdef CONFIG_F2FS_CHECK_FS
mir_exist = f2fs_test_and_clear_bit(offset,
se->cur_valid_map_mir);
if (unlikely(exist != mir_exist)) {
f2fs_err(sbi, "Inconsistent error when clearing bitmap, blk:%u, old bit:%d",
blkaddr, exist);
f2fs_bug_on(sbi, 1);
}
#endif
if (unlikely(!exist)) {
f2fs_err(sbi, "Bitmap was wrongly cleared, blk:%u",
blkaddr);
f2fs_bug_on(sbi, 1);
se->valid_blocks++;
del = 0;
} else if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
/*
* If checkpoints are off, we must not reuse data that
* was used in the previous checkpoint. If it was used
* before, we must track that to know how much space we
* really have.
*/
if (f2fs_test_bit(offset, se->ckpt_valid_map)) {
spin_lock(&sbi->stat_lock);
sbi->unusable_block_count++;
spin_unlock(&sbi->stat_lock);
}
}
if (f2fs_block_unit_discard(sbi) &&
f2fs_test_and_clear_bit(offset, se->discard_map))
sbi->discard_blks++;
del = update_sit_entry_for_release(sbi, se, blkaddr, offset, del);
}
if (!f2fs_test_bit(offset, se->ckpt_valid_map))
se->ckpt_valid_blocks += del;
__mark_sit_entry_dirty(sbi, segno);
@@ -2406,26 +2445,43 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
get_sec_entry(sbi, segno)->valid_blocks += del;
}
void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr,
unsigned int len)
{
unsigned int segno = GET_SEGNO(sbi, addr);
struct sit_info *sit_i = SIT_I(sbi);
block_t addr_start = addr, addr_end = addr + len - 1;
unsigned int seg_num = GET_SEGNO(sbi, addr_end) - segno + 1;
unsigned int i = 1, max_blocks = sbi->blocks_per_seg, cnt;
f2fs_bug_on(sbi, addr == NULL_ADDR);
if (addr == NEW_ADDR || addr == COMPRESS_ADDR)
return;
invalidate_mapping_pages(META_MAPPING(sbi), addr, addr);
f2fs_invalidate_compress_page(sbi, addr);
f2fs_invalidate_internal_cache(sbi, addr, len);
/* add it into sit main buffer */
down_write(&sit_i->sentry_lock);
update_segment_mtime(sbi, addr, 0);
update_sit_entry(sbi, addr, -1);
if (seg_num == 1)
cnt = len;
else
cnt = max_blocks - GET_BLKOFF_FROM_SEG0(sbi, addr);
/* add it into dirty seglist */
locate_dirty_segment(sbi, segno);
do {
update_segment_mtime(sbi, addr_start, 0);
update_sit_entry(sbi, addr_start, -cnt);
/* add it into dirty seglist */
locate_dirty_segment(sbi, segno);
/* update @addr_start and @cnt and @segno */
addr_start = START_BLOCK(sbi, ++segno);
if (++i == seg_num)
cnt = GET_BLKOFF_FROM_SEG0(sbi, addr_end) + 1;
else
cnt = max_blocks;
} while (i <= seg_num);
up_write(&sit_i->sentry_lock);
}
@@ -3478,11 +3534,8 @@ reallocate:
goto out;
}
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);
}
if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO)
f2fs_invalidate_internal_cache(fio->sbi, fio->old_blkaddr, 1);
/* writeout dirty page into bdev */
f2fs_submit_page_write(fio);
@@ -3576,8 +3629,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
}
if (fio->meta_gc)
invalidate_mapping_pages(META_MAPPING(sbi),
fio->new_blkaddr, fio->new_blkaddr);
f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1);
stat_inc_inplace_blocks(fio->sbi);
@@ -3678,9 +3730,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
update_sit_entry(sbi, new_blkaddr, 1);
}
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_invalidate_internal_cache(sbi, old_blkaddr, 1);
if (!from_gc)
update_segment_mtime(sbi, old_blkaddr, 0);
update_sit_entry(sbi, old_blkaddr, -1);
@@ -3769,7 +3819,7 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
for (i = 0; i < len; i++)
f2fs_wait_on_block_writeback(inode, blkaddr + i);
invalidate_mapping_pages(META_MAPPING(sbi), blkaddr, blkaddr + len - 1);
f2fs_truncate_meta_inode_pages(sbi, blkaddr, len);
}
static int read_compacted_summaries(struct f2fs_sb_info *sbi)

View File

@@ -90,6 +90,14 @@
#define ANDROID_KABI_RESERVE(number)
#endif
/*
* ANDROID_KABI_BACKPORT_OK
* Used to allow padding originally reserved with ANDROID_KABI_RESERVE
* to be used for backports of non-LTS patches by partners. These
* fields can by used by replacing with ANDROID_KABI_BACKPORT_USE()
* for partner backports.
*/
#define ANDROID_KABI_BACKPORT_OK(number) ANDROID_KABI_RESERVE(number)
/*
* Macros to use _after_ the ABI is frozen
@@ -104,6 +112,17 @@
#define ANDROID_KABI_USE(number, _new) \
_ANDROID_KABI_REPLACE(_ANDROID_KABI_RESERVE(number), _new)
/*
* ANDROID_KABI_BACKPORT_USE(number, _new)
* Use a previous padding entry that was defined with
* ANDROID_KABI_BACKPORT_OK(). This is functionally identical
* to ANDROID_KABI_USE() except that it differentiates the
* normal use of KABI fields for LTS from KABI fields that
* were released for use with other backports from upstream.
*/
#define ANDROID_KABI_BACKPORT_USE(number, _new) \
ANDROID_KABI_USE(number, _new)
/*
* ANDROID_KABI_USE2(number, _new1, _new2)
* Use a previous padding entry that was defined with ANDROID_KABI_RESERVE for

View File

@@ -27,6 +27,7 @@
#define F2FS_BYTES_TO_BLK(bytes) ((bytes) >> F2FS_BLKSIZE_BITS)
#define F2FS_BLK_TO_BYTES(blk) ((blk) << F2FS_BLKSIZE_BITS)
#define F2FS_BLK_END_BYTES(blk) (F2FS_BLK_TO_BYTES(blk + 1) - 1)
/* 0, 1(node nid), 2(meta nid) are reserved node id */
#define F2FS_RESERVED_NODE_NUM 3

View File

@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2025 Google, Inc.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM android_vendor_lmk
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH trace/events
#if !defined(_ANDROID_VENDOR_LMK_H) || defined(TRACE_HEADER_MULTI_READ)
#define _ANDROID_VENDOR_LMK_H
#include <linux/tracepoint.h>
TRACE_EVENT(android_trigger_vendor_lmk_kill,
TP_PROTO(int reason, short min_oom_score_adj),
TP_ARGS(reason, min_oom_score_adj),
TP_STRUCT__entry(
__field(int, reason)
__field(short, min_oom_score_adj)
),
TP_fast_assign(
__entry->reason = reason;
__entry->min_oom_score_adj = min_oom_score_adj;
),
TP_printk("reason=%u min_oom_score_adj=%hd", __entry->reason, __entry->min_oom_score_adj)
);
#endif /* _ANDROID_VENDOR_LMK_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@@ -211,6 +211,38 @@ EXPORT_PER_CPU_SYMBOL(numa_node);
DEFINE_STATIC_KEY_TRUE(vm_numa_stat_key);
/*
* By default, restrict_cma_redirect is set to true, so only MOVABLE allocations
* marked __GFP_CMA are eligible to be redirected to CMA region. These allocations
* are redirected if *any* free space is available in the CMA region.
* When restrict_cma_redirect is false, all movable allocations
* are eligible for redirection to CMA region (i.e movable allocations are
* not restricted from CMA region), when there is sufficient space there.
* (see __rmqueue()).
*
*/
DEFINE_STATIC_KEY_TRUE(restrict_cma_redirect);
static int __init restrict_cma_redirect_setup(char *str)
{
#ifdef CONFIG_CMA
bool res;
int ret;
ret = kstrtobool(str, &res);
if (!ret && res == false)
static_branch_disable(&restrict_cma_redirect);
#else
pr_warn("CONFIG_CMA not set. Ignoring restrict_cma_redirect option\n");
#endif
return 1;
}
__setup("restrict_cma_redirect=", restrict_cma_redirect_setup);
static inline bool cma_redirect_restricted(void)
{
return static_branch_likely(&restrict_cma_redirect);
}
#ifdef CONFIG_HAVE_MEMORYLESS_NODES
/*
* N.B., Do NOT reference the '_numa_mem_' per cpu variable directly.
@@ -3177,6 +3209,21 @@ __rmqueue(struct zone *zone, unsigned int order, int migratetype,
if (page)
return page;
if (IS_ENABLED(CONFIG_CMA)) {
/*
* Balance movable allocations between regular and CMA areas by
* allocating from CMA when over half of the zone's free memory
* is in the CMA area.
*/
if (!cma_redirect_restricted() && alloc_flags & ALLOC_CMA &&
zone_page_state(zone, NR_FREE_CMA_PAGES) >
zone_page_state(zone, NR_FREE_PAGES) / 2) {
page = __rmqueue_cma_fallback(zone, order);
if (page)
return page;
}
}
retry:
page = __rmqueue_smallest(zone, order, migratetype);
@@ -3186,6 +3233,9 @@ retry:
if (unlikely(!page) && (migratetype == MIGRATE_MOVABLE))
trace_android_vh_rmqueue_cma_fallback(zone, order, &page);
if (!cma_redirect_restricted() && !page && alloc_flags & ALLOC_CMA)
page = __rmqueue_cma_fallback(zone, order);
if (unlikely(!page) && __rmqueue_fallback(zone, order, migratetype,
alloc_flags))
goto retry;
@@ -3231,7 +3281,12 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
for (i = 0; i < count; ++i) {
struct page *page;
if (is_migrate_cma(migratetype))
/*
* If CMA redirect is restricted, use CMA region only for
* MIGRATE_CMA pages. cma_rediret_restricted() is false
* if CONFIG_CMA is not set.
*/
if (cma_redirect_restricted() && is_migrate_cma(migratetype))
page = __rmqueue_cma(zone, order, migratetype,
alloc_flags);
else
@@ -3880,7 +3935,8 @@ struct page *rmqueue_buddy(struct zone *preferred_zone, struct zone *zone,
if (alloc_flags & ALLOC_HIGHATOMIC)
page = __rmqueue_smallest(zone, order, MIGRATE_HIGHATOMIC);
if (!page) {
if (alloc_flags & ALLOC_CMA && migratetype == MIGRATE_MOVABLE)
if (cma_redirect_restricted() && alloc_flags & ALLOC_CMA &&
migratetype == MIGRATE_MOVABLE)
page = __rmqueue_cma(zone, order, migratetype,
alloc_flags);
else
@@ -3924,7 +3980,8 @@ struct page *__rmqueue_pcplist(struct zone *zone, unsigned int order,
do {
/* First try to get CMA pages */
if (migratetype == MIGRATE_MOVABLE && alloc_flags & ALLOC_CMA)
if (cma_redirect_restricted() && migratetype == MIGRATE_MOVABLE &&
alloc_flags & ALLOC_CMA)
list = get_populated_pcp_list(zone, order, pcp, get_cma_migrate_type(),
alloc_flags);
if (list == NULL) {
@@ -4344,7 +4401,12 @@ static inline unsigned int gfp_to_alloc_flags_cma(gfp_t gfp_mask,
unsigned int alloc_flags)
{
#ifdef CONFIG_CMA
if (gfp_migratetype(gfp_mask) == MIGRATE_MOVABLE && gfp_mask & __GFP_CMA)
/*
* If cma_redirect_restricted is true, set ALLOC_CMA only for
* movable allocations that have __GFP_CMA.
*/
if ((!cma_redirect_restricted() || gfp_mask & __GFP_CMA) &&
gfp_migratetype(gfp_mask) == MIGRATE_MOVABLE)
alloc_flags |= ALLOC_CMA;
trace_android_vh_alloc_flags_cma_adjust(gfp_mask, &alloc_flags);
#endif