mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
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: *a624f97c9aMerge tag 'android14-6.1.128_r00' into android14-6.1 *52a41f0bf1ANDROID: usb: typec: tcpci: Combine the parameters of set_auto_vbus_discharge_threshold *f84d5a5fadFROMGIT: usb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR PPS *a5f88b6529UPSTREAM: f2fs: Optimize f2fs_truncate_data_blocks_range() *8171ecc314BACKPORT: f2fs: add parameter @len to f2fs_invalidate_blocks() *2e7c1f7a45UPSTREAM: f2fs: update_sit_entry_for_release() supports consecutive blocks. *80b35f89f0BACKPORT: f2fs: introduce update_sit_entry_for_release/alloc() *600d7eac27BACKPORT: f2fs: add parameter @len to f2fs_invalidate_internal_cache() *187a48cb98UPSTREAM: f2fs: expand f2fs_invalidate_compress_page() to f2fs_invalidate_compress_pages_range() *edcfc793f8UPSTREAM: f2fs: fix to truncate meta inode pages forcely *3812bc69b2BACKPORT: f2fs: introduce f2fs_invalidate_internal_cache() for cleanup *ccc9157843ANDROID: cma: Add restrict_cma_redirect boot parameter *34a86330ccFROMLIST: KVM: arm64: Fix alignment of kvm_hyp_memcache allocations *c93dcf3b53UPSTREAM: binder: log transaction code on failure *4e534b8a58ANDROID: GKI: Galaxy android14-6.1 update symbol for alsa audio device *1ac09f5c05ANDROID: GKI: Update symbol list for arg *e5f309b277ANDROID: dm-bow: Protect Ranges fetched and erased from the RB tree *09717ac61cANDROID: Update the ABI symbol list *3031fa1817ANDROID: Adding an Android vendor LMK event *7658169f5fBACKPORT: usb: xhci: Fix NULL pointer dereference on certain command aborts *4033df202bANDROID: OPP: Fix incorrectly backported logic in _set_opp_level() *1cf6be7092UPSTREAM: io_uring: fix waiters missing wake ups *2055772eadUPSTREAM: f2fs: avoid trying to get invalid block address *554eb9d61aANDROID: KABI macros to release excess KABI fields for use with backports *773ad7ab13ANDROID: GKI: Add new symbol list for arg Change-Id: I71e368853a486e3893c0cc5b964b8fc3c390a4e9 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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
2565
android/abi_gki_aarch64_arg
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) *
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
32
include/trace/events/android_vendor_lmk.h
Normal file
32
include/trace/events/android_vendor_lmk.h
Normal 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>
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user