From be232dc83f469f76fe4e229a38fc4b668bc6096c Mon Sep 17 00:00:00 2001 From: ferreo Date: Thu, 5 Dec 2024 20:04:44 +0100 Subject: [PATCH] Update patches/0001-cachyos-base-all.patch --- patches/0001-cachyos-base-all.patch | 2355 ++++++++++++++++++--------- 1 file changed, 1584 insertions(+), 771 deletions(-) diff --git a/patches/0001-cachyos-base-all.patch b/patches/0001-cachyos-base-all.patch index beb888a..111d249 100644 --- a/patches/0001-cachyos-base-all.patch +++ b/patches/0001-cachyos-base-all.patch @@ -1,6 +1,6 @@ -From 887efc68ad8a5ea19f8df4bc544c6d09c38e1ec5 Mon Sep 17 00:00:00 2001 +From ca0d3edbeafb06cd3a46f864d0db9a400f0156ab Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 21:59:13 +0100 +Date: Thu, 5 Dec 2024 14:33:43 +0100 Subject: [PATCH 01/12] amd-cache-optimizer Signed-off-by: Peter Jung @@ -33,7 +33,7 @@ index 000000000000..ac3431736f5c + - "cache" cores within the larger L3 CCD are prioritized before + those in the smaller L3 CCD. diff --git a/MAINTAINERS b/MAINTAINERS -index b878ddc99f94..3456edbb7b86 100644 +index 6bb4ec0c162a..a578178468f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -965,6 +965,14 @@ Q: https://patchwork.kernel.org/project/linux-rdma/list/ @@ -270,11 +270,11 @@ index 000000000000..0f6d3c54d879 +MODULE_DESCRIPTION("AMD 3D V-Cache Performance Optimizer Driver"); +MODULE_LICENSE("GPL"); -- -2.47.0 +2.47.1 -From a04984088594eef7e446ab1b93b116f638e9bc37 Mon Sep 17 00:00:00 2001 +From 3b4b0f1c81789f3e15c7b55939eaceba375d74c6 Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 21:59:23 +0100 +Date: Thu, 5 Dec 2024 14:33:59 +0100 Subject: [PATCH 02/12] amd-pstate Signed-off-by: Peter Jung @@ -291,9 +291,9 @@ Signed-off-by: Peter Jung arch/x86/kernel/smpboot.c | 14 +- arch/x86/mm/init.c | 23 ++- drivers/cpufreq/amd-pstate-ut.c | 6 +- - drivers/cpufreq/amd-pstate.c | 231 ++++++++++------------- + drivers/cpufreq/amd-pstate.c | 205 ++++++++++------------- tools/arch/x86/include/asm/cpufeatures.h | 2 +- - 14 files changed, 224 insertions(+), 152 deletions(-) + 14 files changed, 222 insertions(+), 128 deletions(-) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 913fd3a7bac6..a7c93191b7c6 100644 @@ -633,7 +633,7 @@ index f66701514d90..a261d7300951 100644 } diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c -index b63863f77c67..d7630bab2516 100644 +index 91d3c3b1c2d3..d7630bab2516 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -233,7 +233,7 @@ static int amd_pstate_get_energy_pref_index(struct amd_cpudata *cpudata) @@ -758,43 +758,7 @@ index b63863f77c67..d7630bab2516 100644 return 0; } -@@ -665,34 +690,12 @@ static void amd_pstate_adjust_perf(unsigned int cpu, - static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on) - { - struct amd_cpudata *cpudata = policy->driver_data; -- struct cppc_perf_ctrls perf_ctrls; -- u32 highest_perf, nominal_perf, nominal_freq, max_freq; -+ u32 nominal_freq, max_freq; - int ret = 0; - -- highest_perf = READ_ONCE(cpudata->highest_perf); -- nominal_perf = READ_ONCE(cpudata->nominal_perf); - nominal_freq = READ_ONCE(cpudata->nominal_freq); - max_freq = READ_ONCE(cpudata->max_freq); - -- if (boot_cpu_has(X86_FEATURE_CPPC)) { -- u64 value = READ_ONCE(cpudata->cppc_req_cached); -- -- value &= ~GENMASK_ULL(7, 0); -- value |= on ? highest_perf : nominal_perf; -- WRITE_ONCE(cpudata->cppc_req_cached, value); -- -- wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); -- } else { -- perf_ctrls.max_perf = on ? highest_perf : nominal_perf; -- ret = cppc_set_perf(cpudata->cpu, &perf_ctrls); -- if (ret) { -- cpufreq_cpu_release(policy); -- pr_debug("Failed to set max perf on CPU:%d. ret:%d\n", -- cpudata->cpu, ret); -- return ret; -- } -- } -- - if (on) - policy->cpuinfo.max_freq = max_freq; - else if (policy->cpuinfo.max_freq > nominal_freq * 1000) -@@ -847,7 +850,7 @@ static u32 amd_pstate_get_transition_delay_us(unsigned int cpu) +@@ -825,7 +850,7 @@ static u32 amd_pstate_get_transition_delay_us(unsigned int cpu) transition_delay_ns = cppc_get_transition_latency(cpu); if (transition_delay_ns == CPUFREQ_ETERNAL) { @@ -803,7 +767,7 @@ index b63863f77c67..d7630bab2516 100644 return AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY; else return AMD_PSTATE_TRANSITION_DELAY; -@@ -1001,7 +1004,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) +@@ -979,7 +1004,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) policy->fast_switch_possible = true; ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0], @@ -812,7 +776,7 @@ index b63863f77c67..d7630bab2516 100644 if (ret < 0) { dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret); goto free_cpudata1; -@@ -1045,7 +1048,7 @@ static int amd_pstate_cpu_resume(struct cpufreq_policy *policy) +@@ -1023,7 +1048,7 @@ static int amd_pstate_cpu_resume(struct cpufreq_policy *policy) { int ret; @@ -821,7 +785,7 @@ index b63863f77c67..d7630bab2516 100644 if (ret) pr_err("failed to enable amd-pstate during resume, return %d\n", ret); -@@ -1056,7 +1059,7 @@ static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy) +@@ -1034,7 +1059,7 @@ static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy) { int ret; @@ -830,7 +794,7 @@ index b63863f77c67..d7630bab2516 100644 if (ret) pr_err("failed to disable amd-pstate during suspend, return %d\n", ret); -@@ -1189,25 +1192,41 @@ static ssize_t show_energy_performance_preference( +@@ -1167,25 +1192,41 @@ static ssize_t show_energy_performance_preference( static void amd_pstate_driver_cleanup(void) { @@ -880,7 +844,7 @@ index b63863f77c67..d7630bab2516 100644 if (ret) { pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n", ret); -@@ -1485,6 +1504,8 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) +@@ -1463,6 +1504,8 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) WRITE_ONCE(cpudata->cppc_cap1_cached, value); } @@ -889,7 +853,7 @@ index b63863f77c67..d7630bab2516 100644 return 0; free_cpudata1: -@@ -1507,26 +1528,13 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) +@@ -1485,26 +1528,13 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; @@ -919,16 +883,7 @@ index b63863f77c67..d7630bab2516 100644 max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, cpudata->max_limit_perf); -@@ -1535,7 +1543,7 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) - value = READ_ONCE(cpudata->cppc_req_cached); - - if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) -- min_perf = max_perf; -+ min_perf = min(cpudata->nominal_perf, max_perf); - - /* Initial min/max values for CPPC Performance Controls Register */ - value &= ~AMD_CPPC_MIN_PERF(~0L); -@@ -1563,12 +1571,6 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) +@@ -1541,12 +1571,6 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) epp = 0; @@ -941,7 +896,7 @@ index b63863f77c67..d7630bab2516 100644 WRITE_ONCE(cpudata->cppc_req_cached, value); return amd_pstate_set_epp(cpudata, epp); } -@@ -1605,7 +1607,7 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata) +@@ -1583,7 +1607,7 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata) u64 value, max_perf; int ret; @@ -950,7 +905,7 @@ index b63863f77c67..d7630bab2516 100644 if (ret) pr_err("failed to enable amd pstate during resume, return %d\n", ret); -@@ -1616,8 +1618,9 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata) +@@ -1594,8 +1618,9 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata) wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); } else { perf_ctrls.max_perf = max_perf; @@ -961,7 +916,7 @@ index b63863f77c67..d7630bab2516 100644 } } -@@ -1657,9 +1660,11 @@ static void amd_pstate_epp_offline(struct cpufreq_policy *policy) +@@ -1635,9 +1660,11 @@ static void amd_pstate_epp_offline(struct cpufreq_policy *policy) wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value); } else { perf_ctrls.desired_perf = 0; @@ -974,7 +929,7 @@ index b63863f77c67..d7630bab2516 100644 } mutex_unlock(&amd_pstate_limits_lock); } -@@ -1679,13 +1684,6 @@ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) +@@ -1657,13 +1684,6 @@ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy) return 0; } @@ -988,7 +943,7 @@ index b63863f77c67..d7630bab2516 100644 static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; -@@ -1699,7 +1697,7 @@ static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) +@@ -1677,7 +1697,7 @@ static int amd_pstate_epp_suspend(struct cpufreq_policy *policy) cpudata->suspended = true; /* disable CPPC in lowlevel firmware */ @@ -997,7 +952,7 @@ index b63863f77c67..d7630bab2516 100644 if (ret) pr_err("failed to suspend, return %d\n", ret); -@@ -1741,7 +1739,7 @@ static struct cpufreq_driver amd_pstate_driver = { +@@ -1719,7 +1739,7 @@ static struct cpufreq_driver amd_pstate_driver = { static struct cpufreq_driver amd_pstate_epp_driver = { .flags = CPUFREQ_CONST_LOOPS, @@ -1006,7 +961,7 @@ index b63863f77c67..d7630bab2516 100644 .setpolicy = amd_pstate_epp_set_policy, .init = amd_pstate_epp_cpu_init, .exit = amd_pstate_epp_cpu_exit, -@@ -1755,26 +1753,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = { +@@ -1733,26 +1753,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = { .attr = amd_pstate_epp_attr, }; @@ -1034,7 +989,7 @@ index b63863f77c67..d7630bab2516 100644 * CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F. * show the debug message that helps to check if the CPU has CPPC support for loading issue. */ -@@ -1864,10 +1843,10 @@ static int __init amd_pstate_init(void) +@@ -1842,10 +1843,10 @@ static int __init amd_pstate_init(void) if (cppc_state == AMD_PSTATE_UNDEFINED) { /* Disable on the following configs by default: * 1. Undefined platforms @@ -1047,7 +1002,7 @@ index b63863f77c67..d7630bab2516 100644 pr_info("driver load is disabled, boot with specific mode to enable this\n"); return -ENODEV; } -@@ -1875,50 +1854,31 @@ static int __init amd_pstate_init(void) +@@ -1853,50 +1854,31 @@ static int __init amd_pstate_init(void) cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE; } @@ -1077,17 +1032,17 @@ index b63863f77c67..d7630bab2516 100644 - static_call_update(amd_pstate_enable, cppc_enable); - static_call_update(amd_pstate_init_perf, cppc_init_perf); - static_call_update(amd_pstate_update_perf, cppc_update_perf); +- } +- +- if (amd_pstate_prefcore) { +- ret = amd_detect_prefcore(&amd_pstate_prefcore); +- if (ret) +- return ret; + static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable); + static_call_update(amd_pstate_init_perf, shmem_init_perf); + static_call_update(amd_pstate_update_perf, shmem_update_perf); } -- if (amd_pstate_prefcore) { -- ret = amd_detect_prefcore(&amd_pstate_prefcore); -- if (ret) -- return ret; -- } -- - /* enable amd pstate feature */ - ret = amd_pstate_enable(true); + ret = amd_pstate_register_driver(cppc_state); @@ -1108,7 +1063,7 @@ index b63863f77c67..d7630bab2516 100644 } dev_root = bus_get_dev_root(&cpu_subsys); -@@ -1935,8 +1895,7 @@ static int __init amd_pstate_init(void) +@@ -1913,8 +1895,7 @@ static int __init amd_pstate_init(void) global_attr_free: cpufreq_unregister_driver(current_pstate_driver); @@ -1132,11 +1087,11 @@ index dd4682857c12..23698d0f4bb4 100644 /* * BUG word(s) -- -2.47.0 +2.47.1 -From 39068aed1309d7e263f7f3a04334dd367c2885df Mon Sep 17 00:00:00 2001 +From 22d86a45e904cc75dda7aa5352c61cb40af5e258 Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 21:59:35 +0100 +Date: Thu, 5 Dec 2024 14:34:11 +0100 Subject: [PATCH 03/12] autofdo Signed-off-by: Peter Jung @@ -1518,7 +1473,7 @@ index 000000000000..92195958e3db + + $ make LLVM=1 CLANG_AUTOFDO_PROFILE= CLANG_PROPELLER_PROFILE_PREFIX= diff --git a/MAINTAINERS b/MAINTAINERS -index 3456edbb7b86..97802662e8d8 100644 +index a578178468f1..a2d251917629 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3674,6 +3674,13 @@ F: kernel/audit* @@ -1550,7 +1505,7 @@ index 3456edbb7b86..97802662e8d8 100644 M: Petr Mladek R: Steven Rostedt diff --git a/Makefile b/Makefile -index 68a8faff2543..5ccec99bf086 100644 +index da6e99309a4d..ca57863d294f 100644 --- a/Makefile +++ b/Makefile @@ -1018,6 +1018,8 @@ include-$(CONFIG_KMSAN) += scripts/Makefile.kmsan @@ -1657,7 +1612,7 @@ index feb8102a9ca7..bc497a67d363 100644 DISCARDS diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h -index eeadbaeccf88..c995474e4c64 100644 +index fa284b64b2de..54504013c749 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -95,18 +95,25 @@ @@ -1878,11 +1833,11 @@ index 3d27983dc908..6f64d611faea 100644 return -1; /* until end of address space */ -- -2.47.0 +2.47.1 -From e068cbe064ee528baae88081fade4839076b1681 Mon Sep 17 00:00:00 2001 +From 16c298c1b5423342fed9480db28cbbbc97b51d0e Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 21:59:48 +0100 +Date: Thu, 5 Dec 2024 14:34:23 +0100 Subject: [PATCH 04/12] bbr3 Signed-off-by: Peter Jung @@ -2142,7 +2097,7 @@ index 86bb2e8b17c9..9d9a3eb2ce9b 100644 union tcp_cc_info { diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h -index 3b687d20c9ed..a7c30c243b54 100644 +index db7254d52d93..38de18d921ea 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -507,12 +507,14 @@ enum { @@ -5264,22 +5219,23 @@ index 79064580c8c0..697270ce1ea6 100644 event = icsk->icsk_pending; -- -2.47.0 +2.47.1 -From f3a6d6d71bfb323d55631f442c8ef5a33448bf92 Mon Sep 17 00:00:00 2001 +From 4dd9316343809174a5fde1af50590a7c714efe76 Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 21:59:58 +0100 +Date: Thu, 5 Dec 2024 14:34:35 +0100 Subject: [PATCH 05/12] cachy Signed-off-by: Peter Jung --- .../admin-guide/kernel-parameters.txt | 12 + + Documentation/admin-guide/sysctl/vm.rst | 72 + Documentation/gpu/amdgpu/thermal.rst | 12 + Makefile | 8 + - arch/x86/Kconfig.cpu | 359 +- - arch/x86/Makefile | 87 +- + arch/x86/Kconfig.cpu | 367 +- + arch/x86/Makefile | 89 +- arch/x86/include/asm/pci.h | 6 + - arch/x86/include/asm/vermagic.h | 70 + + arch/x86/include/asm/vermagic.h | 72 + arch/x86/pci/common.c | 7 +- drivers/Makefile | 13 +- drivers/ata/ahci.c | 23 +- @@ -5314,29 +5270,30 @@ Signed-off-by: Peter Jung drivers/scsi/vhba/Kconfig | 9 + drivers/scsi/vhba/Makefile | 4 + drivers/scsi/vhba/vhba.c | 1130 ++++++ + include/linux/mm.h | 8 + include/linux/pagemap.h | 2 +- include/linux/user_namespace.h | 4 + include/linux/wait.h | 2 + init/Kconfig | 26 + kernel/Kconfig.hz | 24 + - kernel/Kconfig.preempt | 2 +- kernel/fork.c | 14 + kernel/locking/rwsem.c | 4 +- kernel/sched/fair.c | 13 + kernel/sched/sched.h | 2 +- kernel/sched/wait.c | 24 + - kernel/sysctl.c | 12 + + kernel/sysctl.c | 46 + kernel/user_namespace.c | 7 + - mm/Kconfig | 2 +- + mm/Kconfig | 65 +- mm/compaction.c | 4 + mm/huge_memory.c | 4 + + mm/mm_init.c | 1 + mm/page-writeback.c | 8 + mm/page_alloc.c | 4 + mm/swap.c | 5 + mm/vmpressure.c | 4 + - mm/vmscan.c | 8 + + mm/vmscan.c | 147 + net/ipv4/inet_connection_sock.c | 2 +- - 63 files changed, 6591 insertions(+), 67 deletions(-) + 65 files changed, 6919 insertions(+), 66 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2loopback.c create mode 100644 drivers/media/v4l2-core/v4l2loopback.h create mode 100644 drivers/media/v4l2-core/v4l2loopback_formats.h @@ -5375,6 +5332,103 @@ index d401577b5a6a..e6ec15a89924 100644 noioapicquirk [APIC] Disable all boot interrupt quirks. Safety option to keep boot IRQs enabled. This should never be necessary. +diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst +index f48eaa98d22d..fc777c14cff6 100644 +--- a/Documentation/admin-guide/sysctl/vm.rst ++++ b/Documentation/admin-guide/sysctl/vm.rst +@@ -25,6 +25,9 @@ files can be found in mm/swap.c. + Currently, these files are in /proc/sys/vm: + + - admin_reserve_kbytes ++- anon_min_ratio ++- clean_low_ratio ++- clean_min_ratio + - compact_memory + - compaction_proactiveness + - compact_unevictable_allowed +@@ -108,6 +111,67 @@ On x86_64 this is about 128MB. + Changing this takes effect whenever an application requests memory. + + ++anon_min_ratio ++============== ++ ++This knob provides *hard* protection of anonymous pages. The anonymous pages ++on the current node won't be reclaimed under any conditions when their amount ++is below vm.anon_min_ratio. ++ ++This knob may be used to prevent excessive swap thrashing when anonymous ++memory is low (for example, when memory is going to be overfilled by ++compressed data of zram module). ++ ++Setting this value too high (close to 100) can result in inability to ++swap and can lead to early OOM under memory pressure. ++ ++The unit of measurement is the percentage of the total memory of the node. ++ ++The default value is 15. ++ ++ ++clean_low_ratio ++================ ++ ++This knob provides *best-effort* protection of clean file pages. The file pages ++on the current node won't be reclaimed under memory pressure when the amount of ++clean file pages is below vm.clean_low_ratio *unless* we threaten to OOM. ++ ++Protection of clean file pages using this knob may be used when swapping is ++still possible to ++ - prevent disk I/O thrashing under memory pressure; ++ - improve performance in disk cache-bound tasks under memory pressure. ++ ++Setting it to a high value may result in a early eviction of anonymous pages ++into the swap space by attempting to hold the protected amount of clean file ++pages in memory. ++ ++The unit of measurement is the percentage of the total memory of the node. ++ ++The default value is 0. ++ ++ ++clean_min_ratio ++================ ++ ++This knob provides *hard* protection of clean file pages. The file pages on the ++current node won't be reclaimed under memory pressure when the amount of clean ++file pages is below vm.clean_min_ratio. ++ ++Hard protection of clean file pages using this knob may be used to ++ - prevent disk I/O thrashing under memory pressure even with no free swap space; ++ - improve performance in disk cache-bound tasks under memory pressure; ++ - avoid high latency and prevent livelock in near-OOM conditions. ++ ++Setting it to a high value may result in a early out-of-memory condition due to ++the inability to reclaim the protected amount of clean file pages when other ++types of pages cannot be reclaimed. ++ ++The unit of measurement is the percentage of the total memory of the node. ++ ++The default value is 15. ++ ++ + compact_memory + ============== + +@@ -964,6 +1028,14 @@ be 133 (x + 2x = 200, 2x = 133.33). + At 0, the kernel will not initiate swap until the amount of free and + file-backed pages is less than the high watermark in a zone. + ++This knob has no effect if the amount of clean file pages on the current ++node is below vm.clean_low_ratio or vm.clean_min_ratio. In this case, ++only anonymous pages can be reclaimed. ++ ++If the number of anonymous pages on the current node is below ++vm.anon_min_ratio, then only file pages can be reclaimed with ++any vm.swappiness value. ++ + + unprivileged_userfaultfd + ======================== diff --git a/Documentation/gpu/amdgpu/thermal.rst b/Documentation/gpu/amdgpu/thermal.rst index 6d942b5c58f0..1768a106aab1 100644 --- a/Documentation/gpu/amdgpu/thermal.rst @@ -5399,7 +5453,7 @@ index 6d942b5c58f0..1768a106aab1 100644 ====== diff --git a/Makefile b/Makefile -index 5ccec99bf086..5c6151566fd3 100644 +index ca57863d294f..7cc9e5a04f71 100644 --- a/Makefile +++ b/Makefile @@ -801,11 +801,19 @@ KBUILD_CFLAGS += -fno-delete-null-pointer-checks @@ -5423,7 +5477,7 @@ index 5ccec99bf086..5c6151566fd3 100644 # depends on `opt-level` and `debug-assertions`, respectively. KBUILD_RUSTFLAGS += -Cdebug-assertions=$(if $(CONFIG_RUST_DEBUG_ASSERTIONS),y,n) diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu -index 2a7279d80460..f5849153b385 100644 +index 2a7279d80460..786fcf84d128 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -155,9 +155,8 @@ config MPENTIUM4 @@ -5581,7 +5635,7 @@ index 2a7279d80460..f5849153b385 100644 help Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and -@@ -278,14 +388,191 @@ config MCORE2 +@@ -278,14 +388,199 @@ config MCORE2 family in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo) @@ -5689,14 +5743,22 @@ index 2a7279d80460..f5849153b385 100644 + + Enables -march=cannonlake + -+config MICELAKE -+ bool "Intel Ice Lake" ++config MICELAKE_CLIENT ++ bool "Intel Ice Lake (Client)" + help + + Select this for 10th Gen Core processors in the Ice Lake family. + + Enables -march=icelake-client + ++config MICELAKE_SERVER ++ bool "Intel Ice lake (Server)" ++ help ++ ++ Select this for the 3rd Gen Xeon processors in the Ice lake family. ++ ++ Enables -march=icelake-server ++ +config MCASCADELAKE + bool "Intel Cascade Lake" + help @@ -5779,7 +5841,7 @@ index 2a7279d80460..f5849153b385 100644 config GENERIC_CPU bool "Generic-x86-64" -@@ -294,6 +581,26 @@ config GENERIC_CPU +@@ -294,6 +589,26 @@ config GENERIC_CPU Generic x86-64 CPU. Run equally well on all x86-64 CPUs. @@ -5806,7 +5868,7 @@ index 2a7279d80460..f5849153b385 100644 endchoice config X86_GENERIC -@@ -308,6 +615,30 @@ config X86_GENERIC +@@ -308,6 +623,30 @@ config X86_GENERIC This is really intended for distributors who need more generic optimizations. @@ -5837,34 +5899,34 @@ index 2a7279d80460..f5849153b385 100644 # # Define implied options from the CPU selection here config X86_INTERNODE_CACHE_SHIFT -@@ -318,7 +649,7 @@ config X86_INTERNODE_CACHE_SHIFT +@@ -318,7 +657,7 @@ config X86_INTERNODE_CACHE_SHIFT config X86_L1_CACHE_SHIFT int default "7" if MPENTIUM4 || MPSC - default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU -+ default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MZEN5 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MEMERALDRAPIDS || MNATIVE_INTEL || MNATIVE_AMD ++ default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MZEN5 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE_CLIENT || MICELAKE_SERVER || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MEMERALDRAPIDS || MNATIVE_INTEL || MNATIVE_AMD default "4" if MELAN || M486SX || M486 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX -@@ -336,11 +667,11 @@ config X86_ALIGNMENT_16 +@@ -336,11 +675,11 @@ config X86_ALIGNMENT_16 config X86_INTEL_USERCOPY def_bool y - depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 -+ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MEMERALDRAPIDS || MNATIVE_INTEL ++ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE_CLIENT || MICELAKE_SERVER || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MEMERALDRAPIDS || MNATIVE_INTEL config X86_USE_PPRO_CHECKSUM def_bool y - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM -+ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MZEN5 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MEMERALDRAPIDS || MNATIVE_INTEL || MNATIVE_AMD ++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MZEN5 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE_CLIENT || MICELAKE_SERVER || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MEMERALDRAPIDS || MNATIVE_INTEL || MNATIVE_AMD # # P6_NOPs are a relatively minor optimization that require a family >= diff --git a/arch/x86/Makefile b/arch/x86/Makefile -index 5b773b34768d..74e94c9ba198 100644 +index 5b773b34768d..5f57fd8750c6 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile -@@ -182,15 +182,96 @@ else +@@ -182,15 +182,98 @@ else cflags-$(CONFIG_MK8) += -march=k8 cflags-$(CONFIG_MPSC) += -march=nocona cflags-$(CONFIG_MCORE2) += -march=core2 @@ -5906,7 +5968,8 @@ index 5b773b34768d..74e94c9ba198 100644 + cflags-$(CONFIG_MSKYLAKE) += -march=skylake + cflags-$(CONFIG_MSKYLAKEX) += -march=skylake-avx512 + cflags-$(CONFIG_MCANNONLAKE) += -march=cannonlake -+ cflags-$(CONFIG_MICELAKE) += -march=icelake-client ++ cflags-$(CONFIG_MICELAKE_CLIENT) += -march=icelake-client ++ cflags-$(CONFIG_MICELAKE_SERVER) += -march=icelake-server + cflags-$(CONFIG_MCASCADELAKE) += -march=cascadelake + cflags-$(CONFIG_MCOOPERLAKE) += -march=cooperlake + cflags-$(CONFIG_MTIGERLAKE) += -march=tigerlake @@ -5951,7 +6014,8 @@ index 5b773b34768d..74e94c9ba198 100644 + rustflags-$(CONFIG_MSKYLAKE) += -Ctarget-cpu=skylake + rustflags-$(CONFIG_MSKYLAKEX) += -Ctarget-cpu=skylake-avx512 + rustflags-$(CONFIG_MCANNONLAKE) += -Ctarget-cpu=cannonlake -+ rustflags-$(CONFIG_MICELAKE) += -Ctarget-cpu=icelake-client ++ rustflags-$(CONFIG_MICELAKE_CLIENT) += -Ctarget-cpu=icelake-client ++ rustflags-$(CONFIG_MICELAKE_SERVER) += -Ctarget-cpu=icelake-server + rustflags-$(CONFIG_MCASCADELAKE) += -Ctarget-cpu=cascadelake + rustflags-$(CONFIG_MCOOPERLAKE) += -Ctarget-cpu=cooperlake + rustflags-$(CONFIG_MTIGERLAKE) += -Ctarget-cpu=tigerlake @@ -5989,10 +6053,10 @@ index b3ab80a03365..5e883b397ff3 100644 already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ diff --git a/arch/x86/include/asm/vermagic.h b/arch/x86/include/asm/vermagic.h -index 75884d2cdec3..f4e29563473d 100644 +index 75884d2cdec3..2fdae271f47f 100644 --- a/arch/x86/include/asm/vermagic.h +++ b/arch/x86/include/asm/vermagic.h -@@ -17,6 +17,54 @@ +@@ -17,6 +17,56 @@ #define MODULE_PROC_FAMILY "586MMX " #elif defined CONFIG_MCORE2 #define MODULE_PROC_FAMILY "CORE2 " @@ -6024,8 +6088,10 @@ index 75884d2cdec3..f4e29563473d 100644 +#define MODULE_PROC_FAMILY "SKYLAKEX " +#elif defined CONFIG_MCANNONLAKE +#define MODULE_PROC_FAMILY "CANNONLAKE " -+#elif defined CONFIG_MICELAKE -+#define MODULE_PROC_FAMILY "ICELAKE " ++#elif defined CONFIG_MICELAKE_CLIENT ++#define MODULE_PROC_FAMILY "ICELAKE_CLIENT " ++#elif defined CONFIG_MICELAKE_SERVER ++#define MODULE_PROC_FAMILY "ICELAKE_SERVER " +#elif defined CONFIG_MCASCADELAKE +#define MODULE_PROC_FAMILY "CASCADELAKE " +#elif defined CONFIG_MCOOPERLAKE @@ -6047,7 +6113,7 @@ index 75884d2cdec3..f4e29563473d 100644 #elif defined CONFIG_MATOM #define MODULE_PROC_FAMILY "ATOM " #elif defined CONFIG_M686 -@@ -35,6 +83,28 @@ +@@ -35,6 +85,28 @@ #define MODULE_PROC_FAMILY "K7 " #elif defined CONFIG_MK8 #define MODULE_PROC_FAMILY "K8 " @@ -6276,10 +6342,10 @@ index df17e79c45c7..e454488c1a31 100644 + endmenu diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 8d97f17ffe66..27b3d03bfdcd 100644 +index 24fbde7dd1c4..6a50ee0ef556 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -4473,7 +4473,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) +@@ -4497,7 +4497,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) return r; } @@ -6302,7 +6368,7 @@ index ebabfe3a512f..4d3ebcaacca1 100644 * * AMD driver supports pre-defined mathematical functions for transferring diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -index 288be19db7c1..9d48d01d5217 100644 +index 9be87b532517..47e8cd9a756f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -473,7 +473,7 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc) @@ -12572,6 +12638,25 @@ index 000000000000..7531223355e5 +module_init(vhba_init); +module_exit(vhba_exit); + +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 61fff5d34ed5..18dc2544700b 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -205,6 +205,14 @@ static inline void __mm_zero_struct_page(struct page *page) + + extern int sysctl_max_map_count; + ++extern bool sysctl_workingset_protection; ++extern u8 sysctl_anon_min_ratio; ++extern u8 sysctl_clean_low_ratio; ++extern u8 sysctl_clean_min_ratio; ++int vm_workingset_protection_update_handler( ++ const struct ctl_table *table, int write, ++ void __user *buffer, size_t *lenp, loff_t *ppos); ++ + extern unsigned long sysctl_user_reserve_kbytes; + extern unsigned long sysctl_admin_reserve_kbytes; + diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 68a5f1ff3301..291873a34079 100644 --- a/include/linux/pagemap.h @@ -12628,10 +12713,10 @@ index 8aa3372f21a0..924778a426ce 100644 void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout); diff --git a/init/Kconfig b/init/Kconfig -index c521e1421ad4..38dbd16da6a9 100644 +index 7256fa127530..857869dbc22c 100644 --- a/init/Kconfig +++ b/init/Kconfig -@@ -145,6 +145,10 @@ config THREAD_INFO_IN_TASK +@@ -154,6 +154,10 @@ config THREAD_INFO_IN_TASK menu "General setup" @@ -12642,7 +12727,7 @@ index c521e1421ad4..38dbd16da6a9 100644 config BROKEN bool -@@ -1300,6 +1304,22 @@ config USER_NS +@@ -1309,6 +1313,22 @@ config USER_NS If unsure, say N. @@ -12665,7 +12750,7 @@ index c521e1421ad4..38dbd16da6a9 100644 config PID_NS bool "PID Namespaces" default y -@@ -1442,6 +1462,12 @@ config CC_OPTIMIZE_FOR_PERFORMANCE +@@ -1451,6 +1471,12 @@ config CC_OPTIMIZE_FOR_PERFORMANCE with the "-O2" compiler flag for best performance and most helpful compile-time warnings. @@ -12720,21 +12805,8 @@ index 38ef6d06888e..0f78364efd4f 100644 default 1000 if HZ_1000 config SCHED_HRTICK -diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt -index fe782cd77388..a69475f2bca7 100644 ---- a/kernel/Kconfig.preempt -+++ b/kernel/Kconfig.preempt -@@ -69,7 +69,7 @@ config PREEMPT - - config PREEMPT_RT - bool "Fully Preemptible Kernel (Real-Time)" -- depends on EXPERT && ARCH_SUPPORTS_RT -+ depends on ARCH_SUPPORTS_RT - select PREEMPTION - help - This option turns the kernel into a real-time kernel by replacing diff --git a/kernel/fork.c b/kernel/fork.c -index 22f43721d031..8287afdd01d2 100644 +index ce8be55e5e04..e97e527cec69 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -107,6 +107,10 @@ @@ -12748,7 +12820,7 @@ index 22f43721d031..8287afdd01d2 100644 #include #include #include -@@ -2138,6 +2142,10 @@ __latent_entropy struct task_struct *copy_process( +@@ -2158,6 +2162,10 @@ __latent_entropy struct task_struct *copy_process( if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS)) return ERR_PTR(-EINVAL); @@ -12759,7 +12831,7 @@ index 22f43721d031..8287afdd01d2 100644 /* * Thread groups must share signals as well, and detached threads * can only be started up within the thread group. -@@ -3291,6 +3299,12 @@ int ksys_unshare(unsigned long unshare_flags) +@@ -3311,6 +3319,12 @@ int ksys_unshare(unsigned long unshare_flags) if (unshare_flags & CLONE_NEWNS) unshare_flags |= CLONE_FS; @@ -12887,7 +12959,7 @@ index 51e38f5f4701..c5cc616484ba 100644 { wq_entry->flags = flags; diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index 79e6cb1d5c48..676e89dc38c3 100644 +index 79e6cb1d5c48..4a62ae02a2c0 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -80,6 +80,9 @@ @@ -12916,6 +12988,47 @@ index 79e6cb1d5c48..676e89dc38c3 100644 #ifdef CONFIG_PROC_SYSCTL { .procname = "tainted", +@@ -2198,6 +2210,40 @@ static struct ctl_table vm_table[] = { + .extra1 = SYSCTL_ZERO, + }, + #endif ++ { ++ .procname = "workingset_protection", ++ .data = &sysctl_workingset_protection, ++ .maxlen = sizeof(bool), ++ .mode = 0644, ++ .proc_handler = &proc_dobool, ++ }, ++ { ++ .procname = "anon_min_ratio", ++ .data = &sysctl_anon_min_ratio, ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = &vm_workingset_protection_update_handler, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE_HUNDRED, ++ }, ++ { ++ .procname = "clean_low_ratio", ++ .data = &sysctl_clean_low_ratio, ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = &vm_workingset_protection_update_handler, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE_HUNDRED, ++ }, ++ { ++ .procname = "clean_min_ratio", ++ .data = &sysctl_clean_min_ratio, ++ .maxlen = sizeof(u8), ++ .mode = 0644, ++ .proc_handler = &vm_workingset_protection_update_handler, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE_HUNDRED, ++ }, + { + .procname = "user_reserve_kbytes", + .data = &sysctl_user_reserve_kbytes, diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index aa0b2e47f2f2..d74d857b1696 100644 --- a/kernel/user_namespace.c @@ -12935,10 +13048,80 @@ index aa0b2e47f2f2..d74d857b1696 100644 static DEFINE_MUTEX(userns_state_mutex); diff --git a/mm/Kconfig b/mm/Kconfig -index 33fa51d608dc..6bfea371341e 100644 +index 33fa51d608dc..87cb63f7ca57 100644 --- a/mm/Kconfig +++ b/mm/Kconfig -@@ -648,7 +648,7 @@ config COMPACTION +@@ -499,6 +499,69 @@ config ARCH_WANT_OPTIMIZE_DAX_VMEMMAP + config ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP + bool + ++config ANON_MIN_RATIO ++ int "Default value for vm.anon_min_ratio" ++ depends on SYSCTL ++ range 0 100 ++ default 15 ++ help ++ This option sets the default value for vm.anon_min_ratio sysctl knob. ++ ++ The vm.anon_min_ratio sysctl knob provides *hard* protection of ++ anonymous pages. The anonymous pages on the current node won't be ++ reclaimed under any conditions when their amount is below ++ vm.anon_min_ratio. This knob may be used to prevent excessive swap ++ thrashing when anonymous memory is low (for example, when memory is ++ going to be overfilled by compressed data of zram module). ++ ++ Setting this value too high (close to MemTotal) can result in ++ inability to swap and can lead to early OOM under memory pressure. ++ ++config CLEAN_LOW_RATIO ++ int "Default value for vm.clean_low_ratio" ++ depends on SYSCTL ++ range 0 100 ++ default 0 ++ help ++ This option sets the default value for vm.clean_low_ratio sysctl knob. ++ ++ The vm.clean_low_ratio sysctl knob provides *best-effort* ++ protection of clean file pages. The file pages on the current node ++ won't be reclaimed under memory pressure when the amount of clean file ++ pages is below vm.clean_low_ratio *unless* we threaten to OOM. ++ Protection of clean file pages using this knob may be used when ++ swapping is still possible to ++ - prevent disk I/O thrashing under memory pressure; ++ - improve performance in disk cache-bound tasks under memory ++ pressure. ++ ++ Setting it to a high value may result in a early eviction of anonymous ++ pages into the swap space by attempting to hold the protected amount ++ of clean file pages in memory. ++ ++config CLEAN_MIN_RATIO ++ int "Default value for vm.clean_min_ratio" ++ depends on SYSCTL ++ range 0 100 ++ default 15 ++ help ++ This option sets the default value for vm.clean_min_ratio sysctl knob. ++ ++ The vm.clean_min_ratio sysctl knob provides *hard* protection of ++ clean file pages. The file pages on the current node won't be ++ reclaimed under memory pressure when the amount of clean file pages is ++ below vm.clean_min_ratio. Hard protection of clean file pages using ++ this knob may be used to ++ - prevent disk I/O thrashing under memory pressure even with no free ++ swap space; ++ - improve performance in disk cache-bound tasks under memory ++ pressure; ++ - avoid high latency and prevent livelock in near-OOM conditions. ++ ++ Setting it to a high value may result in a early out-of-memory condition ++ due to the inability to reclaim the protected amount of clean file pages ++ when other types of pages cannot be reclaimed. ++ + config HAVE_MEMBLOCK_PHYS_MAP + bool + +@@ -648,7 +711,7 @@ config COMPACTION config COMPACT_UNEVICTABLE_DEFAULT int depends on COMPACTION @@ -12979,6 +13162,18 @@ index 5734d5d5060f..af595df5b65f 100644 (1<clean_below_min : ++ (sc->anon_below_min && !sc->clean_below_min)) ++ goto keep_locked; ++ + /* + * The number of dirty pages determines if a node is marked + * reclaim_congested. kswapd will stall and start writing +@@ -2415,6 +2441,15 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, + goto out; + } + ++ /* ++ * Force-scan anon if clean file pages is under vm.clean_low_ratio ++ * or vm.clean_min_ratio. ++ */ ++ if (sc->clean_below_low || sc->clean_below_min) { ++ scan_balance = SCAN_ANON; ++ goto out; ++ } ++ + /* + * If there is enough inactive page cache, we do not reclaim + * anything from the anonymous working right now. +@@ -2559,6 +2594,14 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, + BUG(); + } + ++ /* ++ * Hard protection of the working set. ++ * Don't reclaim anon/file pages when the amount is ++ * below the watermark of the same type. ++ */ ++ if (file ? sc->clean_below_min : sc->anon_below_min) ++ scan = 0; ++ + nr[lru] = scan; + } + } +@@ -3992,7 +4035,11 @@ static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc } /* to protect the working set of the last N jiffies */ @@ -13088,8 +13353,136 @@ index 28ba2b06fc7d..99568ccfb0fd 100644 static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) { +@@ -4030,6 +4077,96 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) + } + } + ++int vm_workingset_protection_update_handler(const struct ctl_table *table, int write, ++ void __user *buffer, size_t *lenp, loff_t *ppos) ++{ ++ int ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos); ++ if (ret || !write) ++ return ret; ++ ++ workingset_protection_prev_totalram = 0; ++ ++ return 0; ++} ++ ++static void prepare_workingset_protection(pg_data_t *pgdat, struct scan_control *sc) ++{ ++ unsigned long node_mem_total; ++ struct sysinfo i; ++ ++ if (!(sysctl_workingset_protection)) { ++ sc->anon_below_min = 0; ++ sc->clean_below_low = 0; ++ sc->clean_below_min = 0; ++ return; ++ } ++ ++ if (likely(sysctl_anon_min_ratio || ++ sysctl_clean_low_ratio || ++ sysctl_clean_min_ratio)) { ++#ifdef CONFIG_NUMA ++ si_meminfo_node(&i, pgdat->node_id); ++#else //CONFIG_NUMA ++ si_meminfo(&i); ++#endif //CONFIG_NUMA ++ node_mem_total = i.totalram; ++ ++ if (unlikely(workingset_protection_prev_totalram != node_mem_total)) { ++ sysctl_anon_min_ratio_kb = ++ node_mem_total * sysctl_anon_min_ratio / 100; ++ sysctl_clean_low_ratio_kb = ++ node_mem_total * sysctl_clean_low_ratio / 100; ++ sysctl_clean_min_ratio_kb = ++ node_mem_total * sysctl_clean_min_ratio / 100; ++ workingset_protection_prev_totalram = node_mem_total; ++ } ++ } ++ ++ /* ++ * Check the number of anonymous pages to protect them from ++ * reclaiming if their amount is below the specified. ++ */ ++ if (sysctl_anon_min_ratio) { ++ unsigned long reclaimable_anon; ++ ++ reclaimable_anon = ++ node_page_state(pgdat, NR_ACTIVE_ANON) + ++ node_page_state(pgdat, NR_INACTIVE_ANON) + ++ node_page_state(pgdat, NR_ISOLATED_ANON); ++ ++ sc->anon_below_min = reclaimable_anon < sysctl_anon_min_ratio_kb; ++ } else ++ sc->anon_below_min = 0; ++ ++ /* ++ * Check the number of clean file pages to protect them from ++ * reclaiming if their amount is below the specified. ++ */ ++ if (sysctl_clean_low_ratio || sysctl_clean_min_ratio) { ++ unsigned long reclaimable_file, dirty, clean; ++ ++ reclaimable_file = ++ node_page_state(pgdat, NR_ACTIVE_FILE) + ++ node_page_state(pgdat, NR_INACTIVE_FILE) + ++ node_page_state(pgdat, NR_ISOLATED_FILE); ++ dirty = node_page_state(pgdat, NR_FILE_DIRTY); ++ /* ++ * node_page_state() sum can go out of sync since ++ * all the values are not read at once. ++ */ ++ if (likely(reclaimable_file > dirty)) ++ clean = reclaimable_file - dirty; ++ else ++ clean = 0; ++ ++ sc->clean_below_low = clean < sysctl_clean_low_ratio_kb; ++ sc->clean_below_min = clean < sysctl_clean_min_ratio_kb; ++ } else { ++ sc->clean_below_low = 0; ++ sc->clean_below_min = 0; ++ } ++} ++ + /****************************************************************************** + * rmap/PT walk feedback + ******************************************************************************/ +@@ -4528,6 +4665,12 @@ static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int sw + */ + if (!swappiness) + type = LRU_GEN_FILE; ++ else if (sc->clean_below_min) ++ type = LRU_GEN_ANON; ++ else if (sc->anon_below_min) ++ type = LRU_GEN_FILE; ++ else if (sc->clean_below_low) ++ type = LRU_GEN_ANON; + else if (min_seq[LRU_GEN_ANON] < min_seq[LRU_GEN_FILE]) + type = LRU_GEN_ANON; + else if (swappiness == 1) +@@ -4807,6 +4950,8 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + struct pglist_data *pgdat = lruvec_pgdat(lruvec); + ++ prepare_workingset_protection(pgdat, sc); ++ + /* lru_gen_age_node() called mem_cgroup_calculate_protection() */ + if (mem_cgroup_below_min(NULL, memcg)) + return MEMCG_LRU_YOUNG; +@@ -5954,6 +6099,8 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) + + prepare_scan_control(pgdat, sc); + ++ prepare_workingset_protection(pgdat, sc); ++ + shrink_node_memcgs(pgdat, sc); + + flush_reclaim_state(sc); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c -index 2b698f8419fe..fd039c41d1c8 100644 +index fe7947f77406..99e138cfdd95 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -634,7 +634,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) @@ -13102,21 +13495,21 @@ index 2b698f8419fe..fd039c41d1c8 100644 release_sock(sk); if (reqsk_queue_empty(&icsk->icsk_accept_queue)) -- -2.47.0 +2.47.1 -From 938a1998dd5f44d955fb93e9764abda4ca66a057 Mon Sep 17 00:00:00 2001 +From b6bf895456ea8a4c4e8bb7263152b45083b3737f Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 22:00:08 +0100 +Date: Thu, 5 Dec 2024 14:36:53 +0100 Subject: [PATCH 06/12] crypto Signed-off-by: Peter Jung --- arch/x86/crypto/Kconfig | 4 +- - arch/x86/crypto/aegis128-aesni-asm.S | 532 ++++++++-------------- + arch/x86/crypto/aegis128-aesni-asm.S | 533 ++++++++-------------- arch/x86/crypto/aegis128-aesni-glue.c | 145 +++--- arch/x86/crypto/crc32c-intel_glue.c | 2 +- arch/x86/crypto/crc32c-pcl-intel-asm_64.S | 354 +++++--------- - 5 files changed, 387 insertions(+), 650 deletions(-) + 5 files changed, 387 insertions(+), 651 deletions(-) diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig index 7b1bebed879d..3d2e38ba5240 100644 @@ -13141,7 +13534,7 @@ index 7b1bebed879d..3d2e38ba5240 100644 config CRYPTO_NHPOLY1305_SSE2 tristate "Hash functions: NHPoly1305 (SSE2)" diff --git a/arch/x86/crypto/aegis128-aesni-asm.S b/arch/x86/crypto/aegis128-aesni-asm.S -index ad7f4c891625..7294dc0ee7ba 100644 +index 2de859173940..7294dc0ee7ba 100644 --- a/arch/x86/crypto/aegis128-aesni-asm.S +++ b/arch/x86/crypto/aegis128-aesni-asm.S @@ -1,14 +1,13 @@ @@ -13166,7 +13559,7 @@ index ad7f4c891625..7294dc0ee7ba 100644 #define T1 %xmm7 -#define STATEP %rdi --#define LEN %rsi +-#define LEN %esi -#define SRC %rdx -#define DST %rcx - @@ -13211,32 +13604,32 @@ index ad7f4c891625..7294dc0ee7ba 100644 - xor %r9d, %r9d - pxor MSG, MSG - -- mov LEN, %r8 +- mov LEN, %r8d - and $0x1, %r8 - jz .Lld_partial_1 - -- mov LEN, %r8 +- mov LEN, %r8d - and $0x1E, %r8 - add SRC, %r8 - mov (%r8), %r9b - -.Lld_partial_1: -- mov LEN, %r8 +- mov LEN, %r8d - and $0x2, %r8 - jz .Lld_partial_2 - -- mov LEN, %r8 +- mov LEN, %r8d - and $0x1C, %r8 - add SRC, %r8 - shl $0x10, %r9 - mov (%r8), %r9w - -.Lld_partial_2: -- mov LEN, %r8 +- mov LEN, %r8d - and $0x4, %r8 - jz .Lld_partial_4 - -- mov LEN, %r8 +- mov LEN, %r8d - and $0x18, %r8 - add SRC, %r8 - shl $32, %r9 @@ -13246,11 +13639,11 @@ index ad7f4c891625..7294dc0ee7ba 100644 -.Lld_partial_4: - movq %r9, MSG - -- mov LEN, %r8 +- mov LEN, %r8d - and $0x8, %r8 - jz .Lld_partial_8 - -- mov LEN, %r8 +- mov LEN, %r8d - and $0x10, %r8 - add SRC, %r8 - pslldq $8, MSG @@ -13312,7 +13705,7 @@ index ad7f4c891625..7294dc0ee7ba 100644 + * DST. Clobbers %rax, %rcx, and %r8. */ -SYM_FUNC_START_LOCAL(__store_partial) -- mov LEN, %r8 +- mov LEN, %r8d - mov DST, %r9 - - movq T0, %r10 @@ -13931,7 +14324,7 @@ index ad7f4c891625..7294dc0ee7ba 100644 + store_partial MSG /* mask with byte count: */ -- movq LEN, T0 +- movd LEN, T0 - punpcklbw T0, T0 - punpcklbw T0, T0 - punpcklbw T0, T0 @@ -13944,7 +14337,7 @@ index ad7f4c891625..7294dc0ee7ba 100644 pand T0, MSG aegis128_update -@@ -695,17 +551,19 @@ SYM_TYPED_FUNC_START(crypto_aegis128_aesni_dec_tail) +@@ -695,18 +551,19 @@ SYM_TYPED_FUNC_START(crypto_aegis128_aesni_dec_tail) movdqu STATE1, 0x20(STATEP) movdqu STATE2, 0x30(STATEP) movdqu STATE3, 0x40(STATEP) @@ -13956,7 +14349,8 @@ index ad7f4c891625..7294dc0ee7ba 100644 /* - * void crypto_aegis128_aesni_final(void *state, void *tag_xor, -- * u64 assoclen, u64 cryptlen); +- * unsigned int assoclen, +- * unsigned int cryptlen); + * void aegis128_aesni_final(struct aegis_state *state, + * struct aegis_block *tag_xor, + * unsigned int assoclen, unsigned int cryptlen); @@ -13971,12 +14365,12 @@ index ad7f4c891625..7294dc0ee7ba 100644 /* load the state: */ movdqu 0x00(STATEP), STATE0 -@@ -715,10 +573,8 @@ SYM_FUNC_START(crypto_aegis128_aesni_final) +@@ -716,10 +573,8 @@ SYM_FUNC_START(crypto_aegis128_aesni_final) movdqu 0x40(STATEP), STATE4 /* prepare length block: */ -- movq %rdx, MSG -- movq %rcx, T0 +- movd %edx, MSG +- movd %ecx, T0 - pslldq $8, T0 - pxor T0, MSG + movd ASSOCLEN, MSG @@ -13984,7 +14378,7 @@ index ad7f4c891625..7294dc0ee7ba 100644 psllq $3, MSG /* multiply by 8 (to get bit count) */ pxor STATE3, MSG -@@ -733,7 +589,7 @@ SYM_FUNC_START(crypto_aegis128_aesni_final) +@@ -734,7 +589,7 @@ SYM_FUNC_START(crypto_aegis128_aesni_final) aegis128_update; pxor MSG, STATE3 /* xor tag: */ @@ -13993,7 +14387,7 @@ index ad7f4c891625..7294dc0ee7ba 100644 pxor STATE0, MSG pxor STATE1, MSG -@@ -741,8 +597,6 @@ SYM_FUNC_START(crypto_aegis128_aesni_final) +@@ -742,8 +597,6 @@ SYM_FUNC_START(crypto_aegis128_aesni_final) pxor STATE3, MSG pxor STATE4, MSG @@ -14707,52 +15101,59 @@ index bbcff1fb78cb..752812bc4991 100644 ## PCLMULQDQ tables ## Table is 128 entries x 2 words (8 bytes) each -- -2.47.0 +2.47.1 -From 8c7a03d045e3dcbbbc6c21a4ed733cc4dcbf91ad Mon Sep 17 00:00:00 2001 +From b87a14bbaced97e13e94aab5dfa5caa88b41d452 Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 22:00:19 +0100 +Date: Thu, 5 Dec 2024 14:41:32 +0100 Subject: [PATCH 07/12] fixes Signed-off-by: Peter Jung --- arch/Kconfig | 4 +- + arch/x86/include/asm/futex.h | 8 +- arch/x86/kernel/alternative.c | 10 +- arch/x86/mm/tlb.c | 22 +-- - drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 + - drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 30 ++++ + drivers/bluetooth/btmtk.c | 4 +- + drivers/bluetooth/btusb.c | 2 + + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 + + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 50 +++++- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 31 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 5 +- - drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 156 +++++++++++------- + drivers/gpu/drm/amd/pm/amdgpu_pm.c | 6 +- + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 150 ++++++++++------ drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 15 +- - .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 146 ++++++++-------- - .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 146 ++++++++-------- - .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 145 ++++++++-------- + .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 166 +++++++++-------- + .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 167 ++++++++++------- + .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 168 +++++++++++------- .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 41 ++--- .../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 43 ++--- - .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 143 ++++++++-------- - .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 117 +++++++------ - .../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 144 ++++++++-------- - drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 30 ++++ - drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 5 + - drivers/gpu/drm/drm_edid.c | 47 +++++- - drivers/misc/lkdtm/bugs.c | 2 +- + .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 167 +++++++++-------- + .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 138 ++++++++------ + .../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 168 +++++++++++------- + drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 25 +++ + drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 4 + + drivers/gpu/drm/drm_edid.c | 47 ++++- + drivers/hid/hid-ids.h | 1 + fs/ntfs3/attrib.c | 9 +- fs/ntfs3/bitmap.c | 62 ++----- - fs/ntfs3/file.c | 34 ++-- - fs/ntfs3/frecord.c | 104 ++---------- + fs/ntfs3/file.c | 32 ++-- + fs/ntfs3/frecord.c | 104 ++--------- fs/ntfs3/fsntfs.c | 2 +- fs/ntfs3/ntfs_fs.h | 3 +- fs/ntfs3/record.c | 16 +- fs/ntfs3/run.c | 40 +++-- - include/linux/compiler_attributes.h | 13 -- - include/linux/compiler_types.h | 19 +++ include/linux/mm_types.h | 1 + - init/Kconfig | 8 + + include/linux/sched/ext.h | 1 + + kernel/futex/core.c | 22 --- + kernel/futex/futex.h | 59 +++++- + kernel/kprobes.c | 23 ++- + kernel/sched/ext.c | 9 +- kernel/workqueue.c | 22 ++- - lib/overflow_kunit.c | 2 +- mm/mmap.c | 1 + scripts/package/PKGBUILD | 5 + - 36 files changed, 867 insertions(+), 727 deletions(-) + sound/pci/hda/patch_realtek.c | 2 + + 43 files changed, 1103 insertions(+), 755 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 00551f340dbe..833b2344ce79 100644 @@ -14776,6 +15177,32 @@ index 00551f340dbe..833b2344ce79 100644 depends on HAVE_ARCH_MMAP_RND_COMPAT_BITS help This value can be used to select the number of bits to use to +diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h +index 99d345b686fa..6e2458088800 100644 +--- a/arch/x86/include/asm/futex.h ++++ b/arch/x86/include/asm/futex.h +@@ -48,7 +48,9 @@ do { \ + static __always_inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) + { +- if (!user_access_begin(uaddr, sizeof(u32))) ++ if (can_do_masked_user_access()) ++ uaddr = masked_user_access_begin(uaddr); ++ else if (!user_access_begin(uaddr, sizeof(u32))) + return -EFAULT; + + switch (op) { +@@ -84,7 +86,9 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + { + int ret = 0; + +- if (!user_access_begin(uaddr, sizeof(u32))) ++ if (can_do_masked_user_access()) ++ uaddr = masked_user_access_begin(uaddr); ++ else if (!user_access_begin(uaddr, sizeof(u32))) + return -EFAULT; + asm volatile("\n" + "1:\t" LOCK_PREFIX "cmpxchgl %3, %2\n" diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index d17518ca19b8..8b66a555d2f0 100644 --- a/arch/x86/kernel/alternative.c @@ -14810,10 +15237,10 @@ index d17518ca19b8..8b66a555d2f0 100644 { memcpy(dst, src, len); diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c -index 86593d1b787d..1aac4fa90d3d 100644 +index b0678d59ebdb..3059b675101c 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c -@@ -568,7 +568,7 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next, +@@ -569,7 +569,7 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next, * mm_cpumask. The TLB shootdown code can figure out from * cpu_tlbstate_shared.is_lazy whether or not to send an IPI. */ @@ -14822,7 +15249,7 @@ index 86593d1b787d..1aac4fa90d3d 100644 !cpumask_test_cpu(cpu, mm_cpumask(next)))) cpumask_set_cpu(cpu, mm_cpumask(next)); -@@ -606,18 +606,15 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next, +@@ -607,18 +607,15 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next, cond_mitigation(tsk); /* @@ -14847,7 +15274,7 @@ index 86593d1b787d..1aac4fa90d3d 100644 cpumask_set_cpu(cpu, mm_cpumask(next)); next_tlb_gen = atomic64_read(&next->context.tlb_gen); -@@ -761,8 +758,11 @@ static void flush_tlb_func(void *info) +@@ -762,8 +759,11 @@ static void flush_tlb_func(void *info) count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED); /* Can only happen on remote CPUs */ @@ -14860,8 +15287,43 @@ index 86593d1b787d..1aac4fa90d3d 100644 } if (unlikely(loaded_mm == &init_mm)) +diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c +index 480e4adba9fa..3626faab9c91 100644 +--- a/drivers/bluetooth/btmtk.c ++++ b/drivers/bluetooth/btmtk.c +@@ -1325,7 +1325,6 @@ int btmtk_usb_setup(struct hci_dev *hdev) + fwname = FIRMWARE_MT7668; + break; + case 0x7922: +- case 0x7961: + case 0x7925: + /* Reset the device to ensure it's in the initial state before + * downloading the firmware to ensure. +@@ -1333,7 +1332,8 @@ int btmtk_usb_setup(struct hci_dev *hdev) + + if (!test_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags)) + btmtk_usb_subsys_reset(hdev, dev_id); +- ++ fallthrough; ++ case 0x7961: + btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id, + fw_version, fw_flavor); + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 4ccaddb46ddd..80f9e88f89b8 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -636,6 +636,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe11e), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0489, 0xe124), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3603), .driver_info = BTUSB_MEDIATEK | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -index 7617963901fa..9726c4a5842a 100644 +index 7617963901fa..9f992e09de86 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -273,6 +273,8 @@ extern int amdgpu_agp; @@ -14873,8 +15335,112 @@ index 7617963901fa..9726c4a5842a 100644 #define AMDGPU_VM_MAX_NUM_CTX 4096 #define AMDGPU_SG_THRESHOLD (256*1024*1024) #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 +@@ -855,6 +857,7 @@ struct amdgpu_device { + bool need_swiotlb; + bool accel_working; + struct notifier_block acpi_nb; ++ struct notifier_block pm_nb; + struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS]; + struct debugfs_blob_wrapper debugfs_vbios_blob; + struct debugfs_blob_wrapper debugfs_discovery_blob; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index c2394c8b4d6b..046a2c8ec0bd 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -145,6 +145,8 @@ const char *amdgpu_asic_name[] = { + }; + + static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev); ++static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode, ++ void *data); + + /** + * DOC: pcie_replay_count +@@ -4469,6 +4471,11 @@ int amdgpu_device_init(struct amdgpu_device *adev, + + amdgpu_device_check_iommu_direct_map(adev); + ++ adev->pm_nb.notifier_call = amdgpu_device_pm_notifier; ++ r = register_pm_notifier(&adev->pm_nb); ++ if (r) ++ goto failed; ++ + return 0; + + release_ras_con: +@@ -4533,6 +4540,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) + drain_workqueue(adev->mman.bdev.wq); + adev->shutdown = true; + ++ unregister_pm_notifier(&adev->pm_nb); ++ + /* make sure IB test finished before entering exclusive mode + * to avoid preemption on IB test + */ +@@ -4650,8 +4659,8 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev) + { + int ret; + +- /* No need to evict vram on APUs for suspend to ram or s2idle */ +- if ((adev->in_s3 || adev->in_s0ix) && (adev->flags & AMD_IS_APU)) ++ /* No need to evict vram on APUs unless going to S4 */ ++ if (!adev->in_s4 && (adev->flags & AMD_IS_APU)) + return 0; + + ret = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM); +@@ -4663,6 +4672,41 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev) + /* + * Suspend & resume. + */ ++/** ++ * amdgpu_device_pm_notifier - Notification block for Suspend/Hibernate events ++ * @nb: notifier block ++ * @mode: suspend mode ++ * @data: data ++ * ++ * This function is called when the system is about to suspend or hibernate. ++ * It is used to evict resources from the device before the system goes to ++ * sleep while there is still access to swap. ++ */ ++static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode, ++ void *data) ++{ ++ struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, pm_nb); ++ int r; ++ ++ switch (mode) { ++ case PM_HIBERNATION_PREPARE: ++ adev->in_s4 = true; ++ fallthrough; ++ case PM_SUSPEND_PREPARE: ++ r = amdgpu_device_evict_resources(adev); ++ /* ++ * This is considered non-fatal at this time because ++ * amdgpu_device_prepare() will also fatally evict resources. ++ * See https://gitlab.freedesktop.org/drm/amd/-/issues/3781 ++ */ ++ if (r) ++ drm_warn(adev_to_drm(adev), "Failed to evict resources, freeze active processes if problems occur: %d\n", r); ++ break; ++ } ++ ++ return NOTIFY_DONE; ++} ++ + /** + * amdgpu_device_prepare - prepare for device suspend + * +@@ -4702,7 +4746,7 @@ int amdgpu_device_prepare(struct drm_device *dev) + return 0; + + unprepare: +- adev->in_s0ix = adev->in_s3 = false; ++ adev->in_s0ix = adev->in_s3 = adev->in_s4 = false; + + return r; + } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index 852e6f315576..ebc13f056153 100644 +index 852e6f315576..0f085a044240 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -260,6 +260,8 @@ struct amdgpu_watchdog_timer amdgpu_watchdog_timer = { @@ -14886,7 +15452,15 @@ index 852e6f315576..ebc13f056153 100644 /** * DOC: ignore_min_pcap (int) * Ignore the minimum power cap. -@@ -3056,6 +3058,21 @@ static struct pci_driver amdgpu_kms_pci_driver = { +@@ -2639,7 +2641,6 @@ static int amdgpu_pmops_freeze(struct device *dev) + struct amdgpu_device *adev = drm_to_adev(drm_dev); + int r; + +- adev->in_s4 = true; + r = amdgpu_device_suspend(drm_dev, true); + adev->in_s4 = false; + if (r) +@@ -3056,6 +3057,21 @@ static struct pci_driver amdgpu_kms_pci_driver = { .dev_groups = amdgpu_sysfs_groups, }; @@ -14908,7 +15482,7 @@ index 852e6f315576..ebc13f056153 100644 static int __init amdgpu_init(void) { int r; -@@ -3063,6 +3080,10 @@ static int __init amdgpu_init(void) +@@ -3063,6 +3079,10 @@ static int __init amdgpu_init(void) if (drm_firmware_drivers_only()) return -EINVAL; @@ -14919,7 +15493,7 @@ index 852e6f315576..ebc13f056153 100644 r = amdgpu_sync_init(); if (r) goto error_sync; -@@ -3078,6 +3099,11 @@ static int __init amdgpu_init(void) +@@ -3078,6 +3098,11 @@ static int __init amdgpu_init(void) /* Ignore KFD init failures. Normal when CONFIG_HSA_AMD is not set. */ amdgpu_amdkfd_init(); @@ -14931,7 +15505,7 @@ index 852e6f315576..ebc13f056153 100644 /* let modprobe override vga console setting */ return pci_register_driver(&amdgpu_kms_pci_driver); -@@ -3085,6 +3111,9 @@ static int __init amdgpu_init(void) +@@ -3085,6 +3110,9 @@ static int __init amdgpu_init(void) amdgpu_sync_fini(); error_sync: @@ -14941,7 +15515,7 @@ index 852e6f315576..ebc13f056153 100644 return r; } -@@ -3096,6 +3125,7 @@ static void __exit amdgpu_exit(void) +@@ -3096,6 +3124,7 @@ static void __exit amdgpu_exit(void) amdgpu_acpi_release(); amdgpu_sync_fini(); amdgpu_fence_slab_fini(); @@ -14950,10 +15524,10 @@ index 852e6f315576..ebc13f056153 100644 amdgpu_xcp_drv_release(); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -index f1ffab5a1eae..15614e43be5a 100644 +index 156abd2ba5a6..72a528f73000 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -@@ -800,8 +800,9 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) +@@ -827,8 +827,9 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) AMD_IP_BLOCK_TYPE_GFX, true)) adev->gfx.gfx_off_state = true; } else { @@ -14965,8 +15539,25 @@ index f1ffab5a1eae..15614e43be5a 100644 } } } else { +diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c +index d4a6cf6e98e8..20d28c68593d 100644 +--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c +@@ -1409,7 +1409,11 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, + * create a custom set of heuristics, write a string of numbers to the file + * starting with the number of the custom profile along with a setting + * for each heuristic parameter. Due to differences across asic families +- * the heuristic parameters vary from family to family. ++ * the heuristic parameters vary from family to family. Additionally, ++ * you can apply the custom heuristics to different clock domains. Each ++ * clock domain is considered a distinct operation so if you modify the ++ * gfxclk heuristics and then the memclk heuristics, the all of the ++ * custom heuristics will be retained until you switch to another profile. + * + */ + diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -index 44f0b159d232..953fcd37749b 100644 +index 44f0b159d232..7abf6fc9cbbe 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -72,6 +72,10 @@ static int smu_set_power_limit(void *handle, uint32_t limit); @@ -15020,7 +15611,19 @@ index 44f0b159d232..953fcd37749b 100644 smu->display_config = &adev->pm.pm_display_cfg; smu->smu_dpm.dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; -@@ -2113,6 +2101,9 @@ static int smu_suspend(void *handle) +@@ -1338,6 +1326,11 @@ static int smu_sw_fini(void *handle) + return ret; + } + ++ if (smu->custom_profile_params) { ++ kfree(smu->custom_profile_params); ++ smu->custom_profile_params = NULL; ++ } ++ + smu_fini_microcode(smu); + + return 0; +@@ -2113,6 +2106,9 @@ static int smu_suspend(void *handle) if (!ret) adev->gfx.gfx_off_entrycount = count; @@ -15030,14 +15633,14 @@ index 44f0b159d232..953fcd37749b 100644 return 0; } -@@ -2224,26 +2215,46 @@ static int smu_enable_umd_pstate(void *handle, - return 0; +@@ -2225,25 +2221,49 @@ static int smu_enable_umd_pstate(void *handle, } --static int smu_bump_power_profile_mode(struct smu_context *smu, + static int smu_bump_power_profile_mode(struct smu_context *smu, - long *param, - uint32_t param_size) -+static int smu_bump_power_profile_mode(struct smu_context *smu) ++ long *custom_params, ++ u32 custom_params_max_idx) { - int ret = 0; + u32 workload_mask = 0; @@ -15053,7 +15656,9 @@ index 44f0b159d232..953fcd37749b 100644 if (smu->ppt_funcs->set_power_profile_mode) - ret = smu->ppt_funcs->set_power_profile_mode(smu, param, param_size); -+ ret = smu->ppt_funcs->set_power_profile_mode(smu, workload_mask); ++ ret = smu->ppt_funcs->set_power_profile_mode(smu, workload_mask, ++ custom_params, ++ custom_params_max_idx); + + if (!ret) + smu->workload_mask = workload_mask; @@ -15086,7 +15691,7 @@ index 44f0b159d232..953fcd37749b 100644 struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); if (!skip_display_settings) { -@@ -2280,14 +2291,8 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, +@@ -2280,14 +2300,8 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, } if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && @@ -15099,11 +15704,11 @@ index 44f0b159d232..953fcd37749b 100644 - smu_bump_power_profile_mode(smu, workload, 0); - } + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) -+ smu_bump_power_profile_mode(smu); ++ smu_bump_power_profile_mode(smu, NULL, 0); return ret; } -@@ -2306,13 +2311,13 @@ static int smu_handle_task(struct smu_context *smu, +@@ -2306,13 +2320,13 @@ static int smu_handle_task(struct smu_context *smu, ret = smu_pre_display_config_changed(smu); if (ret) return ret; @@ -15120,7 +15725,7 @@ index 44f0b159d232..953fcd37749b 100644 break; default: break; -@@ -2334,12 +2339,11 @@ static int smu_handle_dpm_task(void *handle, +@@ -2334,12 +2348,11 @@ static int smu_handle_dpm_task(void *handle, static int smu_switch_power_profile(void *handle, enum PP_SMC_POWER_PROFILE type, @@ -15135,7 +15740,7 @@ index 44f0b159d232..953fcd37749b 100644 if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; -@@ -2347,21 +2351,21 @@ static int smu_switch_power_profile(void *handle, +@@ -2347,21 +2360,21 @@ static int smu_switch_power_profile(void *handle, if (!(type < PP_SMC_POWER_PROFILE_CUSTOM)) return -EINVAL; @@ -15159,7 +15764,7 @@ index 44f0b159d232..953fcd37749b 100644 + smu_power_profile_mode_get(smu, type); + else + smu_power_profile_mode_put(smu, type); -+ ret = smu_bump_power_profile_mode(smu); ++ ret = smu_bump_power_profile_mode(smu, NULL, 0); + if (ret) { + if (enable) + smu_power_profile_mode_put(smu, type); @@ -15171,12 +15776,12 @@ index 44f0b159d232..953fcd37749b 100644 return 0; } -@@ -3063,12 +3067,48 @@ static int smu_set_power_profile_mode(void *handle, +@@ -3063,12 +3076,35 @@ static int smu_set_power_profile_mode(void *handle, uint32_t param_size) { struct smu_context *smu = handle; -+ bool custom_changed = false; -+ int ret = 0, i; ++ bool custom = false; ++ int ret = 0; if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled || !smu->ppt_funcs->set_power_profile_mode) @@ -15184,32 +15789,19 @@ index 44f0b159d232..953fcd37749b 100644 - return smu_bump_power_profile_mode(smu, param, param_size); + if (param[param_size] == PP_SMC_POWER_PROFILE_CUSTOM) { -+ if (param_size > SMU_BACKEND_MAX_CUSTOM_PARAMETERS) -+ return -EINVAL; -+ /* param_size is actually a max index, not an array size */ -+ for (i = 0; i <= param_size; i++) { -+ if (smu->custom_profile_input[i] != param[i]) { -+ custom_changed = true; -+ break; -+ } -+ } ++ custom = true; ++ /* clear frontend mask so custom changes propogate */ ++ smu->workload_mask = 0; + } + -+ if ((param[param_size] != smu->power_profile_mode) || custom_changed) { -+ /* save the parameters for custom */ -+ if (custom_changed) { -+ /* param_size is actually a max index, not an array size */ -+ for (i = 0; i <= param_size; i++) -+ smu->custom_profile_input[i] = param[i]; -+ smu->custom_profile_size = param_size; -+ /* clear frontend mask so custom changes propogate */ -+ smu->workload_mask = 0; -+ } ++ if ((param[param_size] != smu->power_profile_mode) || custom) { + /* clear the old user preference */ + smu_power_profile_mode_put(smu, smu->power_profile_mode); + /* set the new user preference */ + smu_power_profile_mode_get(smu, param[param_size]); -+ ret = smu_bump_power_profile_mode(smu); ++ ret = smu_bump_power_profile_mode(smu, ++ custom ? param : NULL, ++ custom ? param_size : 0); + if (ret) + smu_power_profile_mode_put(smu, param[param_size]); + else @@ -15222,19 +15814,10 @@ index 44f0b159d232..953fcd37749b 100644 static int smu_get_fan_control_mode(void *handle, u32 *fan_mode) diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -index b44a185d07e8..cd71663462ff 100644 +index b44a185d07e8..2b8a18ce25d9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -@@ -509,6 +509,8 @@ enum smu_fw_status { - */ - #define SMU_WBRF_EVENT_HANDLING_PACE 10 - -+#define SMU_BACKEND_MAX_CUSTOM_PARAMETERS 11 -+ - struct smu_context { - struct amdgpu_device *adev; - struct amdgpu_irq_src irq_source; -@@ -556,11 +558,14 @@ struct smu_context { +@@ -556,11 +556,13 @@ struct smu_context { uint32_t hard_min_uclk_req_from_dal; bool disable_uclk_switch; @@ -15247,49 +15830,52 @@ index b44a185d07e8..cd71663462ff 100644 - uint32_t default_power_profile_mode; + uint32_t workload_refcount[PP_SMC_POWER_PROFILE_COUNT]; + /* backend specific custom workload settings */ -+ long custom_profile_input[SMU_BACKEND_MAX_CUSTOM_PARAMETERS]; -+ bool custom_profile_size; ++ long *custom_profile_params; bool pm_enabled; bool is_apu; -@@ -731,9 +736,9 @@ struct pptable_funcs { +@@ -731,9 +733,12 @@ struct pptable_funcs { * @set_power_profile_mode: Set a power profile mode. Also used to * create/set custom power profile modes. * &input: Power profile mode parameters. - * &size: Size of &input. + * &workload_mask: mask of workloads to enable ++ * &custom_params: custom profile parameters ++ * &custom_params_max_idx: max valid idx into custom_params */ - int (*set_power_profile_mode)(struct smu_context *smu, long *input, uint32_t size); -+ int (*set_power_profile_mode)(struct smu_context *smu, u32 workload_mask); ++ int (*set_power_profile_mode)(struct smu_context *smu, u32 workload_mask, ++ long *custom_params, u32 custom_params_max_idx); /** * @dpm_set_vcn_enable: Enable/disable VCN engine dynamic power diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c -index c0f6b59369b7..2d56ece1861f 100644 +index c0f6b59369b7..f4c64c46ff7a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c -@@ -1441,98 +1441,96 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, +@@ -1441,98 +1441,120 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, return size; } -static int arcturus_set_power_profile_mode(struct smu_context *smu, - long *input, - uint32_t size) ++#define ARCTURUS_CUSTOM_PARAMS_COUNT 10 ++#define ARCTURUS_CUSTOM_PARAMS_CLOCK_COUNT 2 ++#define ARCTURUS_CUSTOM_PARAMS_SIZE (ARCTURUS_CUSTOM_PARAMS_CLOCK_COUNT * ARCTURUS_CUSTOM_PARAMS_COUNT * sizeof(long)) ++ +static int arcturus_set_power_profile_mode_coeff(struct smu_context *smu, -+ long *input, -+ uint32_t size) ++ long *input) { DpmActivityMonitorCoeffInt_t activity_monitor; - int workload_type = 0; - uint32_t profile_mode = input[size]; - int ret = 0; -+ int ret; ++ int ret, idx; - if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode); -+ if (size != 10) - return -EINVAL; -+ +- return -EINVAL; + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, + WORKLOAD_PPLIB_CUSTOM_BIT, @@ -15300,31 +15886,31 @@ index c0f6b59369b7..2d56ece1861f 100644 + return ret; } -+ switch (input[0]) { -+ case 0: /* Gfxclk */ -+ activity_monitor.Gfx_FPS = input[1]; -+ activity_monitor.Gfx_UseRlcBusy = input[2]; -+ activity_monitor.Gfx_MinActiveFreqType = input[3]; -+ activity_monitor.Gfx_MinActiveFreq = input[4]; -+ activity_monitor.Gfx_BoosterFreqType = input[5]; -+ activity_monitor.Gfx_BoosterFreq = input[6]; -+ activity_monitor.Gfx_PD_Data_limit_c = input[7]; -+ activity_monitor.Gfx_PD_Data_error_coeff = input[8]; -+ activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9]; -+ break; -+ case 1: /* Uclk */ -+ activity_monitor.Mem_FPS = input[1]; -+ activity_monitor.Mem_UseRlcBusy = input[2]; -+ activity_monitor.Mem_MinActiveFreqType = input[3]; -+ activity_monitor.Mem_MinActiveFreq = input[4]; -+ activity_monitor.Mem_BoosterFreqType = input[5]; -+ activity_monitor.Mem_BoosterFreq = input[6]; -+ activity_monitor.Mem_PD_Data_limit_c = input[7]; -+ activity_monitor.Mem_PD_Data_error_coeff = input[8]; -+ activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; -+ break; -+ default: -+ return -EINVAL; ++ idx = 0 * ARCTURUS_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Gfxclk */ ++ activity_monitor.Gfx_FPS = input[idx + 1]; ++ activity_monitor.Gfx_UseRlcBusy = input[idx + 2]; ++ activity_monitor.Gfx_MinActiveFreqType = input[idx + 3]; ++ activity_monitor.Gfx_MinActiveFreq = input[idx + 4]; ++ activity_monitor.Gfx_BoosterFreqType = input[idx + 5]; ++ activity_monitor.Gfx_BoosterFreq = input[idx + 6]; ++ activity_monitor.Gfx_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor.Gfx_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor.Gfx_PD_Data_error_rate_coeff = input[idx + 9]; ++ } ++ idx = 1 * ARCTURUS_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Uclk */ ++ activity_monitor.Mem_FPS = input[idx + 1]; ++ activity_monitor.Mem_UseRlcBusy = input[idx + 2]; ++ activity_monitor.Mem_MinActiveFreqType = input[idx + 3]; ++ activity_monitor.Mem_MinActiveFreq = input[idx + 4]; ++ activity_monitor.Mem_BoosterFreqType = input[idx + 5]; ++ activity_monitor.Mem_BoosterFreq = input[idx + 6]; ++ activity_monitor.Mem_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor.Mem_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor.Mem_PD_Data_error_rate_coeff = input[idx + 9]; + } - if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) && @@ -15377,29 +15963,52 @@ index c0f6b59369b7..2d56ece1861f 100644 - activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; - break; - default: -- return -EINVAL; -- } +static int arcturus_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) +{ + u32 backend_workload_mask = 0; -+ bool custom_enabled = false; -+ int ret; - ++ int ret, idx = -1, i; ++ ++ smu_cmn_get_backend_workload_mask(smu, workload_mask, ++ &backend_workload_mask); ++ ++ if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) { ++ if (smu->smc_fw_version < 0x360d00) + return -EINVAL; ++ if (!smu->custom_profile_params) { ++ smu->custom_profile_params = ++ kzalloc(ARCTURUS_CUSTOM_PARAMS_SIZE, GFP_KERNEL); ++ if (!smu->custom_profile_params) ++ return -ENOMEM; + } +- - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, - WORKLOAD_PPLIB_CUSTOM_BIT, - (void *)(&activity_monitor), - true); -- if (ret) { ++ if (custom_params && custom_params_max_idx) { ++ if (custom_params_max_idx != ARCTURUS_CUSTOM_PARAMS_COUNT) ++ return -EINVAL; ++ if (custom_params[0] >= ARCTURUS_CUSTOM_PARAMS_CLOCK_COUNT) ++ return -EINVAL; ++ idx = custom_params[0] * ARCTURUS_CUSTOM_PARAMS_COUNT; ++ smu->custom_profile_params[idx] = 1; ++ for (i = 1; i < custom_params_max_idx; i++) ++ smu->custom_profile_params[idx + i] = custom_params[i]; ++ } ++ ret = arcturus_set_power_profile_mode_coeff(smu, ++ smu->custom_profile_params); + if (ret) { - dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); -- return ret; -- } ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; + } - } -+ smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); - +- - /* - * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT - * Not all profile modes are supported on arcturus. @@ -15410,12 +16019,8 @@ index c0f6b59369b7..2d56ece1861f 100644 - if (workload_type < 0) { - dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on arcturus\n", profile_mode); - return -EINVAL; -+ if (custom_enabled) { -+ ret = arcturus_set_power_profile_mode_coeff(smu, -+ smu->custom_profile_input, -+ smu->custom_profile_size); -+ if (ret) -+ return ret; ++ } else if (smu->custom_profile_params) { ++ memset(smu->custom_profile_params, 0, ARCTURUS_CUSTOM_PARAMS_SIZE); } ret = smu_cmn_send_smc_msg_with_param(smu, @@ -15429,6 +16034,8 @@ index c0f6b59369b7..2d56ece1861f 100644 - dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type); + dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n", + workload_mask); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; return ret; } @@ -15440,28 +16047,26 @@ index c0f6b59369b7..2d56ece1861f 100644 static int arcturus_set_performance_level(struct smu_context *smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -index 16af1a329621..72e30a3d0242 100644 +index 16af1a329621..27c1892b2c74 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -@@ -2004,87 +2004,99 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) +@@ -2004,87 +2004,122 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) return size; } -static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) ++#define NAVI10_CUSTOM_PARAMS_COUNT 10 ++#define NAVI10_CUSTOM_PARAMS_CLOCKS_COUNT 3 ++#define NAVI10_CUSTOM_PARAMS_SIZE (NAVI10_CUSTOM_PARAMS_CLOCKS_COUNT * NAVI10_CUSTOM_PARAMS_COUNT * sizeof(long)) ++ +static int navi10_set_power_profile_mode_coeff(struct smu_context *smu, -+ long *input, -+ uint32_t size) ++ long *input) { DpmActivityMonitorCoeffInt_t activity_monitor; - int workload_type, ret = 0; -+ int ret; ++ int ret, idx; - smu->power_profile_mode = input[size]; -+ if (size != 10) -+ return -EINVAL; - -- if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { -- dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, + (void *)(&activity_monitor), false); @@ -15469,55 +16074,63 @@ index 16af1a329621..72e30a3d0242 100644 + dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); + return ret; + } -+ -+ switch (input[0]) { -+ case 0: /* Gfxclk */ -+ activity_monitor.Gfx_FPS = input[1]; -+ activity_monitor.Gfx_MinFreqStep = input[2]; -+ activity_monitor.Gfx_MinActiveFreqType = input[3]; -+ activity_monitor.Gfx_MinActiveFreq = input[4]; -+ activity_monitor.Gfx_BoosterFreqType = input[5]; -+ activity_monitor.Gfx_BoosterFreq = input[6]; -+ activity_monitor.Gfx_PD_Data_limit_c = input[7]; -+ activity_monitor.Gfx_PD_Data_error_coeff = input[8]; -+ activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9]; -+ break; -+ case 1: /* Socclk */ -+ activity_monitor.Soc_FPS = input[1]; -+ activity_monitor.Soc_MinFreqStep = input[2]; -+ activity_monitor.Soc_MinActiveFreqType = input[3]; -+ activity_monitor.Soc_MinActiveFreq = input[4]; -+ activity_monitor.Soc_BoosterFreqType = input[5]; -+ activity_monitor.Soc_BoosterFreq = input[6]; -+ activity_monitor.Soc_PD_Data_limit_c = input[7]; -+ activity_monitor.Soc_PD_Data_error_coeff = input[8]; -+ activity_monitor.Soc_PD_Data_error_rate_coeff = input[9]; -+ break; -+ case 2: /* Memclk */ -+ activity_monitor.Mem_FPS = input[1]; -+ activity_monitor.Mem_MinFreqStep = input[2]; -+ activity_monitor.Mem_MinActiveFreqType = input[3]; -+ activity_monitor.Mem_MinActiveFreq = input[4]; -+ activity_monitor.Mem_BoosterFreqType = input[5]; -+ activity_monitor.Mem_BoosterFreq = input[6]; -+ activity_monitor.Mem_PD_Data_limit_c = input[7]; -+ activity_monitor.Mem_PD_Data_error_coeff = input[8]; -+ activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; -+ break; -+ default: - return -EINVAL; - } -- if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { -- if (size != 10) -- return -EINVAL; +- if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { +- dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); +- return -EINVAL; ++ idx = 0 * NAVI10_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Gfxclk */ ++ activity_monitor.Gfx_FPS = input[idx + 1]; ++ activity_monitor.Gfx_MinFreqStep = input[idx + 2]; ++ activity_monitor.Gfx_MinActiveFreqType = input[idx + 3]; ++ activity_monitor.Gfx_MinActiveFreq = input[idx + 4]; ++ activity_monitor.Gfx_BoosterFreqType = input[idx + 5]; ++ activity_monitor.Gfx_BoosterFreq = input[idx + 6]; ++ activity_monitor.Gfx_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor.Gfx_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor.Gfx_PD_Data_error_rate_coeff = input[idx + 9]; ++ } ++ idx = 1 * NAVI10_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Socclk */ ++ activity_monitor.Soc_FPS = input[idx + 1]; ++ activity_monitor.Soc_MinFreqStep = input[idx + 2]; ++ activity_monitor.Soc_MinActiveFreqType = input[idx + 3]; ++ activity_monitor.Soc_MinActiveFreq = input[idx + 4]; ++ activity_monitor.Soc_BoosterFreqType = input[idx + 5]; ++ activity_monitor.Soc_BoosterFreq = input[idx + 6]; ++ activity_monitor.Soc_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor.Soc_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor.Soc_PD_Data_error_rate_coeff = input[idx + 9]; ++ } ++ idx = 2 * NAVI10_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Memclk */ ++ activity_monitor.Mem_FPS = input[idx + 1]; ++ activity_monitor.Mem_MinFreqStep = input[idx + 2]; ++ activity_monitor.Mem_MinActiveFreqType = input[idx + 3]; ++ activity_monitor.Mem_MinActiveFreq = input[idx + 4]; ++ activity_monitor.Mem_BoosterFreqType = input[idx + 5]; ++ activity_monitor.Mem_BoosterFreq = input[idx + 6]; ++ activity_monitor.Mem_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor.Mem_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor.Mem_PD_Data_error_rate_coeff = input[idx + 9]; ++ } ++ + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, + (void *)(&activity_monitor), true); + if (ret) { + dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); + return ret; -+ } + } + +- if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { +- if (size != 10) +- return -EINVAL; ++ return ret; ++} - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -15526,8 +16139,13 @@ index 16af1a329621..72e30a3d0242 100644 - dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); - return ret; - } -+ return ret; -+} ++static int navi10_set_power_profile_mode(struct smu_context *smu, ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) ++{ ++ u32 backend_workload_mask = 0; ++ int ret, idx = -1, i; - switch (input[0]) { - case 0: /* Gfxclk */ @@ -15566,29 +16184,38 @@ index 16af1a329621..72e30a3d0242 100644 - default: - return -EINVAL; - } -+static int navi10_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) -+{ -+ u32 backend_workload_mask = 0; -+ bool custom_enabled = false; -+ int ret; ++ smu_cmn_get_backend_workload_mask(smu, workload_mask, ++ &backend_workload_mask); - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, - (void *)(&activity_monitor), true); -- if (ret) { -- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); -+ smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); -+ -+ if (custom_enabled) { ++ if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) { ++ if (!smu->custom_profile_params) { ++ smu->custom_profile_params = kzalloc(NAVI10_CUSTOM_PARAMS_SIZE, GFP_KERNEL); ++ if (!smu->custom_profile_params) ++ return -ENOMEM; ++ } ++ if (custom_params && custom_params_max_idx) { ++ if (custom_params_max_idx != NAVI10_CUSTOM_PARAMS_COUNT) ++ return -EINVAL; ++ if (custom_params[0] >= NAVI10_CUSTOM_PARAMS_CLOCKS_COUNT) ++ return -EINVAL; ++ idx = custom_params[0] * NAVI10_CUSTOM_PARAMS_COUNT; ++ smu->custom_profile_params[idx] = 1; ++ for (i = 1; i < custom_params_max_idx; i++) ++ smu->custom_profile_params[idx + i] = custom_params[i]; ++ } + ret = navi10_set_power_profile_mode_coeff(smu, -+ smu->custom_profile_input, -+ smu->custom_profile_size); -+ if (ret) ++ smu->custom_profile_params); + if (ret) { +- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; return ret; -- } + } ++ } else if (smu->custom_profile_params) { ++ memset(smu->custom_profile_params, 0, NAVI10_CUSTOM_PARAMS_SIZE); } - /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ @@ -15605,32 +16232,35 @@ index 16af1a329621..72e30a3d0242 100644 + if (ret) { + dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n", + workload_mask); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; + } return ret; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -index 9c3c48297cba..4945a3dda73e 100644 +index 9c3c48297cba..1af90990d05c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -@@ -1706,90 +1706,101 @@ static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char * +@@ -1706,90 +1706,126 @@ static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char * return size; } -static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) ++#define SIENNA_CICHLID_CUSTOM_PARAMS_COUNT 10 ++#define SIENNA_CICHLID_CUSTOM_PARAMS_CLOCK_COUNT 3 ++#define SIENNA_CICHLID_CUSTOM_PARAMS_SIZE (SIENNA_CICHLID_CUSTOM_PARAMS_CLOCK_COUNT * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT * sizeof(long)) ++ +static int sienna_cichlid_set_power_profile_mode_coeff(struct smu_context *smu, -+ long *input, uint32_t size) ++ long *input) { DpmActivityMonitorCoeffIntExternal_t activity_monitor_external; DpmActivityMonitorCoeffInt_t *activity_monitor = &(activity_monitor_external.DpmActivityMonitorCoeffInt); - int workload_type, ret = 0; -+ int ret; -+ -+ if (size != 10) -+ return -EINVAL; ++ int ret, idx; - smu->power_profile_mode = input[size]; + ret = smu_cmn_update_table(smu, @@ -15643,42 +16273,45 @@ index 9c3c48297cba..4945a3dda73e 100644 - if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); -+ switch (input[0]) { -+ case 0: /* Gfxclk */ -+ activity_monitor->Gfx_FPS = input[1]; -+ activity_monitor->Gfx_MinFreqStep = input[2]; -+ activity_monitor->Gfx_MinActiveFreqType = input[3]; -+ activity_monitor->Gfx_MinActiveFreq = input[4]; -+ activity_monitor->Gfx_BoosterFreqType = input[5]; -+ activity_monitor->Gfx_BoosterFreq = input[6]; -+ activity_monitor->Gfx_PD_Data_limit_c = input[7]; -+ activity_monitor->Gfx_PD_Data_error_coeff = input[8]; -+ activity_monitor->Gfx_PD_Data_error_rate_coeff = input[9]; -+ break; -+ case 1: /* Socclk */ -+ activity_monitor->Fclk_FPS = input[1]; -+ activity_monitor->Fclk_MinFreqStep = input[2]; -+ activity_monitor->Fclk_MinActiveFreqType = input[3]; -+ activity_monitor->Fclk_MinActiveFreq = input[4]; -+ activity_monitor->Fclk_BoosterFreqType = input[5]; -+ activity_monitor->Fclk_BoosterFreq = input[6]; -+ activity_monitor->Fclk_PD_Data_limit_c = input[7]; -+ activity_monitor->Fclk_PD_Data_error_coeff = input[8]; -+ activity_monitor->Fclk_PD_Data_error_rate_coeff = input[9]; -+ break; -+ case 2: /* Memclk */ -+ activity_monitor->Mem_FPS = input[1]; -+ activity_monitor->Mem_MinFreqStep = input[2]; -+ activity_monitor->Mem_MinActiveFreqType = input[3]; -+ activity_monitor->Mem_MinActiveFreq = input[4]; -+ activity_monitor->Mem_BoosterFreqType = input[5]; -+ activity_monitor->Mem_BoosterFreq = input[6]; -+ activity_monitor->Mem_PD_Data_limit_c = input[7]; -+ activity_monitor->Mem_PD_Data_error_coeff = input[8]; -+ activity_monitor->Mem_PD_Data_error_rate_coeff = input[9]; -+ break; -+ default: - return -EINVAL; +- return -EINVAL; ++ idx = 0 * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Gfxclk */ ++ activity_monitor->Gfx_FPS = input[idx + 1]; ++ activity_monitor->Gfx_MinFreqStep = input[idx + 2]; ++ activity_monitor->Gfx_MinActiveFreqType = input[idx + 3]; ++ activity_monitor->Gfx_MinActiveFreq = input[idx + 4]; ++ activity_monitor->Gfx_BoosterFreqType = input[idx + 5]; ++ activity_monitor->Gfx_BoosterFreq = input[idx + 6]; ++ activity_monitor->Gfx_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor->Gfx_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor->Gfx_PD_Data_error_rate_coeff = input[idx + 9]; ++ } ++ idx = 1 * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Socclk */ ++ activity_monitor->Fclk_FPS = input[idx + 1]; ++ activity_monitor->Fclk_MinFreqStep = input[idx + 2]; ++ activity_monitor->Fclk_MinActiveFreqType = input[idx + 3]; ++ activity_monitor->Fclk_MinActiveFreq = input[idx + 4]; ++ activity_monitor->Fclk_BoosterFreqType = input[idx + 5]; ++ activity_monitor->Fclk_BoosterFreq = input[idx + 6]; ++ activity_monitor->Fclk_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor->Fclk_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor->Fclk_PD_Data_error_rate_coeff = input[idx + 9]; ++ } ++ idx = 2 * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Memclk */ ++ activity_monitor->Mem_FPS = input[idx + 1]; ++ activity_monitor->Mem_MinFreqStep = input[idx + 2]; ++ activity_monitor->Mem_MinActiveFreqType = input[idx + 3]; ++ activity_monitor->Mem_MinActiveFreq = input[idx + 4]; ++ activity_monitor->Mem_BoosterFreqType = input[idx + 5]; ++ activity_monitor->Mem_BoosterFreq = input[idx + 6]; ++ activity_monitor->Mem_PD_Data_limit_c = input[idx + 7]; ++ activity_monitor->Mem_PD_Data_error_coeff = input[idx + 8]; ++ activity_monitor->Mem_PD_Data_error_rate_coeff = input[idx + 9]; } - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { @@ -15738,30 +16371,48 @@ index 9c3c48297cba..4945a3dda73e 100644 - break; - default: - return -EINVAL; -- } +static int sienna_cichlid_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) +{ + u32 backend_workload_mask = 0; -+ bool custom_enabled = false; -+ int ret; - ++ int ret, idx = -1, i; ++ ++ smu_cmn_get_backend_workload_mask(smu, workload_mask, ++ &backend_workload_mask); ++ ++ if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) { ++ if (!smu->custom_profile_params) { ++ smu->custom_profile_params = ++ kzalloc(SIENNA_CICHLID_CUSTOM_PARAMS_SIZE, GFP_KERNEL); ++ if (!smu->custom_profile_params) ++ return -ENOMEM; + } +- - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, - (void *)(&activity_monitor_external), true); -- if (ret) { -- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); -+ smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); -+ -+ if (custom_enabled) { ++ if (custom_params && custom_params_max_idx) { ++ if (custom_params_max_idx != SIENNA_CICHLID_CUSTOM_PARAMS_COUNT) ++ return -EINVAL; ++ if (custom_params[0] >= SIENNA_CICHLID_CUSTOM_PARAMS_CLOCK_COUNT) ++ return -EINVAL; ++ idx = custom_params[0] * SIENNA_CICHLID_CUSTOM_PARAMS_COUNT; ++ smu->custom_profile_params[idx] = 1; ++ for (i = 1; i < custom_params_max_idx; i++) ++ smu->custom_profile_params[idx + i] = custom_params[i]; ++ } + ret = sienna_cichlid_set_power_profile_mode_coeff(smu, -+ smu->custom_profile_input, -+ smu->custom_profile_size); -+ if (ret) ++ smu->custom_profile_params); + if (ret) { +- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; return ret; -- } + } ++ } else if (smu->custom_profile_params) { ++ memset(smu->custom_profile_params, 0, SIENNA_CICHLID_CUSTOM_PARAMS_SIZE); } - /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ @@ -15778,13 +16429,15 @@ index 9c3c48297cba..4945a3dda73e 100644 + if (ret) { + dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n", + workload_mask); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; + } return ret; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c -index 1fe020f1f4db..85e2f926087b 100644 +index 1fe020f1f4db..9bca748ac2e9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -1054,42 +1054,27 @@ static int vangogh_get_power_profile_mode(struct smu_context *smu, @@ -15793,12 +16446,13 @@ index 1fe020f1f4db..85e2f926087b 100644 -static int vangogh_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) +static int vangogh_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) { - int workload_type, ret; - uint32_t profile_mode = input[size]; + u32 backend_workload_mask = 0; -+ bool custom_enabled = false; + int ret; - if (profile_mode >= PP_SMC_POWER_PROFILE_COUNT) { @@ -15820,8 +16474,7 @@ index 1fe020f1f4db..85e2f926087b 100644 - return -EINVAL; - } + smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); ++ &backend_workload_mask); ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify, - 1 << workload_type, @@ -15844,7 +16497,7 @@ index 1fe020f1f4db..85e2f926087b 100644 static int vangogh_set_soft_freq_limited_range(struct smu_context *smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c -index cc0504b063fa..70dd631c46dc 100644 +index cc0504b063fa..1a8a42b176e5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -862,44 +862,27 @@ static int renoir_force_clk_levels(struct smu_context *smu, @@ -15853,13 +16506,14 @@ index cc0504b063fa..70dd631c46dc 100644 -static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) +static int renoir_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) { - int workload_type, ret; - uint32_t profile_mode = input[size]; + int ret; + u32 backend_workload_mask = 0; -+ bool custom_enabled = false; - if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode); @@ -15883,8 +16537,7 @@ index cc0504b063fa..70dd631c46dc 100644 - return -EINVAL; - } + smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); ++ &backend_workload_mask); ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify, - 1 << workload_type, @@ -15906,7 +16559,7 @@ index cc0504b063fa..70dd631c46dc 100644 static int renoir_set_peak_clock_by_device(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c -index 24675a1d98db..9dfa01db0ec0 100644 +index 24675a1d98db..5fa58ef65371 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -2583,82 +2583,76 @@ static int smu_v13_0_0_get_power_profile_mode(struct smu_context *smu, @@ -15916,9 +16569,12 @@ index 24675a1d98db..9dfa01db0ec0 100644 -static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, - long *input, - uint32_t size) ++#define SMU_13_0_0_CUSTOM_PARAMS_COUNT 9 ++#define SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT 2 ++#define SMU_13_0_0_CUSTOM_PARAMS_SIZE (SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT * SMU_13_0_0_CUSTOM_PARAMS_COUNT * sizeof(long)) ++ +static int smu_v13_0_0_set_power_profile_mode_coeff(struct smu_context *smu, -+ long *input, -+ uint32_t size) ++ long *input) { DpmActivityMonitorCoeffIntExternal_t activity_monitor_external; DpmActivityMonitorCoeffInt_t *activity_monitor = @@ -15927,18 +16583,25 @@ index 24675a1d98db..9dfa01db0ec0 100644 - u32 workload_mask, selected_workload_mask; - - smu->power_profile_mode = input[size]; -+ int ret; ++ int ret, idx; - if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) { - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); -+ if (size != 9) - return -EINVAL; -- } -- +- return -EINVAL; ++ ret = smu_cmn_update_table(smu, ++ SMU_TABLE_ACTIVITY_MONITOR_COEFF, ++ WORKLOAD_PPLIB_CUSTOM_BIT, ++ (void *)(&activity_monitor_external), ++ false); ++ if (ret) { ++ dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); ++ return ret; + } + - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { - if (size != 9) - return -EINVAL; - +- - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, - WORKLOAD_PPLIB_CUSTOM_BIT, @@ -15948,16 +16611,7 @@ index 24675a1d98db..9dfa01db0ec0 100644 - dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); - return ret; - } -+ ret = smu_cmn_update_table(smu, -+ SMU_TABLE_ACTIVITY_MONITOR_COEFF, -+ WORKLOAD_PPLIB_CUSTOM_BIT, -+ (void *)(&activity_monitor_external), -+ false); -+ if (ret) { -+ dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); -+ return ret; -+ } - +- - switch (input[0]) { - case 0: /* Gfxclk */ - activity_monitor->Gfx_FPS = input[1]; @@ -15982,29 +16636,29 @@ index 24675a1d98db..9dfa01db0ec0 100644 - default: - return -EINVAL; - } -+ switch (input[0]) { -+ case 0: /* Gfxclk */ -+ activity_monitor->Gfx_FPS = input[1]; -+ activity_monitor->Gfx_MinActiveFreqType = input[2]; -+ activity_monitor->Gfx_MinActiveFreq = input[3]; -+ activity_monitor->Gfx_BoosterFreqType = input[4]; -+ activity_monitor->Gfx_BoosterFreq = input[5]; -+ activity_monitor->Gfx_PD_Data_limit_c = input[6]; -+ activity_monitor->Gfx_PD_Data_error_coeff = input[7]; -+ activity_monitor->Gfx_PD_Data_error_rate_coeff = input[8]; -+ break; -+ case 1: /* Fclk */ -+ activity_monitor->Fclk_FPS = input[1]; -+ activity_monitor->Fclk_MinActiveFreqType = input[2]; -+ activity_monitor->Fclk_MinActiveFreq = input[3]; -+ activity_monitor->Fclk_BoosterFreqType = input[4]; -+ activity_monitor->Fclk_BoosterFreq = input[5]; -+ activity_monitor->Fclk_PD_Data_limit_c = input[6]; -+ activity_monitor->Fclk_PD_Data_error_coeff = input[7]; -+ activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8]; -+ break; -+ default: -+ return -EINVAL; ++ idx = 0 * SMU_13_0_0_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Gfxclk */ ++ activity_monitor->Gfx_FPS = input[idx + 1]; ++ activity_monitor->Gfx_MinActiveFreqType = input[idx + 2]; ++ activity_monitor->Gfx_MinActiveFreq = input[idx + 3]; ++ activity_monitor->Gfx_BoosterFreqType = input[idx + 4]; ++ activity_monitor->Gfx_BoosterFreq = input[idx + 5]; ++ activity_monitor->Gfx_PD_Data_limit_c = input[idx + 6]; ++ activity_monitor->Gfx_PD_Data_error_coeff = input[idx + 7]; ++ activity_monitor->Gfx_PD_Data_error_rate_coeff = input[idx + 8]; ++ } ++ idx = 1 * SMU_13_0_0_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Fclk */ ++ activity_monitor->Fclk_FPS = input[idx + 1]; ++ activity_monitor->Fclk_MinActiveFreqType = input[idx + 2]; ++ activity_monitor->Fclk_MinActiveFreq = input[idx + 3]; ++ activity_monitor->Fclk_BoosterFreqType = input[idx + 4]; ++ activity_monitor->Fclk_BoosterFreq = input[idx + 5]; ++ activity_monitor->Fclk_PD_Data_limit_c = input[idx + 6]; ++ activity_monitor->Fclk_PD_Data_error_coeff = input[idx + 7]; ++ activity_monitor->Fclk_PD_Data_error_rate_coeff = input[idx + 8]; + } - ret = smu_cmn_update_table(smu, @@ -16036,20 +16690,20 @@ index 24675a1d98db..9dfa01db0ec0 100644 - if (workload_type < 0) - return -EINVAL; +static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) +{ + u32 backend_workload_mask = 0; -+ bool custom_enabled = false; -+ int workload_type, ret; ++ int workload_type, ret, idx = -1, i; - selected_workload_mask = workload_mask = 1 << workload_type; + smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); ++ &backend_workload_mask); /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) && -@@ -2670,15 +2664,26 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, +@@ -2670,15 +2664,48 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, CMN2ASIC_MAPPING_WORKLOAD, PP_SMC_POWER_PROFILE_POWERSAVING); if (workload_type >= 0) @@ -16057,12 +16711,32 @@ index 24675a1d98db..9dfa01db0ec0 100644 + backend_workload_mask |= 1 << workload_type; + } + -+ if (custom_enabled) { ++ if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) { ++ if (!smu->custom_profile_params) { ++ smu->custom_profile_params = ++ kzalloc(SMU_13_0_0_CUSTOM_PARAMS_SIZE, GFP_KERNEL); ++ if (!smu->custom_profile_params) ++ return -ENOMEM; ++ } ++ if (custom_params && custom_params_max_idx) { ++ if (custom_params_max_idx != SMU_13_0_0_CUSTOM_PARAMS_COUNT) ++ return -EINVAL; ++ if (custom_params[0] >= SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT) ++ return -EINVAL; ++ idx = custom_params[0] * SMU_13_0_0_CUSTOM_PARAMS_COUNT; ++ smu->custom_profile_params[idx] = 1; ++ for (i = 1; i < custom_params_max_idx; i++) ++ smu->custom_profile_params[idx + i] = custom_params[i]; ++ } + ret = smu_v13_0_0_set_power_profile_mode_coeff(smu, -+ smu->custom_profile_input, -+ smu->custom_profile_size); -+ if (ret) ++ smu->custom_profile_params); ++ if (ret) { ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; ++ } ++ } else if (smu->custom_profile_params) { ++ memset(smu->custom_profile_params, 0, SMU_13_0_0_CUSTOM_PARAMS_SIZE); } ret = smu_cmn_send_smc_msg_with_param(smu, @@ -16077,36 +16751,37 @@ index 24675a1d98db..9dfa01db0ec0 100644 + if (ret) { + dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n", + workload_mask); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; + } return ret; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c -index 50d16301f3eb..3ae328348d6f 100644 +index 50d16301f3eb..ed41de3d397a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c -@@ -2540,78 +2540,87 @@ do { \ +@@ -2540,78 +2540,110 @@ do { \ return result; } -static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) ++#define SMU_13_0_7_CUSTOM_PARAMS_COUNT 8 ++#define SMU_13_0_7_CUSTOM_PARAMS_CLOCK_COUNT 2 ++#define SMU_13_0_7_CUSTOM_PARAMS_SIZE (SMU_13_0_7_CUSTOM_PARAMS_CLOCK_COUNT * SMU_13_0_7_CUSTOM_PARAMS_COUNT * sizeof(long)) ++ +static int smu_v13_0_7_set_power_profile_mode_coeff(struct smu_context *smu, -+ long *input, uint32_t size) ++ long *input) { DpmActivityMonitorCoeffIntExternal_t activity_monitor_external; DpmActivityMonitorCoeffInt_t *activity_monitor = &(activity_monitor_external.DpmActivityMonitorCoeffInt); - int workload_type, ret = 0; -+ int ret; ++ int ret, idx; - smu->power_profile_mode = input[size]; -+ if (size != 8) -+ return -EINVAL; - -- if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) { -- dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, + (void *)(&activity_monitor_external), false); @@ -16114,28 +16789,31 @@ index 50d16301f3eb..3ae328348d6f 100644 + dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); + return ret; + } -+ -+ switch (input[0]) { -+ case 0: /* Gfxclk */ -+ activity_monitor->Gfx_ActiveHystLimit = input[1]; -+ activity_monitor->Gfx_IdleHystLimit = input[2]; -+ activity_monitor->Gfx_FPS = input[3]; -+ activity_monitor->Gfx_MinActiveFreqType = input[4]; -+ activity_monitor->Gfx_BoosterFreqType = input[5]; -+ activity_monitor->Gfx_MinActiveFreq = input[6]; -+ activity_monitor->Gfx_BoosterFreq = input[7]; -+ break; -+ case 1: /* Fclk */ -+ activity_monitor->Fclk_ActiveHystLimit = input[1]; -+ activity_monitor->Fclk_IdleHystLimit = input[2]; -+ activity_monitor->Fclk_FPS = input[3]; -+ activity_monitor->Fclk_MinActiveFreqType = input[4]; -+ activity_monitor->Fclk_BoosterFreqType = input[5]; -+ activity_monitor->Fclk_MinActiveFreq = input[6]; -+ activity_monitor->Fclk_BoosterFreq = input[7]; -+ break; -+ default: - return -EINVAL; + +- if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_WINDOW3D) { +- dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); +- return -EINVAL; ++ idx = 0 * SMU_13_0_7_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Gfxclk */ ++ activity_monitor->Gfx_ActiveHystLimit = input[idx + 1]; ++ activity_monitor->Gfx_IdleHystLimit = input[idx + 2]; ++ activity_monitor->Gfx_FPS = input[idx + 3]; ++ activity_monitor->Gfx_MinActiveFreqType = input[idx + 4]; ++ activity_monitor->Gfx_BoosterFreqType = input[idx + 5]; ++ activity_monitor->Gfx_MinActiveFreq = input[idx + 6]; ++ activity_monitor->Gfx_BoosterFreq = input[idx + 7]; ++ } ++ idx = 1 * SMU_13_0_7_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Fclk */ ++ activity_monitor->Fclk_ActiveHystLimit = input[idx + 1]; ++ activity_monitor->Fclk_IdleHystLimit = input[idx + 2]; ++ activity_monitor->Fclk_FPS = input[idx + 3]; ++ activity_monitor->Fclk_MinActiveFreqType = input[idx + 4]; ++ activity_monitor->Fclk_BoosterFreqType = input[idx + 5]; ++ activity_monitor->Fclk_MinActiveFreq = input[idx + 6]; ++ activity_monitor->Fclk_BoosterFreq = input[idx + 7]; } - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { @@ -16180,30 +16858,48 @@ index 50d16301f3eb..3ae328348d6f 100644 - break; - default: - return -EINVAL; -- } +static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) +{ + u32 backend_workload_mask = 0; -+ bool custom_enabled = false; -+ int ret; - ++ int ret, idx = -1, i; ++ ++ smu_cmn_get_backend_workload_mask(smu, workload_mask, ++ &backend_workload_mask); ++ ++ if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) { ++ if (!smu->custom_profile_params) { ++ smu->custom_profile_params = ++ kzalloc(SMU_13_0_7_CUSTOM_PARAMS_SIZE, GFP_KERNEL); ++ if (!smu->custom_profile_params) ++ return -ENOMEM; + } +- - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, - (void *)(&activity_monitor_external), true); -- if (ret) { -- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); -+ smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); -+ -+ if (custom_enabled) { ++ if (custom_params && custom_params_max_idx) { ++ if (custom_params_max_idx != SMU_13_0_7_CUSTOM_PARAMS_COUNT) ++ return -EINVAL; ++ if (custom_params[0] >= SMU_13_0_7_CUSTOM_PARAMS_CLOCK_COUNT) ++ return -EINVAL; ++ idx = custom_params[0] * SMU_13_0_7_CUSTOM_PARAMS_COUNT; ++ smu->custom_profile_params[idx] = 1; ++ for (i = 1; i < custom_params_max_idx; i++) ++ smu->custom_profile_params[idx + i] = custom_params[i]; ++ } + ret = smu_v13_0_7_set_power_profile_mode_coeff(smu, -+ smu->custom_profile_input, -+ smu->custom_profile_size); -+ if (ret) ++ smu->custom_profile_params); + if (ret) { +- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; return ret; -- } + } ++ } else if (smu->custom_profile_params) { ++ memset(smu->custom_profile_params, 0, SMU_13_0_7_CUSTOM_PARAMS_SIZE); } - /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ @@ -16223,25 +16919,30 @@ index 50d16301f3eb..3ae328348d6f 100644 + if (ret) { + dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n", + workload_mask); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; + } return ret; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c -index 1e16a281f2dc..aa147105a742 100644 +index 1e16a281f2dc..bfaa9e43f92a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c -@@ -1729,90 +1729,98 @@ static int smu_v14_0_2_get_power_profile_mode(struct smu_context *smu, +@@ -1729,90 +1729,120 @@ static int smu_v14_0_2_get_power_profile_mode(struct smu_context *smu, return size; } -static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu, - long *input, - uint32_t size) ++#define SMU_14_0_2_CUSTOM_PARAMS_COUNT 9 ++#define SMU_14_0_2_CUSTOM_PARAMS_CLOCK_COUNT 2 ++#define SMU_14_0_2_CUSTOM_PARAMS_SIZE (SMU_14_0_2_CUSTOM_PARAMS_CLOCK_COUNT * SMU_14_0_2_CUSTOM_PARAMS_COUNT * sizeof(long)) ++ +static int smu_v14_0_2_set_power_profile_mode_coeff(struct smu_context *smu, -+ long *input, -+ uint32_t size) ++ long *input) { DpmActivityMonitorCoeffIntExternal_t activity_monitor_external; DpmActivityMonitorCoeffInt_t *activity_monitor = @@ -16249,13 +16950,11 @@ index 1e16a281f2dc..aa147105a742 100644 - int workload_type, ret = 0; - uint32_t current_profile_mode = smu->power_profile_mode; - smu->power_profile_mode = input[size]; -+ int ret; ++ int ret, idx; - if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) { - dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); -+ if (size != 9) - return -EINVAL; -+ +- return -EINVAL; + ret = smu_cmn_update_table(smu, + SMU_TABLE_ACTIVITY_MONITOR_COEFF, + WORKLOAD_PPLIB_CUSTOM_BIT, @@ -16269,29 +16968,29 @@ index 1e16a281f2dc..aa147105a742 100644 - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { - if (size != 9) - return -EINVAL; -+ switch (input[0]) { -+ case 0: /* Gfxclk */ -+ activity_monitor->Gfx_FPS = input[1]; -+ activity_monitor->Gfx_MinActiveFreqType = input[2]; -+ activity_monitor->Gfx_MinActiveFreq = input[3]; -+ activity_monitor->Gfx_BoosterFreqType = input[4]; -+ activity_monitor->Gfx_BoosterFreq = input[5]; -+ activity_monitor->Gfx_PD_Data_limit_c = input[6]; -+ activity_monitor->Gfx_PD_Data_error_coeff = input[7]; -+ activity_monitor->Gfx_PD_Data_error_rate_coeff = input[8]; -+ break; -+ case 1: /* Fclk */ -+ activity_monitor->Fclk_FPS = input[1]; -+ activity_monitor->Fclk_MinActiveFreqType = input[2]; -+ activity_monitor->Fclk_MinActiveFreq = input[3]; -+ activity_monitor->Fclk_BoosterFreqType = input[4]; -+ activity_monitor->Fclk_BoosterFreq = input[5]; -+ activity_monitor->Fclk_PD_Data_limit_c = input[6]; -+ activity_monitor->Fclk_PD_Data_error_coeff = input[7]; -+ activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8]; -+ break; -+ default: -+ return -EINVAL; ++ idx = 0 * SMU_14_0_2_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Gfxclk */ ++ activity_monitor->Gfx_FPS = input[idx + 1]; ++ activity_monitor->Gfx_MinActiveFreqType = input[idx + 2]; ++ activity_monitor->Gfx_MinActiveFreq = input[idx + 3]; ++ activity_monitor->Gfx_BoosterFreqType = input[idx + 4]; ++ activity_monitor->Gfx_BoosterFreq = input[idx + 5]; ++ activity_monitor->Gfx_PD_Data_limit_c = input[idx + 6]; ++ activity_monitor->Gfx_PD_Data_error_coeff = input[idx + 7]; ++ activity_monitor->Gfx_PD_Data_error_rate_coeff = input[idx + 8]; ++ } ++ idx = 1 * SMU_14_0_2_CUSTOM_PARAMS_COUNT; ++ if (input[idx]) { ++ /* Fclk */ ++ activity_monitor->Fclk_FPS = input[idx + 1]; ++ activity_monitor->Fclk_MinActiveFreqType = input[idx + 2]; ++ activity_monitor->Fclk_MinActiveFreq = input[idx + 3]; ++ activity_monitor->Fclk_BoosterFreqType = input[idx + 4]; ++ activity_monitor->Fclk_BoosterFreq = input[idx + 5]; ++ activity_monitor->Fclk_PD_Data_limit_c = input[idx + 6]; ++ activity_monitor->Fclk_PD_Data_error_coeff = input[idx + 7]; ++ activity_monitor->Fclk_PD_Data_error_rate_coeff = input[idx + 8]; + } - ret = smu_cmn_update_table(smu, @@ -16351,15 +17050,15 @@ index 1e16a281f2dc..aa147105a742 100644 - } - } +static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu, -+ u32 workload_mask) ++ u32 workload_mask, ++ long *custom_params, ++ u32 custom_params_max_idx) +{ + u32 backend_workload_mask = 0; -+ bool custom_enabled = false; -+ int ret; ++ int ret, idx = -1, i; + + smu_cmn_get_backend_workload_mask(smu, workload_mask, -+ &backend_workload_mask, -+ &custom_enabled); ++ &backend_workload_mask); - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE) + /* disable deep sleep if compute is enabled */ @@ -16375,12 +17074,32 @@ index 1e16a281f2dc..aa147105a742 100644 - smu->power_profile_mode); - if (workload_type < 0) - return -EINVAL; -+ if (custom_enabled) { ++ if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) { ++ if (!smu->custom_profile_params) { ++ smu->custom_profile_params = ++ kzalloc(SMU_14_0_2_CUSTOM_PARAMS_SIZE, GFP_KERNEL); ++ if (!smu->custom_profile_params) ++ return -ENOMEM; ++ } ++ if (custom_params && custom_params_max_idx) { ++ if (custom_params_max_idx != SMU_14_0_2_CUSTOM_PARAMS_COUNT) ++ return -EINVAL; ++ if (custom_params[0] >= SMU_14_0_2_CUSTOM_PARAMS_CLOCK_COUNT) ++ return -EINVAL; ++ idx = custom_params[0] * SMU_14_0_2_CUSTOM_PARAMS_COUNT; ++ smu->custom_profile_params[idx] = 1; ++ for (i = 1; i < custom_params_max_idx; i++) ++ smu->custom_profile_params[idx + i] = custom_params[i]; ++ } + ret = smu_v14_0_2_set_power_profile_mode_coeff(smu, -+ smu->custom_profile_input, -+ smu->custom_profile_size); -+ if (ret) ++ smu->custom_profile_params); ++ if (ret) { ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; ++ } ++ } else if (smu->custom_profile_params) { ++ memset(smu->custom_profile_params, 0, SMU_14_0_2_CUSTOM_PARAMS_SIZE); + } - ret = smu_cmn_send_smc_msg_with_param(smu, @@ -16394,29 +17113,29 @@ index 1e16a281f2dc..aa147105a742 100644 + if (ret) { + dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n", + workload_mask); ++ if (idx != -1) ++ smu->custom_profile_params[idx] = 0; + return ret; + } return ret; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c -index 91ad434bcdae..79406463a65a 100644 +index 91ad434bcdae..0d71db7be325 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c -@@ -1215,3 +1215,33 @@ void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy) +@@ -1215,3 +1215,28 @@ void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy) { policy->desc = &xgmi_plpd_policy_desc; } + +void smu_cmn_get_backend_workload_mask(struct smu_context *smu, + u32 workload_mask, -+ u32 *backend_workload_mask, -+ bool *custom_enabled) ++ u32 *backend_workload_mask) +{ + int workload_type; + u32 profile_mode; + -+ *custom_enabled = false; + *backend_workload_mask = 0; + + for (profile_mode = 0; profile_mode < PP_SMC_POWER_PROFILE_COUNT; profile_mode++) { @@ -16432,23 +17151,19 @@ index 91ad434bcdae..79406463a65a 100644 + continue; + + *backend_workload_mask |= 1 << workload_type; -+ -+ if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) -+ *custom_enabled = true; + } +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h -index 1de685defe85..8d40c02efa00 100644 +index 1de685defe85..a020277dec3e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h -@@ -147,5 +147,10 @@ bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev); +@@ -147,5 +147,9 @@ bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev); void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy); void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy); +void smu_cmn_get_backend_workload_mask(struct smu_context *smu, + u32 workload_mask, -+ u32 *backend_workload_mask, -+ bool *custom_enabled); ++ u32 *backend_workload_mask); + #endif #endif @@ -16545,19 +17260,18 @@ index 855beafb76ff..ad78059ee954 100644 if (!newmode) continue; -diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c -index 62ba01525479..376047beea3d 100644 ---- a/drivers/misc/lkdtm/bugs.c -+++ b/drivers/misc/lkdtm/bugs.c -@@ -445,7 +445,7 @@ static void lkdtm_FAM_BOUNDS(void) - - pr_err("FAIL: survived access of invalid flexible array member index!\n"); - -- if (!__has_attribute(__counted_by__)) -+ if (!IS_ENABLED(CONFIG_CC_HAS_COUNTED_BY)) - pr_warn("This is expected since this %s was built with a compiler that does not support __counted_by\n", - lkdtm_kernel_info); - else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS)) +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 92cff3f2658c..44c54419d93c 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -209,6 +209,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30 + #define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6 ++#define USB_DEVICE_ID_ASUSTEK_ROG_RAIKIRI_PAD 0x1abb + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c index 0763202d00c9..8d789b017fa9 100644 --- a/fs/ntfs3/attrib.c @@ -16774,7 +17488,7 @@ index cf4fe21a5039..04107b950717 100644 ret = true; diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c -index e370eaf9bfe2..3f96a11804c9 100644 +index f704ceef9539..3f96a11804c9 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -182,13 +182,15 @@ static int ntfs_extend_initialized_size(struct file *file, @@ -16794,15 +17508,6 @@ index e370eaf9bfe2..3f96a11804c9 100644 for (;;) { u32 zerofrom, len; -@@ -222,7 +224,7 @@ static int ntfs_extend_initialized_size(struct file *file, - if (err) - goto out; - -- folio_zero_range(folio, zerofrom, folio_size(folio)); -+ folio_zero_range(folio, zerofrom, folio_size(folio) - zerofrom); - - err = ntfs_write_end(file, mapping, pos, len, len, folio, NULL); - if (err < 0) @@ -987,6 +989,7 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) u64 frame_vbo; pgoff_t index; @@ -17219,60 +17924,6 @@ index 58e988cd8049..6e86d66197ef 100644 } return ret; -diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h -index 32284cd26d52..c16d4199bf92 100644 ---- a/include/linux/compiler_attributes.h -+++ b/include/linux/compiler_attributes.h -@@ -94,19 +94,6 @@ - # define __copy(symbol) - #endif - --/* -- * Optional: only supported since gcc >= 15 -- * Optional: only supported since clang >= 18 -- * -- * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 -- * clang: https://github.com/llvm/llvm-project/pull/76348 -- */ --#if __has_attribute(__counted_by__) --# define __counted_by(member) __attribute__((__counted_by__(member))) --#else --# define __counted_by(member) --#endif -- - /* - * Optional: not supported by gcc - * Optional: only supported since clang >= 14.0 -diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h -index 1a957ea2f4fe..639be0f30b45 100644 ---- a/include/linux/compiler_types.h -+++ b/include/linux/compiler_types.h -@@ -323,6 +323,25 @@ struct ftrace_likely_data { - #define __no_sanitize_or_inline __always_inline - #endif - -+/* -+ * Optional: only supported since gcc >= 15 -+ * Optional: only supported since clang >= 18 -+ * -+ * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 -+ * clang: https://github.com/llvm/llvm-project/pull/76348 -+ * -+ * __bdos on clang < 19.1.2 can erroneously return 0: -+ * https://github.com/llvm/llvm-project/pull/110497 -+ * -+ * __bdos on clang < 19.1.3 can be off by 4: -+ * https://github.com/llvm/llvm-project/pull/112636 -+ */ -+#ifdef CONFIG_CC_HAS_COUNTED_BY -+# define __counted_by(member) __attribute__((__counted_by__(member))) -+#else -+# define __counted_by(member) -+#endif -+ - /* - * Apply __counted_by() when the Endianness matches to increase test coverage. - */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 6e3bdf8e38bc..6b6f05404304 100644 --- a/include/linux/mm_types.h @@ -17285,25 +17936,225 @@ index 6e3bdf8e38bc..6b6f05404304 100644 NR_TLB_FLUSH_REASONS, }; -diff --git a/init/Kconfig b/init/Kconfig -index 38dbd16da6a9..504e8a7c4e2a 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -120,6 +120,14 @@ config CC_HAS_ASM_INLINE - config CC_HAS_NO_PROFILE_FN_ATTR - def_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror) +diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h +index 2799e7284fff..1ddbde64a31b 100644 +--- a/include/linux/sched/ext.h ++++ b/include/linux/sched/ext.h +@@ -199,6 +199,7 @@ struct sched_ext_entity { + #ifdef CONFIG_EXT_GROUP_SCHED + struct cgroup *cgrp_moving_from; + #endif ++ /* must be the last field, see init_scx_entity() */ + struct list_head tasks_node; + }; -+# clang needs to be at least 19.1.3 to avoid __bdos miscalculations -+# https://github.com/llvm/llvm-project/pull/110497 -+# https://github.com/llvm/llvm-project/pull/112636 -+# TODO: when gcc 15 is released remove the build test and add gcc version check -+config CC_HAS_COUNTED_BY -+ def_bool $(success,echo 'struct flex { int count; int array[] __attribute__((__counted_by__(count))); };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror) -+ depends on !(CC_IS_CLANG && CLANG_VERSION < 190103) +diff --git a/kernel/futex/core.c b/kernel/futex/core.c +index 136768ae2637..9107704a6574 100644 +--- a/kernel/futex/core.c ++++ b/kernel/futex/core.c +@@ -451,28 +451,6 @@ struct futex_q *futex_top_waiter(struct futex_hash_bucket *hb, union futex_key * + return NULL; + } + +-int futex_cmpxchg_value_locked(u32 *curval, u32 __user *uaddr, u32 uval, u32 newval) +-{ +- int ret; +- +- pagefault_disable(); +- ret = futex_atomic_cmpxchg_inatomic(curval, uaddr, uval, newval); +- pagefault_enable(); +- +- return ret; +-} +- +-int futex_get_value_locked(u32 *dest, u32 __user *from) +-{ +- int ret; +- +- pagefault_disable(); +- ret = __get_user(*dest, from); +- pagefault_enable(); +- +- return ret ? -EFAULT : 0; +-} +- + /** + * wait_for_owner_exiting - Block until the owner has exited + * @ret: owner's current futex lock status +diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h +index 8b195d06f4e8..618ce1fe870e 100644 +--- a/kernel/futex/futex.h ++++ b/kernel/futex/futex.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_PREEMPT_RT + #include +@@ -225,10 +226,64 @@ extern bool __futex_wake_mark(struct futex_q *q); + extern void futex_wake_mark(struct wake_q_head *wake_q, struct futex_q *q); + + extern int fault_in_user_writeable(u32 __user *uaddr); +-extern int futex_cmpxchg_value_locked(u32 *curval, u32 __user *uaddr, u32 uval, u32 newval); +-extern int futex_get_value_locked(u32 *dest, u32 __user *from); + extern struct futex_q *futex_top_waiter(struct futex_hash_bucket *hb, union futex_key *key); + ++static inline int futex_cmpxchg_value_locked(u32 *curval, u32 __user *uaddr, u32 uval, u32 newval) ++{ ++ int ret; + - config PAHOLE_VERSION - int - default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE)) ++ pagefault_disable(); ++ ret = futex_atomic_cmpxchg_inatomic(curval, uaddr, uval, newval); ++ pagefault_enable(); ++ ++ return ret; ++} ++ ++/* ++ * This does a plain atomic user space read, and the user pointer has ++ * already been verified earlier by get_futex_key() to be both aligned ++ * and actually in user space, just like futex_atomic_cmpxchg_inatomic(). ++ * ++ * We still want to avoid any speculation, and while __get_user() is ++ * the traditional model for this, it's actually slower than doing ++ * this manually these days. ++ * ++ * We could just have a per-architecture special function for it, ++ * the same way we do futex_atomic_cmpxchg_inatomic(), but rather ++ * than force everybody to do that, write it out long-hand using ++ * the low-level user-access infrastructure. ++ * ++ * This looks a bit overkill, but generally just results in a couple ++ * of instructions. ++ */ ++static __always_inline int futex_read_inatomic(u32 *dest, u32 __user *from) ++{ ++ u32 val; ++ ++ if (can_do_masked_user_access()) ++ from = masked_user_access_begin(from); ++ else if (!user_read_access_begin(from, sizeof(*from))) ++ return -EFAULT; ++ unsafe_get_user(val, from, Efault); ++ user_access_end(); ++ *dest = val; ++ return 0; ++Efault: ++ user_access_end(); ++ return -EFAULT; ++} ++ ++static inline int futex_get_value_locked(u32 *dest, u32 __user *from) ++{ ++ int ret; ++ ++ pagefault_disable(); ++ ret = futex_read_inatomic(dest, from); ++ pagefault_enable(); ++ ++ return ret; ++} ++ + extern void __futex_unqueue(struct futex_q *q); + extern void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb); + extern int futex_unqueue(struct futex_q *q); +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index da59c68df841..55d0835ea0cf 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1570,16 +1570,25 @@ static int check_kprobe_address_safe(struct kprobe *p, + if (ret) + return ret; + jump_label_lock(); +- preempt_disable(); + + /* Ensure the address is in a text area, and find a module if exists. */ + *probed_mod = NULL; + if (!core_kernel_text((unsigned long) p->addr)) { ++ guard(preempt)(); + *probed_mod = __module_text_address((unsigned long) p->addr); + if (!(*probed_mod)) { + ret = -EINVAL; + goto out; + } ++ ++ /* ++ * We must hold a refcount of the probed module while updating ++ * its code to prohibit unexpected unloading. ++ */ ++ if (unlikely(!try_module_get(*probed_mod))) { ++ ret = -ENOENT; ++ goto out; ++ } + } + /* Ensure it is not in reserved area. */ + if (in_gate_area_no_mm((unsigned long) p->addr) || +@@ -1588,21 +1597,13 @@ static int check_kprobe_address_safe(struct kprobe *p, + static_call_text_reserved(p->addr, p->addr) || + find_bug((unsigned long)p->addr) || + is_cfi_preamble_symbol((unsigned long)p->addr)) { ++ module_put(*probed_mod); + ret = -EINVAL; + goto out; + } + + /* Get module refcount and reject __init functions for loaded modules. */ + if (IS_ENABLED(CONFIG_MODULES) && *probed_mod) { +- /* +- * We must hold a refcount of the probed module while updating +- * its code to prohibit unexpected unloading. +- */ +- if (unlikely(!try_module_get(*probed_mod))) { +- ret = -ENOENT; +- goto out; +- } +- + /* + * If the module freed '.init.text', we couldn't insert + * kprobes in there. +@@ -1610,13 +1611,11 @@ static int check_kprobe_address_safe(struct kprobe *p, + if (within_module_init((unsigned long)p->addr, *probed_mod) && + !module_is_coming(*probed_mod)) { + module_put(*probed_mod); +- *probed_mod = NULL; + ret = -ENOENT; + } + } + + out: +- preempt_enable(); + jump_label_unlock(); + + return ret; +diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c +index 16613631543f..751d73d500e5 100644 +--- a/kernel/sched/ext.c ++++ b/kernel/sched/ext.c +@@ -3567,7 +3567,12 @@ static void scx_ops_exit_task(struct task_struct *p) + + void init_scx_entity(struct sched_ext_entity *scx) + { +- memset(scx, 0, sizeof(*scx)); ++ /* ++ * init_idle() calls this function again after fork sequence is ++ * complete. Don't touch ->tasks_node as it's already linked. ++ */ ++ memset(scx, 0, offsetof(struct sched_ext_entity, tasks_node)); ++ + INIT_LIST_HEAD(&scx->dsq_list.node); + RB_CLEAR_NODE(&scx->dsq_priq); + scx->sticky_cpu = -1; +@@ -6473,8 +6478,6 @@ __bpf_kfunc_end_defs(); + + BTF_KFUNCS_START(scx_kfunc_ids_unlocked) + BTF_ID_FLAGS(func, scx_bpf_create_dsq, KF_SLEEPABLE) +-BTF_ID_FLAGS(func, scx_bpf_dispatch_from_dsq_set_slice) +-BTF_ID_FLAGS(func, scx_bpf_dispatch_from_dsq_set_vtime) + BTF_ID_FLAGS(func, scx_bpf_dispatch_from_dsq, KF_RCU) + BTF_ID_FLAGS(func, scx_bpf_dispatch_vtime_from_dsq, KF_RCU) + BTF_KFUNCS_END(scx_kfunc_ids_unlocked) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 9949ffad8df0..8b07576814a5 100644 --- a/kernel/workqueue.c @@ -17353,21 +18204,8 @@ index 9949ffad8df0..8b07576814a5 100644 if (flush_color >= 0 && atomic_dec_and_test(&wq->nr_pwqs_to_flush)) complete(&wq->first_flusher->done); -diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c -index 2abc78367dd1..5222c6393f11 100644 ---- a/lib/overflow_kunit.c -+++ b/lib/overflow_kunit.c -@@ -1187,7 +1187,7 @@ static void DEFINE_FLEX_test(struct kunit *test) - { - /* Using _RAW_ on a __counted_by struct will initialize "counter" to zero */ - DEFINE_RAW_FLEX(struct foo, two_but_zero, array, 2); --#if __has_attribute(__counted_by__) -+#ifdef CONFIG_CC_HAS_COUNTED_BY - int expected_raw_size = sizeof(struct foo); - #else - int expected_raw_size = sizeof(struct foo) + 2 * sizeof(s16); diff --git a/mm/mmap.c b/mm/mmap.c -index 79d541f1502b..2f01f1a8e304 100644 +index 4f6e566d52fa..7fb4c1e97175 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -901,6 +901,7 @@ __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, @@ -17394,50 +18232,25 @@ index f83493838cf9..4010899652b8 100644 echo "Installing System.map and config..." mkdir -p "${builddir}" cp System.map "${builddir}/System.map" +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 18e6779a83be..c73982b07969 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10682,6 +10682,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1e1f, "ASUS Vivobook 15 X1504VAP", ALC2XX_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), + SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), ++ SND_PCI_QUIRK(0x1043, 0x1e63, "ASUS H7606W", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2), -- -2.47.0 +2.47.1 - -From 13bbddce3f91aced56362376c07e7c1a6ecf89b0 Mon Sep 17 00:00:00 2001 -From: Hao Qin -Date: Thu, 22 Aug 2024 13:23:10 +0800 -Subject: [PATCH] Bluetooth: btmtk: Remove resetting mt7921 before downloading - the fw - -Remove resetting mt7921 before downloading the fw, as it may cause -command timeout when performing the reset. - -Signed-off-by: Hao Qin ---- - drivers/bluetooth/btmtk.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c -index 9bbf205021634f..67219ac262f131 100644 ---- a/drivers/bluetooth/btmtk.c -+++ b/drivers/bluetooth/btmtk.c -@@ -1326,7 +1326,6 @@ int btmtk_usb_setup(struct hci_dev *hdev) - fwname = FIRMWARE_MT7668; - break; - case 0x7922: -- case 0x7961: - case 0x7925: - /* Reset the device to ensure it's in the initial state before - * downloading the firmware to ensure. -@@ -1334,7 +1333,8 @@ int btmtk_usb_setup(struct hci_dev *hdev) - - if (!test_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags)) - btmtk_usb_subsys_reset(hdev, dev_id); -- -+ fallthrough; -+ case 0x7961: - btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id, - fw_version, fw_flavor); - - -From 5aa831042dc384bd259eb368b4a02ae807ce9d39 Mon Sep 17 00:00:00 2001 +From e3136a3233eba6da59d7a48e41c571afe0dd9349 Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 22:00:34 +0100 +Date: Thu, 5 Dec 2024 14:41:42 +0100 Subject: [PATCH 08/12] ntsync Signed-off-by: Peter Jung @@ -17877,7 +18690,7 @@ index 000000000000..767844637a7d + ``objs`` and in ``alert``. If this is attempted, the function fails + with ``EINVAL``. diff --git a/MAINTAINERS b/MAINTAINERS -index 97802662e8d8..889e074c143b 100644 +index a2d251917629..a30770b6f75a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16501,6 +16501,15 @@ T: git https://github.com/Paragon-Software-Group/linux-ntfs3.git @@ -20522,11 +21335,11 @@ index 000000000000..5fa2c9a0768c + +TEST_HARNESS_MAIN -- -2.47.0 +2.47.1 -From d16820bc5addd0ce3fed3e018234022553529bcb Mon Sep 17 00:00:00 2001 +From 71bb61460f0957c5bed4d52c612f0196d3da54d3 Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 22:00:57 +0100 +Date: Thu, 5 Dec 2024 14:41:55 +0100 Subject: [PATCH 09/12] perf-per-core Signed-off-by: Peter Jung @@ -21519,11 +22332,11 @@ index 2361ed4d2b15..37a9afffb59e 100644 CPUHP_AP_PERF_S390_SF_ONLINE, CPUHP_AP_PERF_ARM_CCI_ONLINE, -- -2.47.0 +2.47.1 -From 56c63974139208510b818be3671cd81f53477e9b Mon Sep 17 00:00:00 2001 +From 0eaeb75af11e153427fa208c9f951f605e76923f Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 22:01:17 +0100 +Date: Thu, 5 Dec 2024 14:42:06 +0100 Subject: [PATCH 10/12] pksm Signed-off-by: Peter Jung @@ -21952,11 +22765,11 @@ index 01071182763e..7394bad8178e 100644 +464 common process_ksm_disable sys_process_ksm_disable sys_process_ksm_disable +465 common process_ksm_status sys_process_ksm_status sys_process_ksm_status -- -2.47.0 +2.47.1 -From 0302b0fc0ae9349f48c609d54572001d7ab44fad Mon Sep 17 00:00:00 2001 +From 9a010ef3215a498041d6b72ebf77167480aa5c4d Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 22:01:43 +0100 +Date: Thu, 5 Dec 2024 14:42:15 +0100 Subject: [PATCH 11/12] t2 Signed-off-by: Peter Jung @@ -22112,7 +22925,7 @@ index 14e093da3ccd..ccd7bd29a6d6 100644 ---- diff --git a/MAINTAINERS b/MAINTAINERS -index 889e074c143b..b737a7b5e767 100644 +index a30770b6f75a..63ee2eb3ab41 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7013,6 +7013,12 @@ S: Supported @@ -22129,7 +22942,7 @@ index 889e074c143b..b737a7b5e767 100644 S: Orphan T: git https://gitlab.freedesktop.org/drm/misc/kernel.git diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index ebc13f056153..b232245cf6b2 100644 +index 0f085a044240..88d7acde9d3e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2262,6 +2262,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, @@ -32188,10 +33001,10 @@ index c5e2ec9303c5..874e3af8104c 100644 * a certain separator (' ' by default): * C colon diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl -index 4427572b2477..b60c99d61882 100755 +index b03d526e4c45..66d09cbec5a8 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl -@@ -6917,7 +6917,7 @@ sub process { +@@ -6912,7 +6912,7 @@ sub process { ($extension eq "f" && defined $qualifier && $qualifier !~ /^w/) || ($extension eq "4" && @@ -32201,11 +33014,11 @@ index 4427572b2477..b60c99d61882 100755 last; } -- -2.47.0 +2.47.1 -From 418eb317bb2568c00f1c2bb620ded17db45f9383 Mon Sep 17 00:00:00 2001 +From 1fd0be01b82212aeb9b66ee23aae5e3f018a7b20 Mon Sep 17 00:00:00 2001 From: Peter Jung -Date: Thu, 21 Nov 2024 22:01:56 +0100 +Date: Thu, 5 Dec 2024 14:42:25 +0100 Subject: [PATCH 12/12] zstd Signed-off-by: Peter Jung @@ -50853,4 +51666,4 @@ index 469fc3059be0..0ae819f0c927 100644 EXPORT_SYMBOL(zstd_reset_dstream); -- -2.47.0 +2.47.1