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
|
||||
finish_wait
|
||||
firmware_request_nowarn
|
||||
fixed_phy_register
|
||||
fixed_phy_unregister
|
||||
fixed_size_llseek
|
||||
flow_keys_basic_dissector
|
||||
flush_dcache_page
|
||||
@@ -2327,6 +2329,7 @@
|
||||
irq_create_mapping_affinity
|
||||
irq_create_of_mapping
|
||||
irq_dispose_mapping
|
||||
irq_domain_add_simple
|
||||
irq_domain_alloc_irqs_parent
|
||||
irq_domain_create_hierarchy
|
||||
irq_domain_free_irqs_common
|
||||
@@ -3023,6 +3026,7 @@
|
||||
phy_ethtool_get_link_ksettings
|
||||
phy_ethtool_nway_reset
|
||||
phy_ethtool_set_link_ksettings
|
||||
phy_ethtool_set_wol
|
||||
phy_exit
|
||||
phy_find_first
|
||||
phy_get_pause
|
||||
@@ -3034,9 +3038,12 @@
|
||||
phy_power_off
|
||||
phy_power_on
|
||||
phy_print_status
|
||||
phy_register_fixup_for_uid
|
||||
phy_save_page
|
||||
phy_set_mode_ext
|
||||
phy_start
|
||||
phy_stop
|
||||
phy_unregister_fixup_for_uid
|
||||
pick_highest_pushable_task
|
||||
pid_nr_ns
|
||||
pid_task
|
||||
@@ -4066,6 +4073,7 @@
|
||||
ttm_tt_populate
|
||||
ttm_tt_set_placement_caching
|
||||
ttm_unmap_and_unpopulate_pages
|
||||
tty_encode_baud_rate
|
||||
tty_flip_buffer_push
|
||||
tty_insert_flip_string_fixed_flag
|
||||
tty_kref_put
|
||||
@@ -4214,8 +4222,10 @@
|
||||
usb_asmedia_modifyflowcontrol
|
||||
usb_assign_descriptors
|
||||
usb_autopm_get_interface
|
||||
usb_autopm_get_interface_async
|
||||
usb_autopm_get_interface_no_resume
|
||||
usb_autopm_put_interface
|
||||
usb_autopm_put_interface_async
|
||||
usb_bulk_msg
|
||||
usb_calc_bus_time
|
||||
usb_choose_configuration
|
||||
@@ -4293,6 +4303,7 @@
|
||||
usb_ifnum_to_if
|
||||
usb_initialize_gadget
|
||||
usb_interface_id
|
||||
usb_interrupt_msg
|
||||
usb_kill_urb
|
||||
usb_match_id
|
||||
usb_match_one_id
|
||||
|
@@ -3216,6 +3216,7 @@
|
||||
update_devfreq
|
||||
usb_add_phy_dev
|
||||
usb_assign_descriptors
|
||||
usb_clear_halt
|
||||
usb_copy_descriptors
|
||||
usb_ep_alloc_request
|
||||
usb_ep_autoconfig
|
||||
@@ -3239,6 +3240,7 @@
|
||||
usb_phy_set_charger_current
|
||||
usb_remove_phy
|
||||
usb_role_switch_set_role
|
||||
usb_unlink_urb
|
||||
v4l2_async_notifier_add_subdev
|
||||
v4l2_async_notifier_cleanup
|
||||
v4l2_async_subdev_notifier_register
|
||||
|
@@ -408,6 +408,7 @@
|
||||
dev_fwnode
|
||||
__dev_get_by_index
|
||||
dev_get_by_index
|
||||
dev_get_by_index_rcu
|
||||
dev_get_by_name
|
||||
dev_get_regmap
|
||||
dev_get_stats
|
||||
@@ -1658,7 +1659,9 @@
|
||||
net_ratelimit
|
||||
nf_ct_attach
|
||||
nf_ct_delete
|
||||
nf_register_net_hook
|
||||
nf_register_net_hooks
|
||||
nf_unregister_net_hook
|
||||
nf_unregister_net_hooks
|
||||
nla_find
|
||||
nla_memcpy
|
||||
@@ -2286,6 +2289,7 @@
|
||||
rtc_update_irq
|
||||
rtc_valid_tm
|
||||
rtnl_is_locked
|
||||
__rtnl_link_unregister
|
||||
rtnl_lock
|
||||
rtnl_unlock
|
||||
runqueues
|
||||
|
@@ -2626,6 +2626,7 @@
|
||||
snd_pcm_fill_iec958_consumer
|
||||
snd_pcm_fill_iec958_consumer_hw_params
|
||||
snd_pcm_hw_constraint_eld
|
||||
snd_pcm_stop_xrun
|
||||
|
||||
# required by snd-soc-rk817.ko
|
||||
snd_soc_component_exit_regmap
|
||||
|
@@ -10,6 +10,7 @@
|
||||
nr_swap_pages
|
||||
plist_requeue
|
||||
plist_del
|
||||
__traceiter_android_rvh_handle_pte_fault_end
|
||||
__traceiter_android_vh_handle_pte_fault_end
|
||||
__traceiter_android_vh_cow_user_page
|
||||
__traceiter_android_vh_swapin_add_anon_rmap
|
||||
@@ -20,9 +21,13 @@
|
||||
__traceiter_android_vh_count_pswpout
|
||||
__traceiter_android_vh_count_swpout_vm_event
|
||||
__traceiter_android_vh_swap_slot_cache_active
|
||||
__traceiter_android_rvh_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_rvh_free_swap_slot
|
||||
__traceiter_android_vh_free_swap_slot
|
||||
__traceiter_android_rvh_get_swap_page
|
||||
__traceiter_android_vh_get_swap_page
|
||||
__traceiter_android_vh_page_isolated_for_reclaim
|
||||
__traceiter_android_vh_inactive_is_low
|
||||
@@ -31,10 +36,12 @@
|
||||
__traceiter_android_vh_unuse_swap_page
|
||||
__traceiter_android_vh_init_swap_info_struct
|
||||
__traceiter_android_vh_si_swapinfo
|
||||
__traceiter_android_rvh_alloc_si
|
||||
__traceiter_android_vh_alloc_si
|
||||
__traceiter_android_vh_free_pages
|
||||
__traceiter_android_vh_set_shmem_page_flag
|
||||
__traceiter_android_vh_ra_tuning_max_page
|
||||
__tracepoint_android_rvh_handle_pte_fault_end
|
||||
__tracepoint_android_vh_handle_pte_fault_end
|
||||
__tracepoint_android_vh_cow_user_page
|
||||
__tracepoint_android_vh_swapin_add_anon_rmap
|
||||
@@ -45,9 +52,13 @@
|
||||
__tracepoint_android_vh_count_pswpout
|
||||
__tracepoint_android_vh_count_swpout_vm_event
|
||||
__tracepoint_android_vh_swap_slot_cache_active
|
||||
__tracepoint_android_rvh_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_rvh_free_swap_slot
|
||||
__tracepoint_android_vh_free_swap_slot
|
||||
__tracepoint_android_rvh_get_swap_page
|
||||
__tracepoint_android_vh_get_swap_page
|
||||
__tracepoint_android_vh_page_isolated_for_reclaim
|
||||
__tracepoint_android_vh_inactive_is_low
|
||||
@@ -56,6 +67,7 @@
|
||||
__tracepoint_android_vh_unuse_swap_page
|
||||
__tracepoint_android_vh_init_swap_info_struct
|
||||
__tracepoint_android_vh_si_swapinfo
|
||||
__tracepoint_android_rvh_alloc_si
|
||||
__tracepoint_android_vh_alloc_si
|
||||
__tracepoint_android_vh_free_pages
|
||||
__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_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"
|
||||
|
||||
/***************************************************************************
|
||||
@@ -546,7 +562,10 @@ static int jent_measure_jitter(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 */
|
||||
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
|
||||
* oversampling rate requested by the caller
|
||||
*/
|
||||
if (++k >= (DATA_SIZE_BITS * ec->osr))
|
||||
if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr))
|
||||
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_shrink_node_memcgs);
|
||||
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_cow_user_page);
|
||||
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_swpout_vm_event);
|
||||
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_rvh_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_rvh_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_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_init_swap_info_struct);
|
||||
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_free_pages);
|
||||
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)
|
||||
{
|
||||
struct firmware *fw = NULL;
|
||||
struct cred *kern_cred = NULL;
|
||||
const struct cred *old_cred;
|
||||
bool nondirect = false;
|
||||
int ret;
|
||||
|
||||
@@ -811,18 +809,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
if (ret <= 0) /* error or already assigned */
|
||||
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);
|
||||
|
||||
/* Only full reads can support decompression, platform, and sysfs. */
|
||||
@@ -848,9 +834,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
} else
|
||||
ret = assign_fw(fw, device);
|
||||
|
||||
revert_creds(old_cred);
|
||||
put_cred(kern_cred);
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
fw_abort_batch_reqs(fw);
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include <linux/printk.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "dma-buf-sysfs-stats.h"
|
||||
|
||||
@@ -135,10 +136,51 @@ void dma_buf_uninit_sysfs_statistics(void)
|
||||
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)
|
||||
{
|
||||
struct dma_buf_sysfs_entry *sysfs_entry;
|
||||
int ret;
|
||||
struct work_struct *work;
|
||||
|
||||
if (!dmabuf || !dmabuf->file)
|
||||
return -EINVAL;
|
||||
@@ -148,25 +190,21 @@ int dma_buf_stats_setup(struct dma_buf *dmabuf)
|
||||
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)
|
||||
return -ENOMEM;
|
||||
|
||||
sysfs_entry->kobj.kset = dma_buf_per_buffer_stats_kset;
|
||||
sysfs_entry->dmabuf = dmabuf;
|
||||
|
||||
dmabuf->sysfs_entry = sysfs_entry;
|
||||
|
||||
/* create the directory for buffer stats */
|
||||
ret = kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_ktype, NULL,
|
||||
"%lu", file_inode(dmabuf->file)->i_ino);
|
||||
if (ret)
|
||||
goto err_sysfs_dmabuf;
|
||||
/*
|
||||
* The use of kobj as a work_struct is an ugly hack
|
||||
* to avoid an ABI break in this frozen kernel.
|
||||
*/
|
||||
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;
|
||||
|
||||
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 atomic64_t dmabuf_inode = ATOMIC64_INIT(0);
|
||||
struct file *file;
|
||||
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_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",
|
||||
flags, &dma_buf_fops);
|
||||
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;
|
||||
dmabuf->file = file;
|
||||
|
||||
ret = dma_buf_stats_setup(dmabuf);
|
||||
if (ret)
|
||||
goto err_sysfs;
|
||||
|
||||
mutex_init(&dmabuf->lock);
|
||||
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);
|
||||
mutex_unlock(&db_list.lock);
|
||||
|
||||
ret = dma_buf_stats_setup(dmabuf);
|
||||
if (ret)
|
||||
goto err_sysfs;
|
||||
|
||||
return dmabuf;
|
||||
|
||||
err_sysfs:
|
||||
|
@@ -25,12 +25,16 @@
|
||||
static struct kmem_cache *ino_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);
|
||||
set_ckpt_flags(sbi, CP_ERROR_FLAG);
|
||||
if (!end_io)
|
||||
if (!end_io) {
|
||||
f2fs_flush_merged_writes(sbi);
|
||||
|
||||
f2fs_handle_stop(sbi, reason);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -120,7 +124,7 @@ retry:
|
||||
if (PTR_ERR(page) == -EIO &&
|
||||
++count <= DEFAULT_RETRY_IO_COUNT)
|
||||
goto retry;
|
||||
f2fs_stop_checkpoint(sbi, false);
|
||||
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
@@ -311,7 +311,8 @@ static void f2fs_write_end_io(struct bio *bio)
|
||||
mempool_free(page, sbi->write_io_dummy);
|
||||
|
||||
if (unlikely(bio->bi_status))
|
||||
f2fs_stop_checkpoint(sbi, true);
|
||||
f2fs_stop_checkpoint(sbi, true,
|
||||
STOP_CP_REASON_WRITE_FAIL);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -327,7 +328,8 @@ static void f2fs_write_end_io(struct bio *bio)
|
||||
if (unlikely(bio->bi_status)) {
|
||||
mapping_set_error(page->mapping, -EIO);
|
||||
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) &&
|
||||
|
@@ -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);
|
||||
loff_t max_file_blocks(struct inode *inode);
|
||||
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_sync_fs(struct super_block *sb, int sync);
|
||||
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
|
||||
*/
|
||||
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);
|
||||
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);
|
||||
|
@@ -2249,7 +2249,8 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
||||
if (ret) {
|
||||
if (ret == -EROFS) {
|
||||
ret = 0;
|
||||
f2fs_stop_checkpoint(sbi, false);
|
||||
f2fs_stop_checkpoint(sbi, false,
|
||||
STOP_CP_REASON_SHUTDOWN);
|
||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||
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);
|
||||
if (ret)
|
||||
goto out;
|
||||
f2fs_stop_checkpoint(sbi, false);
|
||||
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
|
||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||
thaw_bdev(sb->s_bdev);
|
||||
break;
|
||||
@@ -2271,16 +2272,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
|
||||
ret = f2fs_sync_fs(sb, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
f2fs_stop_checkpoint(sbi, false);
|
||||
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
|
||||
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
case F2FS_GOING_DOWN_METAFLUSH:
|
||||
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);
|
||||
break;
|
||||
case F2FS_GOING_DOWN_NEED_FSCK:
|
||||
|
@@ -68,7 +68,8 @@ static int gc_thread_func(void *data)
|
||||
|
||||
if (time_to_inject(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)) {
|
||||
@@ -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",
|
||||
segno, type, GET_SUM_TYPE((&sum->footer)));
|
||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||
f2fs_stop_checkpoint(sbi, false);
|
||||
f2fs_stop_checkpoint(sbi, false,
|
||||
STOP_CP_REASON_CORRUPTED_SUMMARY);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
|
@@ -685,7 +685,8 @@ retry:
|
||||
cond_resched();
|
||||
goto retry;
|
||||
} else if (err != -ENOENT) {
|
||||
f2fs_stop_checkpoint(sbi, false);
|
||||
f2fs_stop_checkpoint(sbi, false,
|
||||
STOP_CP_REASON_UPDATE_INODE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@@ -499,7 +499,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
|
||||
{
|
||||
if (time_to_inject(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 */
|
||||
@@ -782,8 +782,11 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi)
|
||||
if (!f2fs_test_bit(i, (char *)&sbi->dirty_device))
|
||||
continue;
|
||||
ret = __submit_flush_wait(sbi, FDEV(i).bdev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
f2fs_stop_checkpoint(sbi, false,
|
||||
STOP_CP_REASON_FLUSH_FAIL);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock(&sbi->dev_lock);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
|
||||
|
@@ -73,6 +73,20 @@ struct f2fs_device {
|
||||
__le32 total_segments;
|
||||
} __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 {
|
||||
__le32 magic; /* Magic Number */
|
||||
__le16 major_ver; /* Major Version */
|
||||
@@ -116,7 +130,8 @@ struct f2fs_super_block {
|
||||
__u8 hot_ext_count; /* # of hot file extension */
|
||||
__le16 s_encoding; /* Filename charset encoding */
|
||||
__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 */
|
||||
} __packed;
|
||||
|
||||
|
@@ -515,6 +515,11 @@ static inline void i_mmap_unlock_write(struct address_space *mapping)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* rmap_walk_control: To control rmap traversing for specific needs
|
||||
*
|
||||
* 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
|
||||
* done: for checking traversing termination condition
|
||||
* 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 {
|
||||
void *arg;
|
||||
bool try_lock;
|
||||
bool contended;
|
||||
/*
|
||||
* Return false if page table scanning in rmap_walk should be stopped.
|
||||
* Otherwise, return true.
|
||||
@@ -286,13 +290,21 @@ struct rmap_walk_control {
|
||||
bool (*rmap_one)(struct page *page, struct vm_area_struct *vma,
|
||||
unsigned long addr, void *arg);
|
||||
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);
|
||||
};
|
||||
|
||||
void rmap_walk(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 */
|
||||
|
||||
#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,
|
||||
TP_PROTO(struct readahead_control *ractl, unsigned long *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,
|
||||
TP_PROTO(struct vm_fault *vmf, unsigned long 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,
|
||||
TP_PROTO(bool 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,
|
||||
TP_PROTO(struct swap_slots_cache *cache, unsigned int type,
|
||||
bool free_slots, bool *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,
|
||||
TP_PROTO(struct swap_slots_cache *cache, int *ret, bool *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,
|
||||
TP_PROTO(swp_entry_t entry, struct swap_slots_cache *cache, bool *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,
|
||||
TP_PROTO(struct page *page, swp_entry_t *entry,
|
||||
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,
|
||||
TP_PROTO(struct swap_info_struct *si, bool *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,
|
||||
TP_PROTO(struct swap_info_struct **p, bool *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. */
|
||||
static int random_and_perf_prepare_fusion(unsigned int cpu)
|
||||
{
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
perf_event_init_cpu(cpu);
|
||||
#endif
|
||||
random_prepare_cpu(cpu);
|
||||
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)
|
||||
{
|
||||
unsigned int task_flags = 0;
|
||||
unsigned int task_flags;
|
||||
struct rq_flags rf;
|
||||
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);
|
||||
|
||||
if (task_on_rq_queued(task)) {
|
||||
task_flags = TSK_RUNNING;
|
||||
if (task_current(rq, task))
|
||||
task_flags |= TSK_ONCPU;
|
||||
} else if (task->in_iowait)
|
||||
task_flags = TSK_IOWAIT;
|
||||
|
||||
if (task->in_memstall)
|
||||
task_flags |= TSK_MEMSTALL;
|
||||
/*
|
||||
* We may race with schedule() dropping the rq lock between
|
||||
* deactivating prev and switching to next. Because the psi
|
||||
* updates from the deactivation are deferred to the switch
|
||||
* callback to save cgroup tree updates, the task's scheduling
|
||||
* state here is not coherent with its psi state:
|
||||
*
|
||||
* schedule() cgroup_move_task()
|
||||
* 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)
|
||||
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);
|
||||
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 */
|
||||
spin_lock(vmf->ptl);
|
||||
|
8
mm/ksm.c
8
mm/ksm.c
@@ -2626,7 +2626,13 @@ again:
|
||||
struct vm_area_struct *vma;
|
||||
|
||||
cond_resched();
|
||||
anon_vma_lock_read(anon_vma);
|
||||
if (!anon_vma_trylock_read(anon_vma)) {
|
||||
if (rwc->try_lock) {
|
||||
rwc->contended = true;
|
||||
return;
|
||||
}
|
||||
anon_vma_lock_read(anon_vma);
|
||||
}
|
||||
anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
|
||||
0, ULONG_MAX) {
|
||||
unsigned long addr;
|
||||
|
@@ -477,7 +477,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
|
||||
struct anon_vma *av;
|
||||
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 */
|
||||
return;
|
||||
|
||||
|
@@ -4777,6 +4777,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
|
||||
if (vmf->flags & FAULT_FLAG_WRITE)
|
||||
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);
|
||||
unlock:
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* Since rwc.arg is unused, rwc is effectively immutable, so we
|
||||
* can make it static const to save some cycles and stack.
|
||||
* Since rwc.try_lock is unused, rwc is effectively immutable, so we
|
||||
* 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,
|
||||
.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
|
||||
* 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 *root_anon_vma;
|
||||
@@ -553,6 +555,13 @@ struct anon_vma *page_lock_anon_vma_read(struct page *page)
|
||||
anon_vma = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rwc && rwc->try_lock) {
|
||||
anon_vma = NULL;
|
||||
rwc->contended = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* trylock failed, we got to sleep */
|
||||
if (!atomic_inc_not_zero(&anon_vma->refcount)) {
|
||||
anon_vma = NULL;
|
||||
@@ -850,8 +859,10 @@ static bool invalid_page_referenced_vma(struct vm_area_struct *vma, void *arg)
|
||||
* @memcg: target memory cgroup
|
||||
* @vm_flags: collect encountered vma->vm_flags who actually referenced the page
|
||||
*
|
||||
* Quick test_and_clear_referenced for all mappings to a page,
|
||||
* returns the number of ptes which referenced the page.
|
||||
* Quick test_and_clear_referenced for all mappings of a 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 is_locked,
|
||||
@@ -867,6 +878,7 @@ int page_referenced(struct page *page,
|
||||
.rmap_one = page_referenced_one,
|
||||
.arg = (void *)&pra,
|
||||
.anon_lock = page_lock_anon_vma_read,
|
||||
.try_lock = true,
|
||||
};
|
||||
|
||||
*vm_flags = 0;
|
||||
@@ -897,7 +909,7 @@ int page_referenced(struct page *page,
|
||||
if (we_locked)
|
||||
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,
|
||||
@@ -1898,7 +1910,7 @@ static struct anon_vma *rmap_walk_anon_lock(struct page *page,
|
||||
struct anon_vma *anon_vma;
|
||||
|
||||
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()
|
||||
@@ -1910,7 +1922,17 @@ static struct anon_vma *rmap_walk_anon_lock(struct page *page,
|
||||
if (!anon_vma)
|
||||
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);
|
||||
out:
|
||||
return anon_vma;
|
||||
}
|
||||
|
||||
@@ -2009,9 +2031,18 @@ static void rmap_walk_file(struct page *page, struct rmap_walk_control *rwc,
|
||||
if (!got_lock)
|
||||
return;
|
||||
} else {
|
||||
if (i_mmap_trylock_read(mapping))
|
||||
goto lookup;
|
||||
|
||||
if (rwc->try_lock) {
|
||||
rwc->contended = true;
|
||||
return;
|
||||
}
|
||||
|
||||
i_mmap_lock_read(mapping);
|
||||
}
|
||||
}
|
||||
lookup:
|
||||
vma_interval_tree_foreach(vma, &mapping->i_mmap,
|
||||
pgoff_start, pgoff_end) {
|
||||
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,
|
||||
* 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),
|
||||
&ret, &skip);
|
||||
if (skip)
|
||||
@@ -190,6 +192,8 @@ static void drain_slots_cache_cpu(unsigned int cpu, unsigned int type,
|
||||
bool skip = false;
|
||||
|
||||
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,
|
||||
free_slots, &skip);
|
||||
if (skip)
|
||||
@@ -298,6 +302,7 @@ int free_swap_slot(swp_entry_t entry)
|
||||
bool skip = false;
|
||||
|
||||
cache = raw_cpu_ptr(&swp_slots);
|
||||
trace_android_rvh_free_swap_slot(entry, cache, &skip);
|
||||
trace_android_vh_free_swap_slot(entry, cache, &skip);
|
||||
if (skip)
|
||||
return 0;
|
||||
@@ -335,6 +340,7 @@ swp_entry_t get_swap_page(struct page *page)
|
||||
bool found = false;
|
||||
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);
|
||||
if (found)
|
||||
goto out;
|
||||
|
@@ -2908,6 +2908,7 @@ static struct swap_info_struct *alloc_swap_info(void)
|
||||
int i;
|
||||
bool skip = false;
|
||||
|
||||
trace_android_rvh_alloc_si(&p, &skip);
|
||||
trace_android_vh_alloc_si(&p, &skip);
|
||||
if (!skip)
|
||||
p = kvzalloc(struct_size(p, avail_lists, nr_node_ids), GFP_KERNEL);
|
||||
|
11
mm/vmscan.c
11
mm/vmscan.c
@@ -1045,6 +1045,10 @@ static enum page_references page_check_references(struct page *page,
|
||||
if (vm_flags & VM_LOCKED)
|
||||
return PAGEREF_RECLAIM;
|
||||
|
||||
/* rmap lock contention: rotate */
|
||||
if (referenced_ptes == -1)
|
||||
return PAGEREF_KEEP;
|
||||
|
||||
if (referenced_ptes) {
|
||||
/*
|
||||
* All mapped pages start out with page table
|
||||
@@ -1348,8 +1352,8 @@ static unsigned int shrink_page_list(struct list_head *page_list,
|
||||
|
||||
if (unlikely(PageTransHuge(page)))
|
||||
flags |= TTU_SPLIT_HUGE_PMD;
|
||||
|
||||
trace_android_vh_page_trylock_set(page);
|
||||
if (!ignore_references)
|
||||
trace_android_vh_page_trylock_set(page);
|
||||
if (!try_to_unmap(page, flags)) {
|
||||
stat->nr_unmap_fail += nr_pages;
|
||||
if (!was_swapbacked && PageSwapBacked(page))
|
||||
@@ -2119,8 +2123,9 @@ static void shrink_active_list(unsigned long nr_to_scan,
|
||||
if (bypass)
|
||||
goto skip_page_referenced;
|
||||
trace_android_vh_page_trylock_set(page);
|
||||
/* Referenced or rmap lock contention: rotate */
|
||||
if (page_referenced(page, 0, sc->target_mem_cgroup,
|
||||
&vm_flags)) {
|
||||
&vm_flags) != 0) {
|
||||
/*
|
||||
* Identify referenced, file-backed active pages and
|
||||
* give them one more trip around the active list. So
|
||||
|
Reference in New Issue
Block a user