Merge branch 'android12-5.10' into branch 'android12-5.10-lts'
Sync up with android12-5.10 for the following commits:af699fd6a2
ANDROID: vendor_hook: skip trace_android_vh_page_trylock_set when ignore_references is true5aec776ef8
BACKPORT: ANDROID: dma-buf: Move sysfs work out of DMA-BUF export pathd61d7ebf6f
UPSTREAM: wifi: mac80211: fix MBSSID parsing use-after-free173913b365
UPSTREAM: wifi: mac80211: don't parse mbssid in assoc response9ed9ab8ca9
UPSTREAM: mac80211: mlme: find auth challenge directlyd6e68e31b8
UPSTREAM: wifi: cfg80211: update hidden BSSes to avoid WARN_ON3ea906ba30
UPSTREAM: wifi: mac80211: fix crash in beacon protection for P2P-device241426b24b
UPSTREAM: wifi: mac80211_hwsim: avoid mac80211 warning on bad rate50e27143a5
UPSTREAM: wifi: cfg80211: avoid nontransmitted BSS list corruption05a0122295
UPSTREAM: wifi: cfg80211: fix BSS refcounting bugs2e8c292e35
UPSTREAM: wifi: cfg80211: ensure length byte is present before access5f6b14356a
UPSTREAM: wifi: cfg80211/mac80211: reject bad MBSSID elements6aeb3ccf09
UPSTREAM: wifi: cfg80211: fix u8 overflow in cfg80211_update_notlisted_nontrans()13a84bfa4f
ANDROID: GKI: Update symbols to symbol list09f4246296
ANDROID: sched: add restricted hooks to replace the former hooks376aaf803f
ANDROID: GKI: Add symbol snd_pcm_stop_xrun8512c353a2
ANDROID: ABI: update allowed list for galaxy439fc06787
ANDROID: GKI: Update symbols to symbol listbeaaa7bff8
UPSTREAM: dma-buf: ensure unique directory name for dmabuf statsd71115b1bf
UPSTREAM: dma-buf: call dma_buf_stats_setup after dmabuf is in valid listf9a66cbe70
ANDROID: GKI: Update symbol list for mtk AIoT projectsa3835ce695
UPSTREAM: psi: Fix psi state corruption when schedule() races with cgroup move3b39e91301
BACKPORT: HID: steam: Prevent NULL pointer dereference in steam_{recv,send}_reportc35cda5280
BACKPORT: mm: don't be stuck to rmap lock on reclaim path9613bc53b5
Revert "firmware_loader: use kernel credentials when reading firmware"95f23ced41
UPSTREAM: crypto: jitter - add oversampling of noise sourceb046e2dca5
ANDROID: Fix kenelci build-break for !CONFIG_PERF_EVENTS24220df802
FROMGIT: f2fs: support recording stop_checkpoint reason into super_blockf18e68a234
UPSTREAM: wifi: mac80211_hwsim: use 32-bit skb cookie08cb67eb33
UPSTREAM: wifi: mac80211_hwsim: add back erroneously removed cast9b080edfbd
UPSTREAM: wifi: mac80211_hwsim: fix race condition in pending packet Update the .xml file with the newly tracked symbols: Leaf changes summary: 30 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 24 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 6 Added variables 24 Added functions: [A] 'function void __rtnl_link_unregister(rtnl_link_ops*)' [A] 'function int __traceiter_android_rvh_alloc_si(void*, swap_info_struct**, bool*)' [A] 'function int __traceiter_android_rvh_alloc_swap_slot_cache(void*, swap_slots_cache*, int*, bool*)' [A] 'function int __traceiter_android_rvh_drain_slots_cache_cpu(void*, swap_slots_cache*, unsigned int, bool, bool*)' [A] 'function int __traceiter_android_rvh_free_swap_slot(void*, swp_entry_t, swap_slots_cache*, bool*)' [A] 'function int __traceiter_android_rvh_get_swap_page(void*, page*, swp_entry_t*, swap_slots_cache*, bool*)' [A] 'function int __traceiter_android_rvh_handle_pte_fault_end(void*, vm_fault*, unsigned long int)' [A] 'function net_device* dev_get_by_index_rcu(net*, int)' [A] 'function phy_device* fixed_phy_register(unsigned int, fixed_phy_status*, device_node*)' [A] 'function void fixed_phy_unregister(phy_device*)' [A] 'function irq_domain* irq_domain_add_simple(device_node*, unsigned int, unsigned int, const irq_domain_ops*, void*)' [A] 'function int nf_register_net_hook(net*, const nf_hook_ops*)' [A] 'function void nf_unregister_net_hook(net*, const nf_hook_ops*)' [A] 'function int phy_ethtool_set_wol(phy_device*, ethtool_wolinfo*)' [A] 'function int phy_register_fixup_for_uid(u32, u32, int (phy_device*)*)' [A] 'function int phy_save_page(phy_device*)' [A] 'function int phy_unregister_fixup_for_uid(u32, u32)' [A] 'function int snd_pcm_stop_xrun(snd_pcm_substream*)' [A] 'function void tty_encode_baud_rate(tty_struct*, speed_t, speed_t)' [A] 'function int usb_autopm_get_interface_async(usb_interface*)' [A] 'function void usb_autopm_put_interface_async(usb_interface*)' [A] 'function int usb_clear_halt(usb_device*, int)' [A] 'function int usb_interrupt_msg(usb_device*, unsigned int, void*, int, int*, int)' [A] 'function int usb_unlink_urb(urb*)' 6 Added variables: [A] 'tracepoint __tracepoint_android_rvh_alloc_si' [A] 'tracepoint __tracepoint_android_rvh_alloc_swap_slot_cache' [A] 'tracepoint __tracepoint_android_rvh_drain_slots_cache_cpu' [A] 'tracepoint __tracepoint_android_rvh_free_swap_slot' [A] 'tracepoint __tracepoint_android_rvh_get_swap_page' [A] 'tracepoint __tracepoint_android_rvh_handle_pte_fault_end' Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I225d5838de38d886151cf619654412ee8c5428b2
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1901,6 +1901,8 @@
|
|||||||
find_vpid
|
find_vpid
|
||||||
finish_wait
|
finish_wait
|
||||||
firmware_request_nowarn
|
firmware_request_nowarn
|
||||||
|
fixed_phy_register
|
||||||
|
fixed_phy_unregister
|
||||||
fixed_size_llseek
|
fixed_size_llseek
|
||||||
flow_keys_basic_dissector
|
flow_keys_basic_dissector
|
||||||
flush_dcache_page
|
flush_dcache_page
|
||||||
@@ -2327,6 +2329,7 @@
|
|||||||
irq_create_mapping_affinity
|
irq_create_mapping_affinity
|
||||||
irq_create_of_mapping
|
irq_create_of_mapping
|
||||||
irq_dispose_mapping
|
irq_dispose_mapping
|
||||||
|
irq_domain_add_simple
|
||||||
irq_domain_alloc_irqs_parent
|
irq_domain_alloc_irqs_parent
|
||||||
irq_domain_create_hierarchy
|
irq_domain_create_hierarchy
|
||||||
irq_domain_free_irqs_common
|
irq_domain_free_irqs_common
|
||||||
@@ -3023,6 +3026,7 @@
|
|||||||
phy_ethtool_get_link_ksettings
|
phy_ethtool_get_link_ksettings
|
||||||
phy_ethtool_nway_reset
|
phy_ethtool_nway_reset
|
||||||
phy_ethtool_set_link_ksettings
|
phy_ethtool_set_link_ksettings
|
||||||
|
phy_ethtool_set_wol
|
||||||
phy_exit
|
phy_exit
|
||||||
phy_find_first
|
phy_find_first
|
||||||
phy_get_pause
|
phy_get_pause
|
||||||
@@ -3034,9 +3038,12 @@
|
|||||||
phy_power_off
|
phy_power_off
|
||||||
phy_power_on
|
phy_power_on
|
||||||
phy_print_status
|
phy_print_status
|
||||||
|
phy_register_fixup_for_uid
|
||||||
|
phy_save_page
|
||||||
phy_set_mode_ext
|
phy_set_mode_ext
|
||||||
phy_start
|
phy_start
|
||||||
phy_stop
|
phy_stop
|
||||||
|
phy_unregister_fixup_for_uid
|
||||||
pick_highest_pushable_task
|
pick_highest_pushable_task
|
||||||
pid_nr_ns
|
pid_nr_ns
|
||||||
pid_task
|
pid_task
|
||||||
@@ -4066,6 +4073,7 @@
|
|||||||
ttm_tt_populate
|
ttm_tt_populate
|
||||||
ttm_tt_set_placement_caching
|
ttm_tt_set_placement_caching
|
||||||
ttm_unmap_and_unpopulate_pages
|
ttm_unmap_and_unpopulate_pages
|
||||||
|
tty_encode_baud_rate
|
||||||
tty_flip_buffer_push
|
tty_flip_buffer_push
|
||||||
tty_insert_flip_string_fixed_flag
|
tty_insert_flip_string_fixed_flag
|
||||||
tty_kref_put
|
tty_kref_put
|
||||||
@@ -4214,8 +4222,10 @@
|
|||||||
usb_asmedia_modifyflowcontrol
|
usb_asmedia_modifyflowcontrol
|
||||||
usb_assign_descriptors
|
usb_assign_descriptors
|
||||||
usb_autopm_get_interface
|
usb_autopm_get_interface
|
||||||
|
usb_autopm_get_interface_async
|
||||||
usb_autopm_get_interface_no_resume
|
usb_autopm_get_interface_no_resume
|
||||||
usb_autopm_put_interface
|
usb_autopm_put_interface
|
||||||
|
usb_autopm_put_interface_async
|
||||||
usb_bulk_msg
|
usb_bulk_msg
|
||||||
usb_calc_bus_time
|
usb_calc_bus_time
|
||||||
usb_choose_configuration
|
usb_choose_configuration
|
||||||
@@ -4293,6 +4303,7 @@
|
|||||||
usb_ifnum_to_if
|
usb_ifnum_to_if
|
||||||
usb_initialize_gadget
|
usb_initialize_gadget
|
||||||
usb_interface_id
|
usb_interface_id
|
||||||
|
usb_interrupt_msg
|
||||||
usb_kill_urb
|
usb_kill_urb
|
||||||
usb_match_id
|
usb_match_id
|
||||||
usb_match_one_id
|
usb_match_one_id
|
||||||
|
@@ -3216,6 +3216,7 @@
|
|||||||
update_devfreq
|
update_devfreq
|
||||||
usb_add_phy_dev
|
usb_add_phy_dev
|
||||||
usb_assign_descriptors
|
usb_assign_descriptors
|
||||||
|
usb_clear_halt
|
||||||
usb_copy_descriptors
|
usb_copy_descriptors
|
||||||
usb_ep_alloc_request
|
usb_ep_alloc_request
|
||||||
usb_ep_autoconfig
|
usb_ep_autoconfig
|
||||||
@@ -3239,6 +3240,7 @@
|
|||||||
usb_phy_set_charger_current
|
usb_phy_set_charger_current
|
||||||
usb_remove_phy
|
usb_remove_phy
|
||||||
usb_role_switch_set_role
|
usb_role_switch_set_role
|
||||||
|
usb_unlink_urb
|
||||||
v4l2_async_notifier_add_subdev
|
v4l2_async_notifier_add_subdev
|
||||||
v4l2_async_notifier_cleanup
|
v4l2_async_notifier_cleanup
|
||||||
v4l2_async_subdev_notifier_register
|
v4l2_async_subdev_notifier_register
|
||||||
|
@@ -408,6 +408,7 @@
|
|||||||
dev_fwnode
|
dev_fwnode
|
||||||
__dev_get_by_index
|
__dev_get_by_index
|
||||||
dev_get_by_index
|
dev_get_by_index
|
||||||
|
dev_get_by_index_rcu
|
||||||
dev_get_by_name
|
dev_get_by_name
|
||||||
dev_get_regmap
|
dev_get_regmap
|
||||||
dev_get_stats
|
dev_get_stats
|
||||||
@@ -1658,7 +1659,9 @@
|
|||||||
net_ratelimit
|
net_ratelimit
|
||||||
nf_ct_attach
|
nf_ct_attach
|
||||||
nf_ct_delete
|
nf_ct_delete
|
||||||
|
nf_register_net_hook
|
||||||
nf_register_net_hooks
|
nf_register_net_hooks
|
||||||
|
nf_unregister_net_hook
|
||||||
nf_unregister_net_hooks
|
nf_unregister_net_hooks
|
||||||
nla_find
|
nla_find
|
||||||
nla_memcpy
|
nla_memcpy
|
||||||
@@ -2286,6 +2289,7 @@
|
|||||||
rtc_update_irq
|
rtc_update_irq
|
||||||
rtc_valid_tm
|
rtc_valid_tm
|
||||||
rtnl_is_locked
|
rtnl_is_locked
|
||||||
|
__rtnl_link_unregister
|
||||||
rtnl_lock
|
rtnl_lock
|
||||||
rtnl_unlock
|
rtnl_unlock
|
||||||
runqueues
|
runqueues
|
||||||
|
@@ -2626,6 +2626,7 @@
|
|||||||
snd_pcm_fill_iec958_consumer
|
snd_pcm_fill_iec958_consumer
|
||||||
snd_pcm_fill_iec958_consumer_hw_params
|
snd_pcm_fill_iec958_consumer_hw_params
|
||||||
snd_pcm_hw_constraint_eld
|
snd_pcm_hw_constraint_eld
|
||||||
|
snd_pcm_stop_xrun
|
||||||
|
|
||||||
# required by snd-soc-rk817.ko
|
# required by snd-soc-rk817.ko
|
||||||
snd_soc_component_exit_regmap
|
snd_soc_component_exit_regmap
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
nr_swap_pages
|
nr_swap_pages
|
||||||
plist_requeue
|
plist_requeue
|
||||||
plist_del
|
plist_del
|
||||||
|
__traceiter_android_rvh_handle_pte_fault_end
|
||||||
__traceiter_android_vh_handle_pte_fault_end
|
__traceiter_android_vh_handle_pte_fault_end
|
||||||
__traceiter_android_vh_cow_user_page
|
__traceiter_android_vh_cow_user_page
|
||||||
__traceiter_android_vh_swapin_add_anon_rmap
|
__traceiter_android_vh_swapin_add_anon_rmap
|
||||||
@@ -20,9 +21,13 @@
|
|||||||
__traceiter_android_vh_count_pswpout
|
__traceiter_android_vh_count_pswpout
|
||||||
__traceiter_android_vh_count_swpout_vm_event
|
__traceiter_android_vh_count_swpout_vm_event
|
||||||
__traceiter_android_vh_swap_slot_cache_active
|
__traceiter_android_vh_swap_slot_cache_active
|
||||||
|
__traceiter_android_rvh_drain_slots_cache_cpu
|
||||||
__traceiter_android_vh_drain_slots_cache_cpu
|
__traceiter_android_vh_drain_slots_cache_cpu
|
||||||
|
__traceiter_android_rvh_alloc_swap_slot_cache
|
||||||
__traceiter_android_vh_alloc_swap_slot_cache
|
__traceiter_android_vh_alloc_swap_slot_cache
|
||||||
|
__traceiter_android_rvh_free_swap_slot
|
||||||
__traceiter_android_vh_free_swap_slot
|
__traceiter_android_vh_free_swap_slot
|
||||||
|
__traceiter_android_rvh_get_swap_page
|
||||||
__traceiter_android_vh_get_swap_page
|
__traceiter_android_vh_get_swap_page
|
||||||
__traceiter_android_vh_page_isolated_for_reclaim
|
__traceiter_android_vh_page_isolated_for_reclaim
|
||||||
__traceiter_android_vh_inactive_is_low
|
__traceiter_android_vh_inactive_is_low
|
||||||
@@ -31,10 +36,12 @@
|
|||||||
__traceiter_android_vh_unuse_swap_page
|
__traceiter_android_vh_unuse_swap_page
|
||||||
__traceiter_android_vh_init_swap_info_struct
|
__traceiter_android_vh_init_swap_info_struct
|
||||||
__traceiter_android_vh_si_swapinfo
|
__traceiter_android_vh_si_swapinfo
|
||||||
|
__traceiter_android_rvh_alloc_si
|
||||||
__traceiter_android_vh_alloc_si
|
__traceiter_android_vh_alloc_si
|
||||||
__traceiter_android_vh_free_pages
|
__traceiter_android_vh_free_pages
|
||||||
__traceiter_android_vh_set_shmem_page_flag
|
__traceiter_android_vh_set_shmem_page_flag
|
||||||
__traceiter_android_vh_ra_tuning_max_page
|
__traceiter_android_vh_ra_tuning_max_page
|
||||||
|
__tracepoint_android_rvh_handle_pte_fault_end
|
||||||
__tracepoint_android_vh_handle_pte_fault_end
|
__tracepoint_android_vh_handle_pte_fault_end
|
||||||
__tracepoint_android_vh_cow_user_page
|
__tracepoint_android_vh_cow_user_page
|
||||||
__tracepoint_android_vh_swapin_add_anon_rmap
|
__tracepoint_android_vh_swapin_add_anon_rmap
|
||||||
@@ -45,9 +52,13 @@
|
|||||||
__tracepoint_android_vh_count_pswpout
|
__tracepoint_android_vh_count_pswpout
|
||||||
__tracepoint_android_vh_count_swpout_vm_event
|
__tracepoint_android_vh_count_swpout_vm_event
|
||||||
__tracepoint_android_vh_swap_slot_cache_active
|
__tracepoint_android_vh_swap_slot_cache_active
|
||||||
|
__tracepoint_android_rvh_drain_slots_cache_cpu
|
||||||
__tracepoint_android_vh_drain_slots_cache_cpu
|
__tracepoint_android_vh_drain_slots_cache_cpu
|
||||||
|
__tracepoint_android_rvh_alloc_swap_slot_cache
|
||||||
__tracepoint_android_vh_alloc_swap_slot_cache
|
__tracepoint_android_vh_alloc_swap_slot_cache
|
||||||
|
__tracepoint_android_rvh_free_swap_slot
|
||||||
__tracepoint_android_vh_free_swap_slot
|
__tracepoint_android_vh_free_swap_slot
|
||||||
|
__tracepoint_android_rvh_get_swap_page
|
||||||
__tracepoint_android_vh_get_swap_page
|
__tracepoint_android_vh_get_swap_page
|
||||||
__tracepoint_android_vh_page_isolated_for_reclaim
|
__tracepoint_android_vh_page_isolated_for_reclaim
|
||||||
__tracepoint_android_vh_inactive_is_low
|
__tracepoint_android_vh_inactive_is_low
|
||||||
@@ -56,6 +67,7 @@
|
|||||||
__tracepoint_android_vh_unuse_swap_page
|
__tracepoint_android_vh_unuse_swap_page
|
||||||
__tracepoint_android_vh_init_swap_info_struct
|
__tracepoint_android_vh_init_swap_info_struct
|
||||||
__tracepoint_android_vh_si_swapinfo
|
__tracepoint_android_vh_si_swapinfo
|
||||||
|
__tracepoint_android_rvh_alloc_si
|
||||||
__tracepoint_android_vh_alloc_si
|
__tracepoint_android_vh_alloc_si
|
||||||
__tracepoint_android_vh_free_pages
|
__tracepoint_android_vh_free_pages
|
||||||
__tracepoint_android_vh_set_shmem_page_flag
|
__tracepoint_android_vh_set_shmem_page_flag
|
||||||
|
@@ -117,6 +117,22 @@ struct rand_data {
|
|||||||
#define JENT_EHEALTH 9 /* Health test failed during initialization */
|
#define JENT_EHEALTH 9 /* Health test failed during initialization */
|
||||||
#define JENT_ERCT 10 /* RCT failed during initialization */
|
#define JENT_ERCT 10 /* RCT failed during initialization */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The output n bits can receive more than n bits of min entropy, of course,
|
||||||
|
* but the fixed output of the conditioning function can only asymptotically
|
||||||
|
* approach the output size bits of min entropy, not attain that bound. Random
|
||||||
|
* maps will tend to have output collisions, which reduces the creditable
|
||||||
|
* output entropy (that is what SP 800-90B Section 3.1.5.1.2 attempts to bound).
|
||||||
|
*
|
||||||
|
* The value "64" is justified in Appendix A.4 of the current 90C draft,
|
||||||
|
* and aligns with NIST's in "epsilon" definition in this document, which is
|
||||||
|
* that a string can be considered "full entropy" if you can bound the min
|
||||||
|
* entropy in each bit of output to at least 1-epsilon, where epsilon is
|
||||||
|
* required to be <= 2^(-32).
|
||||||
|
*/
|
||||||
|
#define JENT_ENTROPY_SAFETY_FACTOR 64
|
||||||
|
|
||||||
|
#include <linux/fips.h>
|
||||||
#include "jitterentropy.h"
|
#include "jitterentropy.h"
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@@ -546,7 +562,10 @@ static int jent_measure_jitter(struct rand_data *ec)
|
|||||||
*/
|
*/
|
||||||
static void jent_gen_entropy(struct rand_data *ec)
|
static void jent_gen_entropy(struct rand_data *ec)
|
||||||
{
|
{
|
||||||
unsigned int k = 0;
|
unsigned int k = 0, safety_factor = 0;
|
||||||
|
|
||||||
|
if (fips_enabled)
|
||||||
|
safety_factor = JENT_ENTROPY_SAFETY_FACTOR;
|
||||||
|
|
||||||
/* priming of the ->prev_time value */
|
/* priming of the ->prev_time value */
|
||||||
jent_measure_jitter(ec);
|
jent_measure_jitter(ec);
|
||||||
@@ -560,7 +579,7 @@ static void jent_gen_entropy(struct rand_data *ec)
|
|||||||
* We multiply the loop value with ->osr to obtain the
|
* We multiply the loop value with ->osr to obtain the
|
||||||
* oversampling rate requested by the caller
|
* oversampling rate requested by the caller
|
||||||
*/
|
*/
|
||||||
if (++k >= (DATA_SIZE_BITS * ec->osr))
|
if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -431,6 +431,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_read_done);
|
|||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_tlb_conf);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_tlb_conf);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_node_memcgs);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_node_memcgs);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ra_tuning_max_page);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ra_tuning_max_page);
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_handle_pte_fault_end);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_pte_fault_end);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_pte_fault_end);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cow_user_page);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cow_user_page);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swapin_add_anon_rmap);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swapin_add_anon_rmap);
|
||||||
@@ -441,9 +442,13 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_pswpin);
|
|||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_pswpout);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_pswpout);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_swpout_vm_event);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_swpout_vm_event);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swap_slot_cache_active);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_swap_slot_cache_active);
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_drain_slots_cache_cpu);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_drain_slots_cache_cpu);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_drain_slots_cache_cpu);
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_alloc_swap_slot_cache);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_swap_slot_cache);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_swap_slot_cache);
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_free_swap_slot);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_swap_slot);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_swap_slot);
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_get_swap_page);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_swap_page);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_swap_page);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_cold_or_pageout);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_cold_or_pageout);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_isolated_for_reclaim);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_isolated_for_reclaim);
|
||||||
@@ -453,6 +458,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_account_swap_pages);
|
|||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_unuse_swap_page);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_unuse_swap_page);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_init_swap_info_struct);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_init_swap_info_struct);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_si_swapinfo);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_si_swapinfo);
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_alloc_si);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_si);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_si);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages);
|
||||||
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_shmem_page_flag);
|
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_shmem_page_flag);
|
||||||
|
@@ -793,8 +793,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
size_t offset, u32 opt_flags)
|
size_t offset, u32 opt_flags)
|
||||||
{
|
{
|
||||||
struct firmware *fw = NULL;
|
struct firmware *fw = NULL;
|
||||||
struct cred *kern_cred = NULL;
|
|
||||||
const struct cred *old_cred;
|
|
||||||
bool nondirect = false;
|
bool nondirect = false;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -811,18 +809,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
if (ret <= 0) /* error or already assigned */
|
if (ret <= 0) /* error or already assigned */
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
|
||||||
* We are about to try to access the firmware file. Because we may have been
|
|
||||||
* called by a driver when serving an unrelated request from userland, we use
|
|
||||||
* the kernel credentials to read the file.
|
|
||||||
*/
|
|
||||||
kern_cred = prepare_kernel_cred(NULL);
|
|
||||||
if (!kern_cred) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
old_cred = override_creds(kern_cred);
|
|
||||||
|
|
||||||
ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
|
ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
|
||||||
|
|
||||||
/* Only full reads can support decompression, platform, and sysfs. */
|
/* Only full reads can support decompression, platform, and sysfs. */
|
||||||
@@ -848,9 +834,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
} else
|
} else
|
||||||
ret = assign_fw(fw, device);
|
ret = assign_fw(fw, device);
|
||||||
|
|
||||||
revert_creds(old_cred);
|
|
||||||
put_cred(kern_cred);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fw_abort_batch_reqs(fw);
|
fw_abort_batch_reqs(fw);
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/sysfs.h>
|
#include <linux/sysfs.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
#include "dma-buf-sysfs-stats.h"
|
#include "dma-buf-sysfs-stats.h"
|
||||||
|
|
||||||
@@ -135,10 +136,51 @@ void dma_buf_uninit_sysfs_statistics(void)
|
|||||||
kset_unregister(dma_buf_stats_kset);
|
kset_unregister(dma_buf_stats_kset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sysfs_add_workfn(struct work_struct *work)
|
||||||
|
{
|
||||||
|
/* The ABI would have to change for this to be false, but let's be paranoid. */
|
||||||
|
_Static_assert(sizeof(struct kobject) >= sizeof(struct work_struct),
|
||||||
|
"kobject is smaller than work_struct");
|
||||||
|
|
||||||
|
struct dma_buf_sysfs_entry *sysfs_entry =
|
||||||
|
container_of((struct kobject *)work, struct dma_buf_sysfs_entry, kobj);
|
||||||
|
struct dma_buf *dmabuf = sysfs_entry->dmabuf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A dmabuf is ref-counted via its file member. If this handler holds the only
|
||||||
|
* reference to the dmabuf, there is no need for sysfs kobject creation. This is an
|
||||||
|
* optimization and a race; when the reference count drops to 1 immediately after
|
||||||
|
* this check it is not harmful as the sysfs entry will still get cleaned up in
|
||||||
|
* dma_buf_stats_teardown, which won't get called until the final dmabuf reference
|
||||||
|
* is released, and that can't happen until the end of this function.
|
||||||
|
*/
|
||||||
|
if (file_count(dmabuf->file) > 1) {
|
||||||
|
/*
|
||||||
|
* kobject_init_and_add expects kobject to be zero-filled, but we have populated it
|
||||||
|
* to trigger this work function.
|
||||||
|
*/
|
||||||
|
memset(&dmabuf->sysfs_entry->kobj, 0, sizeof(dmabuf->sysfs_entry->kobj));
|
||||||
|
dmabuf->sysfs_entry->kobj.kset = dma_buf_per_buffer_stats_kset;
|
||||||
|
if (kobject_init_and_add(&dmabuf->sysfs_entry->kobj, &dma_buf_ktype, NULL,
|
||||||
|
"%lu", file_inode(dmabuf->file)->i_ino)) {
|
||||||
|
kobject_put(&dmabuf->sysfs_entry->kobj);
|
||||||
|
dmabuf->sysfs_entry = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Free the sysfs_entry and reset the pointer so dma_buf_stats_teardown doesn't
|
||||||
|
* attempt to operate on it.
|
||||||
|
*/
|
||||||
|
kfree(dmabuf->sysfs_entry);
|
||||||
|
dmabuf->sysfs_entry = NULL;
|
||||||
|
}
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
}
|
||||||
|
|
||||||
int dma_buf_stats_setup(struct dma_buf *dmabuf)
|
int dma_buf_stats_setup(struct dma_buf *dmabuf)
|
||||||
{
|
{
|
||||||
struct dma_buf_sysfs_entry *sysfs_entry;
|
struct dma_buf_sysfs_entry *sysfs_entry;
|
||||||
int ret;
|
struct work_struct *work;
|
||||||
|
|
||||||
if (!dmabuf || !dmabuf->file)
|
if (!dmabuf || !dmabuf->file)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -148,25 +190,21 @@ int dma_buf_stats_setup(struct dma_buf *dmabuf)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysfs_entry = kzalloc(sizeof(struct dma_buf_sysfs_entry), GFP_KERNEL);
|
sysfs_entry = kmalloc(sizeof(struct dma_buf_sysfs_entry), GFP_KERNEL);
|
||||||
if (!sysfs_entry)
|
if (!sysfs_entry)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
sysfs_entry->kobj.kset = dma_buf_per_buffer_stats_kset;
|
|
||||||
sysfs_entry->dmabuf = dmabuf;
|
sysfs_entry->dmabuf = dmabuf;
|
||||||
|
|
||||||
dmabuf->sysfs_entry = sysfs_entry;
|
dmabuf->sysfs_entry = sysfs_entry;
|
||||||
|
|
||||||
/* create the directory for buffer stats */
|
/*
|
||||||
ret = kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_ktype, NULL,
|
* The use of kobj as a work_struct is an ugly hack
|
||||||
"%lu", file_inode(dmabuf->file)->i_ino);
|
* to avoid an ABI break in this frozen kernel.
|
||||||
if (ret)
|
*/
|
||||||
goto err_sysfs_dmabuf;
|
work = (struct work_struct *)&dmabuf->sysfs_entry->kobj;
|
||||||
|
INIT_WORK(work, sysfs_add_workfn);
|
||||||
|
get_dma_buf(dmabuf); /* This reference will be dropped in sysfs_add_workfn. */
|
||||||
|
schedule_work(work);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_sysfs_dmabuf:
|
|
||||||
kobject_put(&sysfs_entry->kobj);
|
|
||||||
dmabuf->sysfs_entry = NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
@@ -486,6 +486,7 @@ EXPORT_SYMBOL_GPL(is_dma_buf_file);
|
|||||||
|
|
||||||
static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
|
static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
|
||||||
{
|
{
|
||||||
|
static atomic64_t dmabuf_inode = ATOMIC64_INIT(0);
|
||||||
struct file *file;
|
struct file *file;
|
||||||
struct inode *inode = alloc_anon_inode(dma_buf_mnt->mnt_sb);
|
struct inode *inode = alloc_anon_inode(dma_buf_mnt->mnt_sb);
|
||||||
|
|
||||||
@@ -495,6 +496,13 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
|
|||||||
inode->i_size = dmabuf->size;
|
inode->i_size = dmabuf->size;
|
||||||
inode_set_bytes(inode, dmabuf->size);
|
inode_set_bytes(inode, dmabuf->size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ->i_ino acquired from get_next_ino() is not unique thus
|
||||||
|
* not suitable for using it as dentry name by dmabuf stats.
|
||||||
|
* Override ->i_ino with the unique and dmabuffs specific
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
inode->i_ino = atomic64_add_return(1, &dmabuf_inode);
|
||||||
file = alloc_file_pseudo(inode, dma_buf_mnt, "dmabuf",
|
file = alloc_file_pseudo(inode, dma_buf_mnt, "dmabuf",
|
||||||
flags, &dma_buf_fops);
|
flags, &dma_buf_fops);
|
||||||
if (IS_ERR(file))
|
if (IS_ERR(file))
|
||||||
@@ -621,10 +629,6 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
|||||||
file->f_mode |= FMODE_LSEEK;
|
file->f_mode |= FMODE_LSEEK;
|
||||||
dmabuf->file = file;
|
dmabuf->file = file;
|
||||||
|
|
||||||
ret = dma_buf_stats_setup(dmabuf);
|
|
||||||
if (ret)
|
|
||||||
goto err_sysfs;
|
|
||||||
|
|
||||||
mutex_init(&dmabuf->lock);
|
mutex_init(&dmabuf->lock);
|
||||||
INIT_LIST_HEAD(&dmabuf->attachments);
|
INIT_LIST_HEAD(&dmabuf->attachments);
|
||||||
|
|
||||||
@@ -632,6 +636,10 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
|||||||
list_add(&dmabuf->list_node, &db_list.head);
|
list_add(&dmabuf->list_node, &db_list.head);
|
||||||
mutex_unlock(&db_list.lock);
|
mutex_unlock(&db_list.lock);
|
||||||
|
|
||||||
|
ret = dma_buf_stats_setup(dmabuf);
|
||||||
|
if (ret)
|
||||||
|
goto err_sysfs;
|
||||||
|
|
||||||
return dmabuf;
|
return dmabuf;
|
||||||
|
|
||||||
err_sysfs:
|
err_sysfs:
|
||||||
|
@@ -25,12 +25,16 @@
|
|||||||
static struct kmem_cache *ino_entry_slab;
|
static struct kmem_cache *ino_entry_slab;
|
||||||
struct kmem_cache *f2fs_inode_entry_slab;
|
struct kmem_cache *f2fs_inode_entry_slab;
|
||||||
|
|
||||||
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
|
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
|
||||||
|
unsigned char reason)
|
||||||
{
|
{
|
||||||
f2fs_build_fault_attr(sbi, 0, 0);
|
f2fs_build_fault_attr(sbi, 0, 0);
|
||||||
set_ckpt_flags(sbi, CP_ERROR_FLAG);
|
set_ckpt_flags(sbi, CP_ERROR_FLAG);
|
||||||
if (!end_io)
|
if (!end_io) {
|
||||||
f2fs_flush_merged_writes(sbi);
|
f2fs_flush_merged_writes(sbi);
|
||||||
|
|
||||||
|
f2fs_handle_stop(sbi, reason);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -120,7 +124,7 @@ retry:
|
|||||||
if (PTR_ERR(page) == -EIO &&
|
if (PTR_ERR(page) == -EIO &&
|
||||||
++count <= DEFAULT_RETRY_IO_COUNT)
|
++count <= DEFAULT_RETRY_IO_COUNT)
|
||||||
goto retry;
|
goto retry;
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE);
|
||||||
}
|
}
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
@@ -311,7 +311,8 @@ static void f2fs_write_end_io(struct bio *bio)
|
|||||||
mempool_free(page, sbi->write_io_dummy);
|
mempool_free(page, sbi->write_io_dummy);
|
||||||
|
|
||||||
if (unlikely(bio->bi_status))
|
if (unlikely(bio->bi_status))
|
||||||
f2fs_stop_checkpoint(sbi, true);
|
f2fs_stop_checkpoint(sbi, true,
|
||||||
|
STOP_CP_REASON_WRITE_FAIL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +328,8 @@ static void f2fs_write_end_io(struct bio *bio)
|
|||||||
if (unlikely(bio->bi_status)) {
|
if (unlikely(bio->bi_status)) {
|
||||||
mapping_set_error(page->mapping, -EIO);
|
mapping_set_error(page->mapping, -EIO);
|
||||||
if (type == F2FS_WB_CP_DATA)
|
if (type == F2FS_WB_CP_DATA)
|
||||||
f2fs_stop_checkpoint(sbi, true);
|
f2fs_stop_checkpoint(sbi, true,
|
||||||
|
STOP_CP_REASON_WRITE_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&
|
f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&
|
||||||
|
@@ -3482,6 +3482,7 @@ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
|
|||||||
int f2fs_quota_sync(struct super_block *sb, int type);
|
int f2fs_quota_sync(struct super_block *sb, int type);
|
||||||
loff_t max_file_blocks(struct inode *inode);
|
loff_t max_file_blocks(struct inode *inode);
|
||||||
void f2fs_quota_off_umount(struct super_block *sb);
|
void f2fs_quota_off_umount(struct super_block *sb);
|
||||||
|
void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason);
|
||||||
int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
|
int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
|
||||||
int f2fs_sync_fs(struct super_block *sb, int sync);
|
int f2fs_sync_fs(struct super_block *sb, int sync);
|
||||||
int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi);
|
int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi);
|
||||||
@@ -3631,7 +3632,8 @@ unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
|
|||||||
/*
|
/*
|
||||||
* checkpoint.c
|
* checkpoint.c
|
||||||
*/
|
*/
|
||||||
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
|
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
|
||||||
|
unsigned char reason);
|
||||||
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
|
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
|
||||||
struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
|
struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
|
||||||
struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
|
struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
|
||||||
|
@@ -2249,7 +2249,8 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret == -EROFS) {
|
if (ret == -EROFS) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false,
|
||||||
|
STOP_CP_REASON_SHUTDOWN);
|
||||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||||
trace_f2fs_shutdown(sbi, in, ret);
|
trace_f2fs_shutdown(sbi, in, ret);
|
||||||
}
|
}
|
||||||
@@ -2262,7 +2263,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
|||||||
ret = freeze_bdev(sb->s_bdev);
|
ret = freeze_bdev(sb->s_bdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
|
||||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||||
thaw_bdev(sb->s_bdev);
|
thaw_bdev(sb->s_bdev);
|
||||||
break;
|
break;
|
||||||
@@ -2271,16 +2272,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
|||||||
ret = f2fs_sync_fs(sb, 1);
|
ret = f2fs_sync_fs(sb, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
|
||||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||||
break;
|
break;
|
||||||
case F2FS_GOING_DOWN_NOSYNC:
|
case F2FS_GOING_DOWN_NOSYNC:
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
|
||||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||||
break;
|
break;
|
||||||
case F2FS_GOING_DOWN_METAFLUSH:
|
case F2FS_GOING_DOWN_METAFLUSH:
|
||||||
f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
|
f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
|
||||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||||
break;
|
break;
|
||||||
case F2FS_GOING_DOWN_NEED_FSCK:
|
case F2FS_GOING_DOWN_NEED_FSCK:
|
||||||
|
@@ -68,7 +68,8 @@ static int gc_thread_func(void *data)
|
|||||||
|
|
||||||
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
|
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
|
||||||
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
|
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false,
|
||||||
|
STOP_CP_REASON_FAULT_INJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sb_start_write_trylock(sbi->sb)) {
|
if (!sb_start_write_trylock(sbi->sb)) {
|
||||||
@@ -1634,7 +1635,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
|
|||||||
f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT",
|
f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT",
|
||||||
segno, type, GET_SUM_TYPE((&sum->footer)));
|
segno, type, GET_SUM_TYPE((&sum->footer)));
|
||||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false,
|
||||||
|
STOP_CP_REASON_CORRUPTED_SUMMARY);
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -685,7 +685,8 @@ retry:
|
|||||||
cond_resched();
|
cond_resched();
|
||||||
goto retry;
|
goto retry;
|
||||||
} else if (err != -ENOENT) {
|
} else if (err != -ENOENT) {
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false,
|
||||||
|
STOP_CP_REASON_UPDATE_INODE);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -499,7 +499,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
|
|||||||
{
|
{
|
||||||
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
|
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
|
||||||
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
|
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
|
||||||
f2fs_stop_checkpoint(sbi, false);
|
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_FAULT_INJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* balance_fs_bg is able to be pending */
|
/* balance_fs_bg is able to be pending */
|
||||||
@@ -782,8 +782,11 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi)
|
|||||||
if (!f2fs_test_bit(i, (char *)&sbi->dirty_device))
|
if (!f2fs_test_bit(i, (char *)&sbi->dirty_device))
|
||||||
continue;
|
continue;
|
||||||
ret = __submit_flush_wait(sbi, FDEV(i).bdev);
|
ret = __submit_flush_wait(sbi, FDEV(i).bdev);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
f2fs_stop_checkpoint(sbi, false,
|
||||||
|
STOP_CP_REASON_FLUSH_FAIL);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock(&sbi->dev_lock);
|
spin_lock(&sbi->dev_lock);
|
||||||
f2fs_clear_bit(i, (char *)&sbi->dirty_device);
|
f2fs_clear_bit(i, (char *)&sbi->dirty_device);
|
||||||
|
@@ -3642,6 +3642,26 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason)
|
||||||
|
{
|
||||||
|
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
f2fs_bug_on(sbi, reason >= MAX_STOP_REASON);
|
||||||
|
|
||||||
|
f2fs_down_write(&sbi->sb_lock);
|
||||||
|
|
||||||
|
if (raw_super->s_stop_reason[reason] < ((1 << BITS_PER_BYTE) - 1))
|
||||||
|
raw_super->s_stop_reason[reason]++;
|
||||||
|
|
||||||
|
err = f2fs_commit_super(sbi, false);
|
||||||
|
if (err)
|
||||||
|
f2fs_err(sbi, "f2fs_commit_super fails to record reason:%u err:%d",
|
||||||
|
reason, err);
|
||||||
|
|
||||||
|
f2fs_up_write(&sbi->sb_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
|
static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
|
||||||
{
|
{
|
||||||
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
|
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
|
||||||
|
@@ -73,6 +73,20 @@ struct f2fs_device {
|
|||||||
__le32 total_segments;
|
__le32 total_segments;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/* reason of stop_checkpoint */
|
||||||
|
enum stop_cp_reason {
|
||||||
|
STOP_CP_REASON_SHUTDOWN,
|
||||||
|
STOP_CP_REASON_FAULT_INJECT,
|
||||||
|
STOP_CP_REASON_META_PAGE,
|
||||||
|
STOP_CP_REASON_WRITE_FAIL,
|
||||||
|
STOP_CP_REASON_CORRUPTED_SUMMARY,
|
||||||
|
STOP_CP_REASON_UPDATE_INODE,
|
||||||
|
STOP_CP_REASON_FLUSH_FAIL,
|
||||||
|
STOP_CP_REASON_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_STOP_REASON 32
|
||||||
|
|
||||||
struct f2fs_super_block {
|
struct f2fs_super_block {
|
||||||
__le32 magic; /* Magic Number */
|
__le32 magic; /* Magic Number */
|
||||||
__le16 major_ver; /* Major Version */
|
__le16 major_ver; /* Major Version */
|
||||||
@@ -116,7 +130,8 @@ struct f2fs_super_block {
|
|||||||
__u8 hot_ext_count; /* # of hot file extension */
|
__u8 hot_ext_count; /* # of hot file extension */
|
||||||
__le16 s_encoding; /* Filename charset encoding */
|
__le16 s_encoding; /* Filename charset encoding */
|
||||||
__le16 s_encoding_flags; /* Filename charset encoding flags */
|
__le16 s_encoding_flags; /* Filename charset encoding flags */
|
||||||
__u8 reserved[306]; /* valid reserved region */
|
__u8 s_stop_reason[MAX_STOP_REASON]; /* stop checkpoint reason */
|
||||||
|
__u8 reserved[274]; /* valid reserved region */
|
||||||
__le32 crc; /* checksum of superblock */
|
__le32 crc; /* checksum of superblock */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
@@ -515,6 +515,11 @@ static inline void i_mmap_unlock_write(struct address_space *mapping)
|
|||||||
up_write(&mapping->i_mmap_rwsem);
|
up_write(&mapping->i_mmap_rwsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int i_mmap_trylock_read(struct address_space *mapping)
|
||||||
|
{
|
||||||
|
return down_read_trylock(&mapping->i_mmap_rwsem);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void i_mmap_lock_read(struct address_space *mapping)
|
static inline void i_mmap_lock_read(struct address_space *mapping)
|
||||||
{
|
{
|
||||||
down_read(&mapping->i_mmap_rwsem);
|
down_read(&mapping->i_mmap_rwsem);
|
||||||
|
@@ -134,6 +134,11 @@ static inline void anon_vma_lock_read(struct anon_vma *anon_vma)
|
|||||||
down_read(&anon_vma->root->rwsem);
|
down_read(&anon_vma->root->rwsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int anon_vma_trylock_read(struct anon_vma *anon_vma)
|
||||||
|
{
|
||||||
|
return down_read_trylock(&anon_vma->root->rwsem);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void anon_vma_unlock_read(struct anon_vma *anon_vma)
|
static inline void anon_vma_unlock_read(struct anon_vma *anon_vma)
|
||||||
{
|
{
|
||||||
up_read(&anon_vma->root->rwsem);
|
up_read(&anon_vma->root->rwsem);
|
||||||
@@ -261,17 +266,14 @@ void try_to_munlock(struct page *);
|
|||||||
|
|
||||||
void remove_migration_ptes(struct page *old, struct page *new, bool locked);
|
void remove_migration_ptes(struct page *old, struct page *new, bool locked);
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by memory-failure.c to kill processes.
|
|
||||||
*/
|
|
||||||
struct anon_vma *page_lock_anon_vma_read(struct page *page);
|
|
||||||
void page_unlock_anon_vma_read(struct anon_vma *anon_vma);
|
|
||||||
int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma);
|
int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rmap_walk_control: To control rmap traversing for specific needs
|
* rmap_walk_control: To control rmap traversing for specific needs
|
||||||
*
|
*
|
||||||
* arg: passed to rmap_one() and invalid_vma()
|
* arg: passed to rmap_one() and invalid_vma()
|
||||||
|
* try_lock: bail out if the rmap lock is contended
|
||||||
|
* contended: indicate the rmap traversal bailed out due to lock contention
|
||||||
* rmap_one: executed on each vma where page is mapped
|
* rmap_one: executed on each vma where page is mapped
|
||||||
* done: for checking traversing termination condition
|
* done: for checking traversing termination condition
|
||||||
* anon_lock: for getting anon_lock by optimized way rather than default
|
* anon_lock: for getting anon_lock by optimized way rather than default
|
||||||
@@ -279,6 +281,8 @@ int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma);
|
|||||||
*/
|
*/
|
||||||
struct rmap_walk_control {
|
struct rmap_walk_control {
|
||||||
void *arg;
|
void *arg;
|
||||||
|
bool try_lock;
|
||||||
|
bool contended;
|
||||||
/*
|
/*
|
||||||
* Return false if page table scanning in rmap_walk should be stopped.
|
* Return false if page table scanning in rmap_walk should be stopped.
|
||||||
* Otherwise, return true.
|
* Otherwise, return true.
|
||||||
@@ -286,13 +290,21 @@ struct rmap_walk_control {
|
|||||||
bool (*rmap_one)(struct page *page, struct vm_area_struct *vma,
|
bool (*rmap_one)(struct page *page, struct vm_area_struct *vma,
|
||||||
unsigned long addr, void *arg);
|
unsigned long addr, void *arg);
|
||||||
int (*done)(struct page *page);
|
int (*done)(struct page *page);
|
||||||
struct anon_vma *(*anon_lock)(struct page *page);
|
struct anon_vma *(*anon_lock)(struct page *page,
|
||||||
|
struct rmap_walk_control *rwc);
|
||||||
bool (*invalid_vma)(struct vm_area_struct *vma, void *arg);
|
bool (*invalid_vma)(struct vm_area_struct *vma, void *arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
void rmap_walk(struct page *page, struct rmap_walk_control *rwc);
|
void rmap_walk(struct page *page, struct rmap_walk_control *rwc);
|
||||||
void rmap_walk_locked(struct page *page, struct rmap_walk_control *rwc);
|
void rmap_walk_locked(struct page *page, struct rmap_walk_control *rwc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by memory-failure.c to kill processes.
|
||||||
|
*/
|
||||||
|
struct anon_vma *page_lock_anon_vma_read(struct page *page,
|
||||||
|
struct rmap_walk_control *rwc);
|
||||||
|
void page_unlock_anon_vma_read(struct anon_vma *anon_vma);
|
||||||
|
|
||||||
#else /* !CONFIG_MMU */
|
#else /* !CONFIG_MMU */
|
||||||
|
|
||||||
#define anon_vma_init() do {} while (0)
|
#define anon_vma_init() do {} while (0)
|
||||||
|
@@ -193,6 +193,9 @@ DECLARE_HOOK(android_vh_subpage_dma_contig_alloc,
|
|||||||
DECLARE_HOOK(android_vh_ra_tuning_max_page,
|
DECLARE_HOOK(android_vh_ra_tuning_max_page,
|
||||||
TP_PROTO(struct readahead_control *ractl, unsigned long *max_page),
|
TP_PROTO(struct readahead_control *ractl, unsigned long *max_page),
|
||||||
TP_ARGS(ractl, max_page));
|
TP_ARGS(ractl, max_page));
|
||||||
|
DECLARE_RESTRICTED_HOOK(android_rvh_handle_pte_fault_end,
|
||||||
|
TP_PROTO(struct vm_fault *vmf, unsigned long highest_memmap_pfn),
|
||||||
|
TP_ARGS(vmf, highest_memmap_pfn), 1);
|
||||||
DECLARE_HOOK(android_vh_handle_pte_fault_end,
|
DECLARE_HOOK(android_vh_handle_pte_fault_end,
|
||||||
TP_PROTO(struct vm_fault *vmf, unsigned long highest_memmap_pfn),
|
TP_PROTO(struct vm_fault *vmf, unsigned long highest_memmap_pfn),
|
||||||
TP_ARGS(vmf, highest_memmap_pfn));
|
TP_ARGS(vmf, highest_memmap_pfn));
|
||||||
@@ -223,16 +226,30 @@ DECLARE_HOOK(android_vh_count_swpout_vm_event,
|
|||||||
DECLARE_HOOK(android_vh_swap_slot_cache_active,
|
DECLARE_HOOK(android_vh_swap_slot_cache_active,
|
||||||
TP_PROTO(bool swap_slot_cache_active),
|
TP_PROTO(bool swap_slot_cache_active),
|
||||||
TP_ARGS(swap_slot_cache_active));
|
TP_ARGS(swap_slot_cache_active));
|
||||||
|
DECLARE_RESTRICTED_HOOK(android_rvh_drain_slots_cache_cpu,
|
||||||
|
TP_PROTO(struct swap_slots_cache *cache, unsigned int type,
|
||||||
|
bool free_slots, bool *skip),
|
||||||
|
TP_ARGS(cache, type, free_slots, skip), 1);
|
||||||
DECLARE_HOOK(android_vh_drain_slots_cache_cpu,
|
DECLARE_HOOK(android_vh_drain_slots_cache_cpu,
|
||||||
TP_PROTO(struct swap_slots_cache *cache, unsigned int type,
|
TP_PROTO(struct swap_slots_cache *cache, unsigned int type,
|
||||||
bool free_slots, bool *skip),
|
bool free_slots, bool *skip),
|
||||||
TP_ARGS(cache, type, free_slots, skip));
|
TP_ARGS(cache, type, free_slots, skip));
|
||||||
|
DECLARE_RESTRICTED_HOOK(android_rvh_alloc_swap_slot_cache,
|
||||||
|
TP_PROTO(struct swap_slots_cache *cache, int *ret, bool *skip),
|
||||||
|
TP_ARGS(cache, ret, skip), 1);
|
||||||
DECLARE_HOOK(android_vh_alloc_swap_slot_cache,
|
DECLARE_HOOK(android_vh_alloc_swap_slot_cache,
|
||||||
TP_PROTO(struct swap_slots_cache *cache, int *ret, bool *skip),
|
TP_PROTO(struct swap_slots_cache *cache, int *ret, bool *skip),
|
||||||
TP_ARGS(cache, ret, skip));
|
TP_ARGS(cache, ret, skip));
|
||||||
|
DECLARE_RESTRICTED_HOOK(android_rvh_free_swap_slot,
|
||||||
|
TP_PROTO(swp_entry_t entry, struct swap_slots_cache *cache, bool *skip),
|
||||||
|
TP_ARGS(entry, cache, skip), 1);
|
||||||
DECLARE_HOOK(android_vh_free_swap_slot,
|
DECLARE_HOOK(android_vh_free_swap_slot,
|
||||||
TP_PROTO(swp_entry_t entry, struct swap_slots_cache *cache, bool *skip),
|
TP_PROTO(swp_entry_t entry, struct swap_slots_cache *cache, bool *skip),
|
||||||
TP_ARGS(entry, cache, skip));
|
TP_ARGS(entry, cache, skip));
|
||||||
|
DECLARE_RESTRICTED_HOOK(android_rvh_get_swap_page,
|
||||||
|
TP_PROTO(struct page *page, swp_entry_t *entry,
|
||||||
|
struct swap_slots_cache *cache, bool *found),
|
||||||
|
TP_ARGS(page, entry, cache, found), 1);
|
||||||
DECLARE_HOOK(android_vh_get_swap_page,
|
DECLARE_HOOK(android_vh_get_swap_page,
|
||||||
TP_PROTO(struct page *page, swp_entry_t *entry,
|
TP_PROTO(struct page *page, swp_entry_t *entry,
|
||||||
struct swap_slots_cache *cache, bool *found),
|
struct swap_slots_cache *cache, bool *found),
|
||||||
@@ -255,6 +272,9 @@ DECLARE_HOOK(android_vh_init_swap_info_struct,
|
|||||||
DECLARE_HOOK(android_vh_si_swapinfo,
|
DECLARE_HOOK(android_vh_si_swapinfo,
|
||||||
TP_PROTO(struct swap_info_struct *si, bool *skip),
|
TP_PROTO(struct swap_info_struct *si, bool *skip),
|
||||||
TP_ARGS(si, skip));
|
TP_ARGS(si, skip));
|
||||||
|
DECLARE_RESTRICTED_HOOK(android_rvh_alloc_si,
|
||||||
|
TP_PROTO(struct swap_info_struct **p, bool *skip),
|
||||||
|
TP_ARGS(p, skip), 1);
|
||||||
DECLARE_HOOK(android_vh_alloc_si,
|
DECLARE_HOOK(android_vh_alloc_si,
|
||||||
TP_PROTO(struct swap_info_struct **p, bool *skip),
|
TP_PROTO(struct swap_info_struct **p, bool *skip),
|
||||||
TP_ARGS(p, skip));
|
TP_ARGS(p, skip));
|
||||||
|
@@ -1865,7 +1865,9 @@ int __boot_cpu_id;
|
|||||||
/* Horrific hacks because we can't add more to cpuhp_hp_states. */
|
/* Horrific hacks because we can't add more to cpuhp_hp_states. */
|
||||||
static int random_and_perf_prepare_fusion(unsigned int cpu)
|
static int random_and_perf_prepare_fusion(unsigned int cpu)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_PERF_EVENTS
|
||||||
perf_event_init_cpu(cpu);
|
perf_event_init_cpu(cpu);
|
||||||
|
#endif
|
||||||
random_prepare_cpu(cpu);
|
random_prepare_cpu(cpu);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -1020,7 +1020,7 @@ void psi_cgroup_free(struct cgroup *cgroup)
|
|||||||
*/
|
*/
|
||||||
void cgroup_move_task(struct task_struct *task, struct css_set *to)
|
void cgroup_move_task(struct task_struct *task, struct css_set *to)
|
||||||
{
|
{
|
||||||
unsigned int task_flags = 0;
|
unsigned int task_flags;
|
||||||
struct rq_flags rf;
|
struct rq_flags rf;
|
||||||
struct rq *rq;
|
struct rq *rq;
|
||||||
|
|
||||||
@@ -1035,15 +1035,31 @@ void cgroup_move_task(struct task_struct *task, struct css_set *to)
|
|||||||
|
|
||||||
rq = task_rq_lock(task, &rf);
|
rq = task_rq_lock(task, &rf);
|
||||||
|
|
||||||
if (task_on_rq_queued(task)) {
|
/*
|
||||||
task_flags = TSK_RUNNING;
|
* We may race with schedule() dropping the rq lock between
|
||||||
if (task_current(rq, task))
|
* deactivating prev and switching to next. Because the psi
|
||||||
task_flags |= TSK_ONCPU;
|
* updates from the deactivation are deferred to the switch
|
||||||
} else if (task->in_iowait)
|
* callback to save cgroup tree updates, the task's scheduling
|
||||||
task_flags = TSK_IOWAIT;
|
* state here is not coherent with its psi state:
|
||||||
|
*
|
||||||
if (task->in_memstall)
|
* schedule() cgroup_move_task()
|
||||||
task_flags |= TSK_MEMSTALL;
|
* rq_lock()
|
||||||
|
* deactivate_task()
|
||||||
|
* p->on_rq = 0
|
||||||
|
* psi_dequeue() // defers TSK_RUNNING & TSK_IOWAIT updates
|
||||||
|
* pick_next_task()
|
||||||
|
* rq_unlock()
|
||||||
|
* rq_lock()
|
||||||
|
* psi_task_change() // old cgroup
|
||||||
|
* task->cgroups = to
|
||||||
|
* psi_task_change() // new cgroup
|
||||||
|
* rq_unlock()
|
||||||
|
* rq_lock()
|
||||||
|
* psi_sched_switch() // does deferred updates in new cgroup
|
||||||
|
*
|
||||||
|
* Don't rely on the scheduling state. Use psi_flags instead.
|
||||||
|
*/
|
||||||
|
task_flags = task->psi_flags;
|
||||||
|
|
||||||
if (task_flags)
|
if (task_flags)
|
||||||
psi_task_change(task, task_flags, 0);
|
psi_task_change(task, task_flags, 0);
|
||||||
|
@@ -1481,7 +1481,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
|
|||||||
*/
|
*/
|
||||||
get_page(page);
|
get_page(page);
|
||||||
spin_unlock(vmf->ptl);
|
spin_unlock(vmf->ptl);
|
||||||
anon_vma = page_lock_anon_vma_read(page);
|
anon_vma = page_lock_anon_vma_read(page, NULL);
|
||||||
|
|
||||||
/* Confirm the PMD did not change while page_table_lock was released */
|
/* Confirm the PMD did not change while page_table_lock was released */
|
||||||
spin_lock(vmf->ptl);
|
spin_lock(vmf->ptl);
|
||||||
|
6
mm/ksm.c
6
mm/ksm.c
@@ -2626,7 +2626,13 @@ again:
|
|||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
|
|
||||||
cond_resched();
|
cond_resched();
|
||||||
|
if (!anon_vma_trylock_read(anon_vma)) {
|
||||||
|
if (rwc->try_lock) {
|
||||||
|
rwc->contended = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
anon_vma_lock_read(anon_vma);
|
anon_vma_lock_read(anon_vma);
|
||||||
|
}
|
||||||
anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
|
anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
|
||||||
0, ULONG_MAX) {
|
0, ULONG_MAX) {
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
@@ -477,7 +477,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
|
|||||||
struct anon_vma *av;
|
struct anon_vma *av;
|
||||||
pgoff_t pgoff;
|
pgoff_t pgoff;
|
||||||
|
|
||||||
av = page_lock_anon_vma_read(page);
|
av = page_lock_anon_vma_read(page, NULL);
|
||||||
if (av == NULL) /* Not actually mapped anymore */
|
if (av == NULL) /* Not actually mapped anymore */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -4777,6 +4777,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
|
|||||||
if (vmf->flags & FAULT_FLAG_WRITE)
|
if (vmf->flags & FAULT_FLAG_WRITE)
|
||||||
flush_tlb_fix_spurious_fault(vmf->vma, vmf->address);
|
flush_tlb_fix_spurious_fault(vmf->vma, vmf->address);
|
||||||
}
|
}
|
||||||
|
trace_android_rvh_handle_pte_fault_end(vmf, highest_memmap_pfn);
|
||||||
trace_android_vh_handle_pte_fault_end(vmf, highest_memmap_pfn);
|
trace_android_vh_handle_pte_fault_end(vmf, highest_memmap_pfn);
|
||||||
unlock:
|
unlock:
|
||||||
pte_unmap_unlock(vmf->pte, vmf->ptl);
|
pte_unmap_unlock(vmf->pte, vmf->ptl);
|
||||||
|
@@ -92,10 +92,10 @@ static bool page_idle_clear_pte_refs_one(struct page *page,
|
|||||||
static void page_idle_clear_pte_refs(struct page *page)
|
static void page_idle_clear_pte_refs(struct page *page)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Since rwc.arg is unused, rwc is effectively immutable, so we
|
* Since rwc.try_lock is unused, rwc is effectively immutable, so we
|
||||||
* can make it static const to save some cycles and stack.
|
* can make it static to save some cycles and stack.
|
||||||
*/
|
*/
|
||||||
static const struct rmap_walk_control rwc = {
|
static struct rmap_walk_control rwc = {
|
||||||
.rmap_one = page_idle_clear_pte_refs_one,
|
.rmap_one = page_idle_clear_pte_refs_one,
|
||||||
.anon_lock = page_lock_anon_vma_read,
|
.anon_lock = page_lock_anon_vma_read,
|
||||||
};
|
};
|
||||||
|
43
mm/rmap.c
43
mm/rmap.c
@@ -518,9 +518,11 @@ out:
|
|||||||
*
|
*
|
||||||
* Its a little more complex as it tries to keep the fast path to a single
|
* Its a little more complex as it tries to keep the fast path to a single
|
||||||
* atomic op -- the trylock. If we fail the trylock, we fall back to getting a
|
* atomic op -- the trylock. If we fail the trylock, we fall back to getting a
|
||||||
* reference like with page_get_anon_vma() and then block on the mutex.
|
* reference like with page_get_anon_vma() and then block on the mutex
|
||||||
|
* on !rwc->try_lock case.
|
||||||
*/
|
*/
|
||||||
struct anon_vma *page_lock_anon_vma_read(struct page *page)
|
struct anon_vma *page_lock_anon_vma_read(struct page *page,
|
||||||
|
struct rmap_walk_control *rwc)
|
||||||
{
|
{
|
||||||
struct anon_vma *anon_vma = NULL;
|
struct anon_vma *anon_vma = NULL;
|
||||||
struct anon_vma *root_anon_vma;
|
struct anon_vma *root_anon_vma;
|
||||||
@@ -553,6 +555,13 @@ struct anon_vma *page_lock_anon_vma_read(struct page *page)
|
|||||||
anon_vma = NULL;
|
anon_vma = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rwc && rwc->try_lock) {
|
||||||
|
anon_vma = NULL;
|
||||||
|
rwc->contended = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* trylock failed, we got to sleep */
|
/* trylock failed, we got to sleep */
|
||||||
if (!atomic_inc_not_zero(&anon_vma->refcount)) {
|
if (!atomic_inc_not_zero(&anon_vma->refcount)) {
|
||||||
anon_vma = NULL;
|
anon_vma = NULL;
|
||||||
@@ -850,8 +859,10 @@ static bool invalid_page_referenced_vma(struct vm_area_struct *vma, void *arg)
|
|||||||
* @memcg: target memory cgroup
|
* @memcg: target memory cgroup
|
||||||
* @vm_flags: collect encountered vma->vm_flags who actually referenced the page
|
* @vm_flags: collect encountered vma->vm_flags who actually referenced the page
|
||||||
*
|
*
|
||||||
* Quick test_and_clear_referenced for all mappings to a page,
|
* Quick test_and_clear_referenced for all mappings of a page,
|
||||||
* returns the number of ptes which referenced the page.
|
*
|
||||||
|
* Return: The number of mappings which referenced the page. Return -1 if
|
||||||
|
* the function bailed out due to rmap lock contention.
|
||||||
*/
|
*/
|
||||||
int page_referenced(struct page *page,
|
int page_referenced(struct page *page,
|
||||||
int is_locked,
|
int is_locked,
|
||||||
@@ -867,6 +878,7 @@ int page_referenced(struct page *page,
|
|||||||
.rmap_one = page_referenced_one,
|
.rmap_one = page_referenced_one,
|
||||||
.arg = (void *)&pra,
|
.arg = (void *)&pra,
|
||||||
.anon_lock = page_lock_anon_vma_read,
|
.anon_lock = page_lock_anon_vma_read,
|
||||||
|
.try_lock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
*vm_flags = 0;
|
*vm_flags = 0;
|
||||||
@@ -897,7 +909,7 @@ int page_referenced(struct page *page,
|
|||||||
if (we_locked)
|
if (we_locked)
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
|
|
||||||
return pra.referenced;
|
return rwc.contended ? -1 : pra.referenced;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma,
|
static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma,
|
||||||
@@ -1898,7 +1910,7 @@ static struct anon_vma *rmap_walk_anon_lock(struct page *page,
|
|||||||
struct anon_vma *anon_vma;
|
struct anon_vma *anon_vma;
|
||||||
|
|
||||||
if (rwc->anon_lock)
|
if (rwc->anon_lock)
|
||||||
return rwc->anon_lock(page);
|
return rwc->anon_lock(page, rwc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: remove_migration_ptes() cannot use page_lock_anon_vma_read()
|
* Note: remove_migration_ptes() cannot use page_lock_anon_vma_read()
|
||||||
@@ -1910,7 +1922,17 @@ static struct anon_vma *rmap_walk_anon_lock(struct page *page,
|
|||||||
if (!anon_vma)
|
if (!anon_vma)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (anon_vma_trylock_read(anon_vma))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (rwc->try_lock) {
|
||||||
|
anon_vma = NULL;
|
||||||
|
rwc->contended = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
anon_vma_lock_read(anon_vma);
|
anon_vma_lock_read(anon_vma);
|
||||||
|
out:
|
||||||
return anon_vma;
|
return anon_vma;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2009,9 +2031,18 @@ static void rmap_walk_file(struct page *page, struct rmap_walk_control *rwc,
|
|||||||
if (!got_lock)
|
if (!got_lock)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
if (i_mmap_trylock_read(mapping))
|
||||||
|
goto lookup;
|
||||||
|
|
||||||
|
if (rwc->try_lock) {
|
||||||
|
rwc->contended = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
i_mmap_lock_read(mapping);
|
i_mmap_lock_read(mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lookup:
|
||||||
vma_interval_tree_foreach(vma, &mapping->i_mmap,
|
vma_interval_tree_foreach(vma, &mapping->i_mmap,
|
||||||
pgoff_start, pgoff_end) {
|
pgoff_start, pgoff_end) {
|
||||||
unsigned long address = vma_address(page, vma);
|
unsigned long address = vma_address(page, vma);
|
||||||
|
@@ -133,6 +133,8 @@ static int alloc_swap_slot_cache(unsigned int cpu)
|
|||||||
* as kvzalloc could trigger reclaim and get_swap_page,
|
* as kvzalloc could trigger reclaim and get_swap_page,
|
||||||
* which can lock swap_slots_cache_mutex.
|
* which can lock swap_slots_cache_mutex.
|
||||||
*/
|
*/
|
||||||
|
trace_android_rvh_alloc_swap_slot_cache(&per_cpu(swp_slots, cpu),
|
||||||
|
&ret, &skip);
|
||||||
trace_android_vh_alloc_swap_slot_cache(&per_cpu(swp_slots, cpu),
|
trace_android_vh_alloc_swap_slot_cache(&per_cpu(swp_slots, cpu),
|
||||||
&ret, &skip);
|
&ret, &skip);
|
||||||
if (skip)
|
if (skip)
|
||||||
@@ -190,6 +192,8 @@ static void drain_slots_cache_cpu(unsigned int cpu, unsigned int type,
|
|||||||
bool skip = false;
|
bool skip = false;
|
||||||
|
|
||||||
cache = &per_cpu(swp_slots, cpu);
|
cache = &per_cpu(swp_slots, cpu);
|
||||||
|
trace_android_rvh_drain_slots_cache_cpu(cache, type,
|
||||||
|
free_slots, &skip);
|
||||||
trace_android_vh_drain_slots_cache_cpu(cache, type,
|
trace_android_vh_drain_slots_cache_cpu(cache, type,
|
||||||
free_slots, &skip);
|
free_slots, &skip);
|
||||||
if (skip)
|
if (skip)
|
||||||
@@ -298,6 +302,7 @@ int free_swap_slot(swp_entry_t entry)
|
|||||||
bool skip = false;
|
bool skip = false;
|
||||||
|
|
||||||
cache = raw_cpu_ptr(&swp_slots);
|
cache = raw_cpu_ptr(&swp_slots);
|
||||||
|
trace_android_rvh_free_swap_slot(entry, cache, &skip);
|
||||||
trace_android_vh_free_swap_slot(entry, cache, &skip);
|
trace_android_vh_free_swap_slot(entry, cache, &skip);
|
||||||
if (skip)
|
if (skip)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -335,6 +340,7 @@ swp_entry_t get_swap_page(struct page *page)
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
entry.val = 0;
|
entry.val = 0;
|
||||||
|
|
||||||
|
trace_android_rvh_get_swap_page(page, &entry, raw_cpu_ptr(&swp_slots), &found);
|
||||||
trace_android_vh_get_swap_page(page, &entry, raw_cpu_ptr(&swp_slots), &found);
|
trace_android_vh_get_swap_page(page, &entry, raw_cpu_ptr(&swp_slots), &found);
|
||||||
if (found)
|
if (found)
|
||||||
goto out;
|
goto out;
|
||||||
|
@@ -2908,6 +2908,7 @@ static struct swap_info_struct *alloc_swap_info(void)
|
|||||||
int i;
|
int i;
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
|
|
||||||
|
trace_android_rvh_alloc_si(&p, &skip);
|
||||||
trace_android_vh_alloc_si(&p, &skip);
|
trace_android_vh_alloc_si(&p, &skip);
|
||||||
if (!skip)
|
if (!skip)
|
||||||
p = kvzalloc(struct_size(p, avail_lists, nr_node_ids), GFP_KERNEL);
|
p = kvzalloc(struct_size(p, avail_lists, nr_node_ids), GFP_KERNEL);
|
||||||
|
@@ -1045,6 +1045,10 @@ static enum page_references page_check_references(struct page *page,
|
|||||||
if (vm_flags & VM_LOCKED)
|
if (vm_flags & VM_LOCKED)
|
||||||
return PAGEREF_RECLAIM;
|
return PAGEREF_RECLAIM;
|
||||||
|
|
||||||
|
/* rmap lock contention: rotate */
|
||||||
|
if (referenced_ptes == -1)
|
||||||
|
return PAGEREF_KEEP;
|
||||||
|
|
||||||
if (referenced_ptes) {
|
if (referenced_ptes) {
|
||||||
/*
|
/*
|
||||||
* All mapped pages start out with page table
|
* All mapped pages start out with page table
|
||||||
@@ -1348,7 +1352,7 @@ static unsigned int shrink_page_list(struct list_head *page_list,
|
|||||||
|
|
||||||
if (unlikely(PageTransHuge(page)))
|
if (unlikely(PageTransHuge(page)))
|
||||||
flags |= TTU_SPLIT_HUGE_PMD;
|
flags |= TTU_SPLIT_HUGE_PMD;
|
||||||
|
if (!ignore_references)
|
||||||
trace_android_vh_page_trylock_set(page);
|
trace_android_vh_page_trylock_set(page);
|
||||||
if (!try_to_unmap(page, flags)) {
|
if (!try_to_unmap(page, flags)) {
|
||||||
stat->nr_unmap_fail += nr_pages;
|
stat->nr_unmap_fail += nr_pages;
|
||||||
@@ -2119,8 +2123,9 @@ static void shrink_active_list(unsigned long nr_to_scan,
|
|||||||
if (bypass)
|
if (bypass)
|
||||||
goto skip_page_referenced;
|
goto skip_page_referenced;
|
||||||
trace_android_vh_page_trylock_set(page);
|
trace_android_vh_page_trylock_set(page);
|
||||||
|
/* Referenced or rmap lock contention: rotate */
|
||||||
if (page_referenced(page, 0, sc->target_mem_cgroup,
|
if (page_referenced(page, 0, sc->target_mem_cgroup,
|
||||||
&vm_flags)) {
|
&vm_flags) != 0) {
|
||||||
/*
|
/*
|
||||||
* Identify referenced, file-backed active pages and
|
* Identify referenced, file-backed active pages and
|
||||||
* give them one more trip around the active list. So
|
* give them one more trip around the active list. So
|
||||||
|
Reference in New Issue
Block a user