diff options
55 files changed, 4870 insertions, 15696 deletions
@@ -1,7 +1,7 @@ pkgbase = linux-g14 pkgdesc = Linux - pkgver = 5.14.9.arch1 - pkgrel = 3 + pkgver = 6.2.12.arch1 + pkgrel = 2 url = https://gitlab.com/dragonn/linux-g14.git arch = x86_64 license = GPL2 @@ -16,82 +16,50 @@ pkgbase = linux-g14 makedepends = git makedepends = gcc>=11.0 options = !strip - source = archlinux-linux::git+https://github.com/archlinux/linux?signed#tag=v5.14.9-arch1 + source = archlinux-linux::git+https://github.com/archlinux/linux?signed#tag=v6.2.12-arch1 source = config source = choose-gcc-optimization.sh - source = sys-kernel_arch-sources-g14_files-0004-5.8+--more-uarches-for-kernel.patch::https://raw.githubusercontent.com/graysky2/kernel_compiler_patch/a8d200f422f4b2abeaa6cfcfa37136b308e6e33e/more-uarches-for-kernel-5.8%2B.patch - source = sys-kernel_arch-sources-g14_files-0005-lru-multi-generational.patch - source = https://gitlab.com/asus-linux/fedora-kernel/-/archive/e087e6d70c49c685b4d7cc7364496ade3aed3609/fedora-kernel-e087e6d70c49c685b4d7cc7364496ade3aed3609.zip - source = sys-kernel_arch-sources-g14_files-0039-asus-wmi-Add-panel-overdrive-functionality.patch - source = sys-kernel_arch-sources-g14_files-0043-ALSA-hda-realtek-Fix-speakers-not-working-on-Asus-Fl.patch - source = sys-kernel_arch-sources-g14_files-0044-claymore.patch - source = sys-kernel_arch-sources-g14_files-0045-v5-asus-wmi-Add-support-for-platform_profile.patch - source = sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch + source = sys-kernel_arch-sources-g14_files-0004-5.17+--more-uarches-for-kernel.patch::https://raw.githubusercontent.com/graysky2/kernel_compiler_patch/master/more-uarches-for-kernel-5.17+.patch + source = 0001-acpi-proc-idle-skip-dummy-wait.patch + source = 0019-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch + source = 0001-platform-x86-asus-wmi-Add-safety-checks-to-dgpu-egpu.patch + source = 0001-Revert-perf-x86-intel-Fix-unchecked-MSR-access-error.patch + source = 0024-V8-0-4-PCI-vmd-Enable-PCIe-ASPM-and-LTR-on-select-hardware.patch + source = 0027-mt76_-mt7921_-Disable-powersave-features-by-default.patch + source = 0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch + source = 0001-linux6.0.y-bore1.7.5.patch + source = 0002-mm-add-vma_has_recency.patch + source = 0028-patch01_gu604_alc285_fixes.patch + source = 0029-HID-asus-Add-support-for-ASUS-ROG-Z13-keyboard.patch + source = 0030-HID-asus-Add-support-for-ASUS-ROG-Z13-ACRNM-keyboard.patch + source = 0031-HID-asus-Map-0xc7-key-event-to-KEY_KBDILLUMTOGGLE.patch source = sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch source = sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch - source = sys-kernel_arch-sources-g14_files-8002-hwmon-k10temp-support-Zen3-APUs.patch - source = sys-kernel_arch-sources-g14_files-8011-Bluetooth-btusb-Enable-MSFT-extension-for-Mediatek-Chip-MT7921.patch - source = sys-kernel_arch-sources-g14_files-8012-mt76-mt7915-send-EAPOL-frames-at-lowest-rate.patch - source = sys-kernel_arch-sources-g14_files-8013-mt76-mt7921-robustify-hardware-initialization-flow.patch - source = sys-kernel_arch-sources-g14_files-8014-mt76-mt7921-fix-retrying-release-semaphore-without-end.patch - source = sys-kernel_arch-sources-g14_files-8015-mt76-mt7921-send-EAPOL-frames-at-lowest-rate.patch - source = sys-kernel_arch-sources-g14_files-8016-mt76-mt7921-Add-mt7922-support.patch - source = sys-kernel_arch-sources-g14_files-8017-mt76-mt7921-enable-VO-tx-aggregation.patch - source = sys-kernel_arch-sources-g14_files-8018-mt76-mt7921-fix-dma-hang-in-rmmod.patch - source = sys-kernel_arch-sources-g14_files-8019-mt76-mt7921-fix-firmware-usage-of-RA-info-using-legacy-rates.patch - source = sys-kernel_arch-sources-g14_files-8020-mt76-mt7921-Fix-out-of-order-process-by-invalid-even.patch - source = sys-kernel_arch-sources-g14_files-8021-mt76-mt7921-fix-the-inconsistent-state-between-bind-and-unbind.patch - source = sys-kernel_arch-sources-g14_files-8022-mt76-mt7921-report-HE-MU-radiotap.patch - source = sys-kernel_arch-sources-g14_files-8023-v2-mt76-mt7921-fix-kernel-warning-from-cfg80211_calculate_bitrate.patch - source = sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch - source = sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch - source = sys-kernel_arch-sources-g14_files-9004-HID-asus-Reduce-object-size-by-consolidating-calls.patch - source = sys-kernel_arch-sources-g14_files-9005-acpi-battery-Always-read-fresh-battery-state-on-update.patch - source = sys-kernel_arch-sources-g14_files-9006-amd-c3-entry.patch - source = sys-kernel_arch-sources-g14_files-9007-squashed-net-tcp_bbr-bbr2-for-5.14.y.patch - source = sys-kernel_arch-sources-g14_files-9008-fix-cpu-hotplug.patch - source = sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch - source = sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch + source = sys-kernel_arch-sources-g14_files-0049-ALSA-hda-realtek-Add-quirk-for-ASUS-M16-GU603H.patch validpgpkeys = ABAF11C65A2970B130ABE3C479BE3E4300411886 validpgpkeys = 647F28654894E3BD457199BE38DBBDC86092693E validpgpkeys = A2FF3A36AAA56654109064AB19802F8B0D70FC30 validpgpkeys = C7E7849466FE2358343588377258734B41C31549 sha256sums = SKIP - sha256sums = aa50b2ec33ce304f9b99ce80555a17ea18b1005dae147a560587acbdae00546f - sha256sums = 1ac18cad2578df4a70f9346f7c6fccbb62f042a0ee0594817fdef9f2704904ee - sha256sums = fa6cee9527d8e963d3398085d1862edc509a52e4540baec463edb8a9dd95bee0 - sha256sums = 69ecf5456468935958f2cbf35691c2533a56344005537902b6051b6323ffff1f - sha256sums = 6806c034b7480245a0b9eec448bd79042ff5ff3f9f5efbf2af78227bc56004a8 - sha256sums = 1ab75535772c63567384eb2ac74753e4d5db2f3317cb265aedf6151b9f18c6c2 - sha256sums = 32bbcde83406810f41c9ed61206a7596eb43707a912ec9d870fd94f160d247c1 - sha256sums = e2d312ea95d18e91801d131a2b5d03cf2175d3088cac6f84a19410078a5b6b14 - sha256sums = 4ef12029ea73ca924b6397e1de4911e84d9e77ddaccdab1ef579823d848524e8 - sha256sums = 1e547bddf80d201f77da1d876cd280e4d40b377bbd8ebc218f0ba57cd959ff76 + sha256sums = 70cf3252ff877cb91ca7eba13439ae181e693513b09ff43e83c48d2b0b46d0f8 + sha256sums = 278118011d7a2eeca9971ac97b31bf0c55ab55e99c662ab9ae4717b55819c9a2 + sha256sums = dea86a521603414a8c7bf9cf1f41090d5d6f8035ce31407449e25964befb1e50 + sha256sums = 0a7ea482fe20c403788d290826cec42fe395e5a6eab07b88845f8b9a9829998d + sha256sums = d45e2ae1d21b1dc8e0de94a4fa58e9a53d72306843f87d3cc49f5f641399d8e3 + sha256sums = 172dbc88d0a3cda78387f3c907fa4953c71cb1cb162f0b34f78b8b78924bc3d4 + sha256sums = 6739a42bf9d233cb58ae9a69c3f78959175de695e2d4a7e66bb9984fcf5c0f7e + sha256sums = f036ac8a49153f66d7d8638508cfe0b4a158d12faf30d2c671b04a6b7b606b3b + sha256sums = a691e7b22633fe0c458d140167d6d381b66149e05de3cb926b30a19fd43e78ce + sha256sums = 7b16fce20b03babc9e149030f43e283534835bbd8835ba0a794fd0205fea1708 + sha256sums = bca0caa5efad45c0acde1e78d43f8ce1af6ebf3cbb0240b143be3e6486509970 + sha256sums = b6288935f2768a7023d11e9a200f47b087669ffd4d418f791ee71d5a51d0530e + sha256sums = 5b19e3d557fbd52ef7e966b6d491c17a77769f03534b8cf9877fe3696e5d291f + sha256sums = 1f63361ebbebecaaa3122ec174b39dfc346eda44592299a058b44bb4837b5d92 + sha256sums = 0febf2e8fee2e5c2222441464812aca66d21d714cd28aa7c218218b509d242fb + sha256sums = 00feb23b3ed0983d13a8929ade35b3dcb23987d21f0e342db4dcb8292656a72e sha256sums = 15e912a66e4bbce1cf0450f1dc6610653df29df8dd6d5426f9c1b039490436c8 - sha256sums = e9e4b03b836e1a86a2a5dc70b0d5512348eb19742f83bee794a3ab7d91bd41cf - sha256sums = de8c9747637768c4356c06aa65c3f157c526aa420f21fdd5edd0ed06f720a62e - sha256sums = 9f6b8c3ea6e1c285e0a7efda4d743dbae343bc6ee7ad599a4ab7d380c750bc83 - sha256sums = 4bfbff4eba07fc9de2ce78097a4a269509468ba0e24c15a82905cd94e093ad55 - sha256sums = c368cc4eefff20b7ae904eec686b7e72b46ff02b32c8a4fbd6bd4039f087e7ba - sha256sums = 1a8639167a1ee1b66f580c0c6f8304e6ef359a68cfa3eb869d9200a9f0234098 - sha256sums = 021f8539ab2fb722b46937b95fdab22a2308236a24ecc1a9ea8db4853721dd39 - sha256sums = a01cf700d79b983807e2285be1b30df6e02db6adfd9c9027fe2dfa8ca5a74bc9 - sha256sums = 1ce9fd988201c4d2e48794c58acda5b768ec0fea1d29555e99d35cd2712281e4 - sha256sums = e7e37c7c433c58e2f5a79e2a7724823bef1dccaa01e857584397b4e3c837d991 - sha256sums = f075ac354acfd65dff4db49dc9798747cb9b7a3dd9839987bc46495bdbbd22dc - sha256sums = 2163cb2e394a013042a40cd3b00dae788603284b20d71e262995366c5534e480 - sha256sums = 1770fec49335bc93194e9e55ced49e1cb67f2df4bf6948e80712a0b2ba50fa49 - sha256sums = 6da4010f86a74125969fd3dbc953da7b45209d33ff3d216474c3399e82e893ff - sha256sums = eb391b6d1ebf7ef99ece00b23609b94180a1f3c0149bcf05f6bbeb74d0b724c7 - sha256sums = f7afab5f2d872dbb66774a189ed462750985aed0df1d81b3a49db9809e8557b6 - sha256sums = dd5b0df91e7c17e26af4839b3a23ba5e8850d329aeb28137ec6468502418f2bd - sha256sums = 544464bf0807b324120767d55867f03014a9fda4e1804768ca341be902d7ade4 - sha256sums = f7a4bf6293912bfc4a20743e58a5a266be8c4dbe3c1862d196d3a3b45f2f7c90 - sha256sums = ee8794a551e33226900654d5c806183bf3b9b2e06f64fdc322987215d233d399 - sha256sums = 2d854fc70297bb52bbc27dbf35ca019800530e40565be9740704d7f81bc4c763 - sha256sums = 1cec0be41732a23c709e66d4a67e71bc5a75c77a3e4b73faafb5d7bfd3fafc0f - sha256sums = 9025ca0788fbacea25200e6ac17036960000424843f544cdd781052231da7903 - sha256sums = e7bd53abc9fddc66790a2e63637b4e2b54ed541f41a2f0fb3aca91ea64ff90dc + sha256sums = 444f2d86de8c2177655b01596f939f99c2e7abfa8efad8a509e0a334f42dfa85 + sha256sums = 982a31e47d3d586789e1b3cdda25f75e3b71d810e7494202089b8f2cef7c0ef9 pkgname = linux-g14 pkgdesc = The Linux kernel and modules diff --git a/.gitignore b/.gitignore index 21eeaed1532c..aedaae62636b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ fedora-kernel-*.zip old old-mediatek new-mediatek -*.tar.zst
\ No newline at end of file +*.tar.zst +*.sig
\ No newline at end of file diff --git a/0001-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch b/0001-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch new file mode 100644 index 000000000000..defab6fb88d7 --- /dev/null +++ b/0001-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch @@ -0,0 +1,193 @@ +From e6529e0ad6942bb0eadc5f5ad0590124153e0a8c Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Wed, 3 Aug 2022 11:02:05 +1200 +Subject: [PATCH 1/1] HID: amd_sfh: Add keyguard for ASUS ROG X13 tablet + +Add support for ROG X13 Flow 2-in-1 to disable the keyboard when +the lid is flipped. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 7 ++++- + drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 1 + + .../hid_descriptor/amd_sfh_hid_desc.c | 27 +++++++++++++++++++ + .../hid_descriptor/amd_sfh_hid_desc.h | 9 +++++++ + .../hid_descriptor/amd_sfh_hid_report_desc.h | 19 +++++++++++++ + 5 files changed, 62 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +index dadc491bbf6b..243541d426d8 100644 +--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c ++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +@@ -26,6 +26,7 @@ + #define ACEL_EN BIT(0) + #define GYRO_EN BIT(1) + #define MAGNO_EN BIT(2) ++#define KBGUARD_EN BIT(15) + #define HPD_EN BIT(16) + #define ALS_EN BIT(19) + +@@ -232,6 +233,9 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) + if (HPD_EN & activestatus) + sensor_id[num_of_sensors++] = HPD_IDX; + ++ if (KBGUARD_EN & activestatus) ++ sensor_id[num_of_sensors++] = KBGUARD_IDX; ++ + return num_of_sensors; + } + +@@ -373,7 +377,8 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev) + + for (i = 0; i < cl_data->num_hid_devices; i++) { + if (cl_data->sensor_idx[i] != HPD_IDX && +- cl_data->sensor_sts[i] == SENSOR_ENABLED) { ++ cl_data->sensor_idx[i] != KBGUARD_IDX && ++ cl_data->sensor_sts[i] == SENSOR_ENABLED) { + mp2->mp2_ops->stop(mp2, cl_data->sensor_idx[i]); + status = amd_sfh_wait_for_response + (mp2, cl_data->sensor_idx[i], SENSOR_DISABLED); +diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +index 8c760526132a..4a86bc6038a2 100644 +--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h ++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +@@ -36,6 +36,7 @@ + #define SENSOR_DISABLED 5 + + #define HPD_IDX 16 ++#define KBGUARD_IDX 15 + + #define AMD_SFH_IDLE_LOOP 200 + +diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c +index 76095bd53c65..f41d28ea7b93 100644 +--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c ++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c +@@ -57,6 +57,11 @@ int get_report_descriptor(int sensor_idx, u8 *rep_desc) + memcpy(rep_desc, hpd_report_descriptor, + sizeof(hpd_report_descriptor)); + break; ++ case KBGUARD_IDX: /* kbguard ? */ ++ memset(rep_desc, 0, sizeof(kbguard_report_descriptor)); ++ memcpy(rep_desc, kbguard_report_descriptor, ++ sizeof(kbguard_report_descriptor)); ++ break; + default: + break; + } +@@ -116,6 +121,16 @@ u32 get_descr_sz(int sensor_idx, int descriptor_name) + return sizeof(struct hpd_feature_report); + } + break; ++ case KBGUARD_IDX: ++ switch (descriptor_name) { ++ case descr_size: ++ return sizeof(kbguard_report_descriptor); ++ case input_size: ++ return sizeof(struct kbguard_input_report); ++ case feature_size: ++ return sizeof(struct kbguard_feature_report); ++ } ++ break; + + default: + break; +@@ -139,6 +154,7 @@ u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) + struct gyro_feature_report gyro_feature; + struct magno_feature_report magno_feature; + struct hpd_feature_report hpd_feature; ++ struct kbguard_feature_report kbguard_feature; + struct als_feature_report als_feature; + u8 report_size = 0; + +@@ -186,6 +202,11 @@ u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) + memcpy(feature_report, &hpd_feature, sizeof(hpd_feature)); + report_size = sizeof(hpd_feature); + break; ++ case KBGUARD_IDX: /* auto disable keyboard when flip out */ ++ get_common_features(&kbguard_feature.common_property, report_id); ++ memcpy(feature_report, &kbguard_feature, sizeof(kbguard_feature)); ++ report_size = sizeof(kbguard_feature); ++ break; + + default: + break; +@@ -210,6 +231,7 @@ u8 get_input_report(u8 current_index, int sensor_idx, int report_id, struct amd_ + struct accel3_input_report acc_input; + struct gyro_input_report gyro_input; + struct hpd_input_report hpd_input; ++ struct kbguard_input_report kbguard_input; + struct als_input_report als_input; + struct hpd_status hpdstatus; + u8 report_size = 0; +@@ -262,6 +284,11 @@ u8 get_input_report(u8 current_index, int sensor_idx, int report_id, struct amd_ + report_size = sizeof(hpd_input); + memcpy(input_report, &hpd_input, sizeof(hpd_input)); + break; ++ case KBGUARD_IDX: /* kb guard */ ++ get_common_inputs(&kbguard_input.common_property, report_id); ++ report_size = sizeof(kbguard_input); ++ memcpy(input_report, &kbguard_input, sizeof(kbguard_input)); ++break; + default: + break; + } +diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h +index 70b1b7abe2c6..98571a8597b3 100644 +--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h ++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h +@@ -105,12 +105,21 @@ struct hpd_feature_report { + struct common_feature_property common_property; + } __packed; + ++struct kbguard_feature_report { ++ struct common_feature_property common_property; ++} __packed; ++ + struct hpd_input_report { + struct common_input_property common_property; + /* values specific to human presence sensor */ + u8 human_presence; + } __packed; + ++struct kbguard_input_report { ++ struct common_input_property common_property; ++} __packed; ++ ++ + int get_report_descriptor(int sensor_idx, u8 rep_desc[]); + u32 get_descr_sz(int sensor_idx, int descriptor_name); + u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report); +diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h +index 697f2791ea9c..7a62fcec2c73 100644 +--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h ++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h +@@ -644,6 +644,25 @@ static const u8 als_report_descriptor[] = { + 0xC0 /* HID end collection */ + }; + ++ ++static const u8 kbguard_report_descriptor[] = { ++0x06, 0x43, 0xFF, // Usage Page (Vendor Defined 0xFF43) ++0x0A, 0x02, 0x02, // Usage (0x0202) ++0xA1, 0x01, // Collection (Application) ++0x85, 0x11, // Report ID (17) ++0x15, 0x00, // Logical Minimum (0) ++0x25, 0x01, // Logical Maximum (1) ++0x35, 0x00, // Physical Minimum (0) ++0x45, 0x01, // Physical Maximum (1) ++0x65, 0x00, // Unit (None) ++0x55, 0x00, // Unit Exponent (0) ++0x75, 0x01, // Report Size (1) ++0x95, 0x98, // Report Count (-104) ++0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) ++0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) ++0xC1, 0x00, // End Collection ++}; ++ + /* BIOMETRIC PRESENCE*/ + static const u8 hpd_report_descriptor[] = { + 0x05, 0x20, /* Usage page */ +-- +2.37.1 + diff --git a/0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch b/0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch new file mode 100644 index 000000000000..e68df1185fa7 --- /dev/null +++ b/0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch @@ -0,0 +1,34 @@ +From 4b4ce124699c160925e5fdeb147a78f79d38351f Mon Sep 17 00:00:00 2001 +From: Simon May <simon.may@protonmail.ch> +Date: Sun, 19 Sep 2021 23:45:59 +0200 +Subject: [PATCH] Revert "PCI: Add a REBAR size quirk for Sapphire RX 5600 XT + Pulse" + +This reverts commit 907830b0fc9e374d00f3c83de5e426157b482c01. +--- + drivers/pci/pci.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 3f353572588d..1c8cc4b98f95 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -3637,14 +3637,7 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) + return 0; + + pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); +- cap &= PCI_REBAR_CAP_SIZES; +- +- /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ +- if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && +- bar == 0 && cap == 0x7000) +- cap = 0x3f000; +- +- return cap >> 4; ++ return (cap & PCI_REBAR_CAP_SIZES) >> 4; + } + EXPORT_SYMBOL(pci_rebar_get_possible_sizes); + +-- +2.30.2 + diff --git a/0001-Revert-perf-x86-intel-Fix-unchecked-MSR-access-error.patch b/0001-Revert-perf-x86-intel-Fix-unchecked-MSR-access-error.patch new file mode 100644 index 000000000000..507a8c31a1b7 --- /dev/null +++ b/0001-Revert-perf-x86-intel-Fix-unchecked-MSR-access-error.patch @@ -0,0 +1,127 @@ +From 94f0bed04310b9e8a061b48170b0b465e301f951 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Sun, 16 Oct 2022 22:14:09 +1300 +Subject: [PATCH] Revert "perf/x86/intel: Fix unchecked MSR access error for + Alder Lake N" + +This reverts commit 24919fdea6f8b31d7cdf32ac291bc5dd0b023878. +--- + arch/x86/events/intel/core.c | 40 +----------------------------------- + arch/x86/events/intel/ds.c | 9 ++------ + arch/x86/events/perf_event.h | 2 -- + 3 files changed, 3 insertions(+), 48 deletions(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index a646a5f9a235..3939debb27e7 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -2102,15 +2102,6 @@ static struct extra_reg intel_tnt_extra_regs[] __read_mostly = { + EVENT_EXTRA_END + }; + +-EVENT_ATTR_STR(mem-loads, mem_ld_grt, "event=0xd0,umask=0x5,ldlat=3"); +-EVENT_ATTR_STR(mem-stores, mem_st_grt, "event=0xd0,umask=0x6"); +- +-static struct attribute *grt_mem_attrs[] = { +- EVENT_PTR(mem_ld_grt), +- EVENT_PTR(mem_st_grt), +- NULL +-}; +- + static struct extra_reg intel_grt_extra_regs[] __read_mostly = { + /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ + INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), +@@ -6004,36 +5995,6 @@ __init int intel_pmu_init(void) + name = "Tremont"; + break; + +- case INTEL_FAM6_ALDERLAKE_N: +- x86_pmu.mid_ack = true; +- memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, +- sizeof(hw_cache_event_ids)); +- memcpy(hw_cache_extra_regs, tnt_hw_cache_extra_regs, +- sizeof(hw_cache_extra_regs)); +- hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1; +- +- x86_pmu.event_constraints = intel_slm_event_constraints; +- x86_pmu.pebs_constraints = intel_grt_pebs_event_constraints; +- x86_pmu.extra_regs = intel_grt_extra_regs; +- +- x86_pmu.pebs_aliases = NULL; +- x86_pmu.pebs_prec_dist = true; +- x86_pmu.pebs_block = true; +- x86_pmu.lbr_pt_coexist = true; +- x86_pmu.flags |= PMU_FL_HAS_RSP_1; +- x86_pmu.flags |= PMU_FL_INSTR_LATENCY; +- +- intel_pmu_pebs_data_source_grt(); +- x86_pmu.pebs_latency_data = adl_latency_data_small; +- x86_pmu.get_event_constraints = tnt_get_event_constraints; +- x86_pmu.limit_period = spr_limit_period; +- td_attr = tnt_events_attrs; +- mem_attr = grt_mem_attrs; +- extra_attr = nhm_format_attr; +- pr_cont("Gracemont events, "); +- name = "gracemont"; +- break; +- + case INTEL_FAM6_WESTMERE: + case INTEL_FAM6_WESTMERE_EP: + case INTEL_FAM6_WESTMERE_EX: +@@ -6380,6 +6341,7 @@ __init int intel_pmu_init(void) + + case INTEL_FAM6_ALDERLAKE: + case INTEL_FAM6_ALDERLAKE_L: ++ case INTEL_FAM6_ALDERLAKE_N: + case INTEL_FAM6_RAPTORLAKE: + case INTEL_FAM6_RAPTORLAKE_P: + case INTEL_FAM6_RAPTORLAKE_S: +diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c +index 7839507b3844..1380ae13ad2b 100644 +--- a/arch/x86/events/intel/ds.c ++++ b/arch/x86/events/intel/ds.c +@@ -110,18 +110,13 @@ void __init intel_pmu_pebs_data_source_skl(bool pmem) + __intel_pmu_pebs_data_source_skl(pmem, pebs_data_source); + } + +-static void __init __intel_pmu_pebs_data_source_grt(u64 *data_source) ++static void __init intel_pmu_pebs_data_source_grt(u64 *data_source) + { + data_source[0x05] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT); + data_source[0x06] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); + data_source[0x08] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD); + } + +-void __init intel_pmu_pebs_data_source_grt(void) +-{ +- __intel_pmu_pebs_data_source_grt(pebs_data_source); +-} +- + void __init intel_pmu_pebs_data_source_adl(void) + { + u64 *data_source; +@@ -132,7 +127,7 @@ void __init intel_pmu_pebs_data_source_adl(void) + + data_source = x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX].pebs_data_source; + memcpy(data_source, pebs_data_source, sizeof(pebs_data_source)); +- __intel_pmu_pebs_data_source_grt(data_source); ++ intel_pmu_pebs_data_source_grt(data_source); + } + + static u64 precise_store_data(u64 status) +diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h +index 332d2e6d8ae4..371967054871 100644 +--- a/arch/x86/events/perf_event.h ++++ b/arch/x86/events/perf_event.h +@@ -1598,8 +1598,6 @@ void intel_pmu_pebs_data_source_skl(bool pmem); + + void intel_pmu_pebs_data_source_adl(void); + +-void intel_pmu_pebs_data_source_grt(void); +- + int intel_pmu_setup_lbr_filter(struct perf_event *event); + + void intel_pt_interrupt(void); +-- +2.37.3 + diff --git a/0001-acpi-proc-idle-skip-dummy-wait.patch b/0001-acpi-proc-idle-skip-dummy-wait.patch new file mode 100644 index 000000000000..63c117200e8e --- /dev/null +++ b/0001-acpi-proc-idle-skip-dummy-wait.patch @@ -0,0 +1,125 @@ +Processors based on the Zen microarchitecture support IOPORT based deeper +C-states. The idle driver reads the acpi_gbl_FADT.xpm_timer_block.address +in the IOPORT based C-state exit path which is claimed to be a +"Dummy wait op" and has been around since ACPI introduction to Linux +dating back to Andy Grover's Mar 14, 2002 posting [1]. +The comment above the dummy operation was elaborated by Andreas Mohr back +in 2006 in commit b488f02156d3d ("ACPI: restore comment justifying 'extra' +P_LVLx access") [2] where the commit log claims: +"this dummy read was about: STPCLK# doesn't get asserted in time on +(some) chipsets, which is why we need to have a dummy I/O read to delay +further instruction processing until the CPU is fully stopped." + +However, sampling certain workloads with IBS on AMD Zen3 system shows +that a significant amount of time is spent in the dummy op, which +incorrectly gets accounted as C-State residency. A large C-State +residency value can prime the cpuidle governor to recommend a deeper +C-State during the subsequent idle instances, starting a vicious cycle, +leading to performance degradation on workloads that rapidly switch +between busy and idle phases. + +One such workload is tbench where a massive performance degradation can +be observed during certain runs. Following are some statistics gathered +by running tbench with 128 clients, on a dual socket (2 x 64C/128T) Zen3 +system with the baseline kernel, baseline kernel keeping C2 disabled, +and baseline kernel with this patch applied keeping C2 enabled: + +baseline kernel was tip:sched/core at +commit f3dd3f674555 ("sched: Remove the limitation of WF_ON_CPU on +wakelist if wakee cpu is idle") + +Kernel : baseline baseline + C2 disabled baseline + patch + +Min (MB/s) : 2215.06 33072.10 (+1393.05%) 33016.10 (+1390.52%) +Max (MB/s) : 32938.80 34399.10 34774.50 +Median (MB/s) : 32191.80 33476.60 33805.70 +AMean (MB/s) : 22448.55 33649.27 (+49.89%) 33865.43 (+50.85%) +AMean Stddev : 17526.70 680.14 880.72 +AMean CoefVar : 78.07% 2.02% 2.60% + +The data shows there are edge cases that can cause massive regressions +in case of tbench. Profiling the bad runs with IBS shows a significant +amount of time being spent in acpi_idle_do_entry method: + +Overhead Command Shared Object Symbol + 74.76% swapper [kernel.kallsyms] [k] acpi_idle_do_entry + 0.71% tbench [kernel.kallsyms] [k] update_sd_lb_stats.constprop.0 + 0.69% tbench_srv [kernel.kallsyms] [k] update_sd_lb_stats.constprop.0 + 0.49% swapper [kernel.kallsyms] [k] psi_group_change + ... + +Annotation of acpi_idle_do_entry method reveals almost all the time in +acpi_idle_do_entry is spent on the port I/O in wait_for_freeze(): + + 0.14 │ in (%dx),%al # <------ First "in" corresponding to inb(cx->address) + 0.51 │ mov 0x144d64d(%rip),%rax + 0.00 │ test $0x80000000,%eax + │ ↓ jne 62 # <------ Skip if running in guest + 0.00 │ mov 0x19800c3(%rip),%rdx + 99.33 │ in (%dx),%eax # <------ Second "in" corresponding to inl(acpi_gbl_FADT.xpm_timer_block.address) + 0.00 │62: mov -0x8(%rbp),%r12 + 0.00 │ leave + 0.00 │ ← ret + +This overhead is reflected in the C2 residency on the test system where +C2 is an IOPORT based C-State. The total C-state residency reported by +"cpupower idle-info" on CPU0 for good and bad case over the 80s tbench +run is as follows (all numbers are in microseconds): + + Good Run Bad Run + (Baseline) + +POLL: 43338 6231 (-85.62%) +C1 (MWAIT Based): 23576156 363861 (-98.45%) +C2 (IOPORT Based): 10781218 77027280 (+614.45%) + +The larger residency value in bad case leads to the system recommending +C2 state again for subsequent idle instances. The pattern lasts till the +end of the tbench run. Following is the breakdown of "entry_method" +passed to acpi_idle_do_entry during good run and bad run: + + Good Run Bad Run + (Baseline) + +Number of times acpi_idle_do_entry was called: 6149573 6149050 (-0.01%) + |-> Number of times entry_method was "ACPI_CSTATE_FFH": 6141494 88144 (-98.56%) + |-> Number of times entry_method was "ACPI_CSTATE_HALT": 0 0 (+0.00%) + |-> Number of times entry_method was "ACPI_CSTATE_SYSTEMIO": 8079 6060906 (+74920.49%) + +For processors based on the Zen microarchitecture, this dummy wait op is +unnecessary and can be skipped when choosing IOPORT based C-States to +avoid polluting the C-state residency information. + +Link: https://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux-fullhistory.git/commit/?id=972c16130d9dc182cedcdd408408d9eacc7d6a2d [1] +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b488f02156d3deb08f5ad7816d565c370a8cc6f1 [2] + +Suggested-by: Calvin Ong <calvin.ong@amd.com> +Cc: stable@vger.kernel.org +Cc: regressions@lists.linux.dev +Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com> +--- + drivers/acpi/processor_idle.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index 16a1663d02d4..18850aa2b79b 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -527,9 +527,11 @@ + static void wait_for_freeze(void) + { + #ifdef CONFIG_X86 +- /* No delay is needed if we are in guest */ +- if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) +- return; ++ /* ++ * No delay is needed if we are in guest or on a processor ++ * based on the Zen microarchitecture. ++ */ ++ if (boot_cpu_has(X86_FEATURE_HYPERVISOR) || boot_cpu_has(X86_FEATURE_ZEN)) + /* + * Modern (>=Nehalem) Intel systems use ACPI via intel_idle, + * not this code. Assume that any Intel systems using this + +-- +2.25.1 diff --git a/0001-linux6.0.y-bore1.7.5.patch b/0001-linux6.0.y-bore1.7.5.patch new file mode 100644 index 000000000000..89281b292f78 --- /dev/null +++ b/0001-linux6.0.y-bore1.7.5.patch @@ -0,0 +1,461 @@ +From 33d4c5a2808aeb991653f9c4cecd7320434f1ea1 Mon Sep 17 00:00:00 2001 +From: Masahito S <firelzrd@gmail.com> +Date: Sun, 18 Dec 2022 15:26:15 +0900 +Subject: [PATCH] linux6.0.y-bore1.7.5 + +--- + include/linux/sched.h | 5 ++ + init/Kconfig | 20 +++++ + kernel/sched/core.c | 29 +++++++ + kernel/sched/debug.c | 3 + + kernel/sched/fair.c | 166 ++++++++++++++++++++++++++++++++++++++-- + kernel/sched/features.h | 4 + + 6 files changed, 220 insertions(+), 7 deletions(-) + +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 8d82d6d32..a53340011 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -545,6 +545,11 @@ struct sched_entity { + u64 sum_exec_runtime; + u64 vruntime; + u64 prev_sum_exec_runtime; ++#ifdef CONFIG_SCHED_BORE ++ u64 prev_burst_time; ++ u64 burst_time; ++ u8 burst_score; ++#endif // CONFIG_SCHED_BORE + + u64 nr_migrations; + +diff --git a/init/Kconfig b/init/Kconfig +index d1d779d6b..04a0b6b20 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1272,6 +1272,26 @@ config CHECKPOINT_RESTORE + + If unsure, say N here. + ++config SCHED_BORE ++ bool "Burst-Oriented Response Enhancer" ++ default y ++ help ++ In Desktop and Mobile computing, one might prefer interactive ++ tasks to keep responsive no matter what they run in the background. ++ ++ Enabling this kernel feature modifies the scheduler to discriminate ++ tasks by their burst time (runtime since it last went sleeping or ++ yielding state) and prioritize those that run less bursty. ++ Such tasks usually include window compositor, widgets backend, ++ terminal emulator, video playback, games and so on. ++ With a little impact to scheduling fairness, it may improve ++ responsiveness especially under heavy background workload. ++ ++ You can turn it off by setting the sysctl kernel.sched_bore = 0. ++ Enabling this feature implies NO_GENTLE_FAIR_SLEEPERS by default. ++ ++ If unsure say Y here. ++ + config SCHED_AUTOGROUP + bool "Automatic process group scheduling" + select CGROUPS +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index ee28253c9..0a9d220fc 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -4320,6 +4320,22 @@ int wake_up_state(struct task_struct *p, unsigned int state) + return try_to_wake_up(p, state, 0); + } + ++#ifdef CONFIG_SCHED_BORE ++static inline void sched_on_fork_calc_prev_burst_from_siblings(struct task_struct *p) ++{ ++ struct task_struct *sib; ++ u64 sum = 0, avg = 0; ++ u32 cnt = 0; ++ list_for_each_entry(sib, &p->sibling, sibling) { ++ cnt++; ++ sum += sib->se.prev_burst_time; ++ } ++ if (cnt) avg = sum / cnt; ++ p->se.prev_burst_time = max(p->se.prev_burst_time, avg); ++ p->se.burst_time = 0; ++} ++#endif // CONFIG_SCHED_BORE ++ + /* + * Perform scheduler related setup for a newly forked process p. + * p is forked by current. +@@ -4336,6 +4352,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) + p->se.prev_sum_exec_runtime = 0; + p->se.nr_migrations = 0; + p->se.vruntime = 0; ++#ifdef CONFIG_SCHED_BORE ++ p->se.burst_time = 0; ++#endif // CONFIG_SCHED_BORE + INIT_LIST_HEAD(&p->se.group_node); + + #ifdef CONFIG_FAIR_GROUP_SCHED +@@ -4536,6 +4555,9 @@ late_initcall(sched_core_sysctl_init); + int sched_fork(unsigned long clone_flags, struct task_struct *p) + { + __sched_fork(clone_flags, p); ++#ifdef CONFIG_SCHED_BORE ++ sched_on_fork_calc_prev_burst_from_siblings(p); ++#endif // CONFIG_SCHED_BORE + /* + * We mark the process as NEW here. This guarantees that + * nobody will actually run it, and a signal or other external +@@ -8947,6 +8969,9 @@ void __init init_idle(struct task_struct *idle, int cpu) + + idle->__state = TASK_RUNNING; + idle->se.exec_start = sched_clock(); ++#ifdef CONFIG_SCHED_BORE ++ idle->se.prev_burst_time = 0; ++#endif //CONFIG_SCHED_BORE + /* + * PF_KTHREAD should already be set at this point; regardless, make it + * look like a proper per-CPU kthread. +@@ -9617,6 +9642,10 @@ void __init sched_init(void) + BUG_ON(&dl_sched_class != &stop_sched_class + 1); + #endif + ++#ifdef CONFIG_SCHED_BORE ++ printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification 1.7.5 by Masahito Suzuki"); ++#endif // CONFIG_SCHED_BORE ++ + wait_bit_init(); + + #ifdef CONFIG_FAIR_GROUP_SCHED +diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c +index 667876da8..e9f7a9cb0 100644 +--- a/kernel/sched/debug.c ++++ b/kernel/sched/debug.c +@@ -546,6 +546,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p) + SPLIT_NS(schedstat_val_or_zero(p->stats.sum_sleep_runtime)), + SPLIT_NS(schedstat_val_or_zero(p->stats.sum_block_runtime))); + ++#ifdef CONFIG_SCHED_BORE ++ SEQ_printf(m, " %2d", p->se.burst_score); ++#endif + #ifdef CONFIG_NUMA_BALANCING + SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p)); + #endif +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 914096c5b..a37e26794 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -19,6 +19,9 @@ + * + * Adaptive scheduling granularity, math enhancements by Peter Zijlstra + * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra ++ * ++ * Burst-Oriented Response Enhancer (BORE) CPU Scheduler ++ * Copyright (C) 2021 Masahito Suzuki <firelzrd@gmail.com> + */ + #include <linux/energy_model.h> + #include <linux/mmap_lock.h> +@@ -66,10 +69,16 @@ + * (to see the precise effective timeslice length of your workload, + * run vmstat and monitor the context-switches (cs) field) + * +- * (default: 6ms * (1 + ilog(ncpus)), units: nanoseconds) ++ * (BORE default: 12.8ms constant, units: nanoseconds) ++ * (CFS default: 6ms * (1 + ilog(ncpus)), units: nanoseconds) + */ ++#ifdef CONFIG_SCHED_BORE ++unsigned int sysctl_sched_latency = 12800000ULL; ++static unsigned int normalized_sysctl_sched_latency = 12800000ULL; ++#else // CONFIG_SCHED_BORE + unsigned int sysctl_sched_latency = 6000000ULL; + static unsigned int normalized_sysctl_sched_latency = 6000000ULL; ++#endif // CONFIG_SCHED_BORE + + /* + * The initial- and re-scaling of tunables is configurable +@@ -80,25 +89,41 @@ static unsigned int normalized_sysctl_sched_latency = 6000000ULL; + * SCHED_TUNABLESCALING_LOG - scaled logarithmical, *1+ilog(ncpus) + * SCHED_TUNABLESCALING_LINEAR - scaled linear, *ncpus + * +- * (default SCHED_TUNABLESCALING_LOG = *(1+ilog(ncpus)) ++ * (BORE default SCHED_TUNABLESCALING_NONE = *1 constant) ++ * (CFS default SCHED_TUNABLESCALING_LOG = *(1+ilog(ncpus)) + */ ++#ifdef CONFIG_SCHED_BORE ++unsigned int sysctl_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE; ++#else // CONFIG_SCHED_BORE + unsigned int sysctl_sched_tunable_scaling = SCHED_TUNABLESCALING_LOG; ++#endif // CONFIG_SCHED_BORE + + /* + * Minimal preemption granularity for CPU-bound tasks: + * +- * (default: 0.75 msec * (1 + ilog(ncpus)), units: nanoseconds) ++ * (BORE default: 1.6 msec constant, units: nanoseconds) ++ * (CFS default: 0.75 msec * (1 + ilog(ncpus)), units: nanoseconds) + */ ++#ifdef CONFIG_SCHED_BORE ++unsigned int sysctl_sched_min_granularity = 1600000ULL; ++static unsigned int normalized_sysctl_sched_min_granularity = 1600000ULL; ++#else // CONFIG_SCHED_BORE + unsigned int sysctl_sched_min_granularity = 750000ULL; + static unsigned int normalized_sysctl_sched_min_granularity = 750000ULL; ++#endif // CONFIG_SCHED_BORE + + /* + * Minimal preemption granularity for CPU-bound SCHED_IDLE tasks. + * Applies only when SCHED_IDLE tasks compete with normal tasks. + * +- * (default: 0.75 msec) ++ * (BORE default: 1.6 msec constant) ++ * (CFS default: 0.75 msec) + */ ++#ifdef CONFIG_SCHED_BORE ++unsigned int sysctl_sched_idle_min_granularity = 1600000ULL; ++#else // CONFIG_SCHED_BORE + unsigned int sysctl_sched_idle_min_granularity = 750000ULL; ++#endif // CONFIG_SCHED_BORE + + /* + * This value is kept at sysctl_sched_latency/sysctl_sched_min_granularity +@@ -118,13 +143,29 @@ unsigned int sysctl_sched_child_runs_first __read_mostly; + * and reduces their over-scheduling. Synchronous workloads will still + * have immediate wakeup/sleep latencies. + * +- * (default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds) ++ * (BORE default: 4.8 msec constant, units: nanoseconds) ++ * (CFS default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds) + */ ++#ifdef CONFIG_SCHED_BORE ++unsigned int sysctl_sched_wakeup_granularity = 4800000UL; ++static unsigned int normalized_sysctl_sched_wakeup_granularity = 4800000UL; ++#else // CONFIG_SCHED_BORE + unsigned int sysctl_sched_wakeup_granularity = 1000000UL; + static unsigned int normalized_sysctl_sched_wakeup_granularity = 1000000UL; ++#endif // CONFIG_SCHED_BORE + + const_debug unsigned int sysctl_sched_migration_cost = 500000UL; + ++#ifdef CONFIG_SCHED_BORE ++unsigned int __read_mostly sched_bore = 1; ++unsigned int __read_mostly sched_burst_penalty_scale = 1256; ++unsigned int __read_mostly sched_burst_granularity = 12; ++unsigned int __read_mostly sched_burst_smoothness = 1; ++static int three = 3; ++static int sixty_four = 64; ++static int maxval_12_bits = 4095; ++#endif // CONFIG_SCHED_BORE ++ + int sched_thermal_decay_shift; + static int __init setup_sched_thermal_decay_shift(char *str) + { +@@ -179,6 +220,44 @@ static unsigned int sysctl_sched_cfs_bandwidth_slice = 5000UL; + + #ifdef CONFIG_SYSCTL + static struct ctl_table sched_fair_sysctls[] = { ++#ifdef CONFIG_SCHED_BORE ++ { ++ .procname = "sched_bore", ++ .data = &sched_bore, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = &three, ++ }, ++ { ++ .procname = "sched_burst_penalty_scale", ++ .data = &sched_burst_penalty_scale, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = &maxval_12_bits, ++ }, ++ { ++ .procname = "sched_burst_granularity", ++ .data = &sched_burst_granularity, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = &sixty_four, ++ }, ++ { ++ .procname = "sched_burst_smoothness", ++ .data = &sched_burst_smoothness, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = &three, ++ }, ++#endif // CONFIG_SCHED_BORE + { + .procname = "sched_child_runs_first", + .data = &sysctl_sched_child_runs_first, +@@ -879,6 +958,36 @@ static void update_tg_load_avg(struct cfs_rq *cfs_rq) + } + #endif /* CONFIG_SMP */ + ++#ifdef CONFIG_SCHED_BORE ++static inline void update_burst_score(struct sched_entity *se) { ++ u64 burst_count; ++ u32 msb, bcnt_prec10; ++ ++ burst_count = max(se->burst_time, se->prev_burst_time) >> sched_burst_granularity; ++ msb = fls64(burst_count); ++ bcnt_prec10 = (msb << 10) | (burst_count << ((65 - msb) & 0x3F) >> 54); ++ se->burst_score = min(bcnt_prec10 * sched_burst_penalty_scale >> 20, (u32)39); ++} ++ ++static u64 burst_scale(u64 delta, struct sched_entity *se) { ++ return mul_u64_u32_shr(delta, sched_prio_to_wmult[se->burst_score], 22); ++} ++ ++static u64 calc_delta_fair_bscale(u64 delta, struct sched_entity *se) { ++ return burst_scale(calc_delta_fair(delta, se), se); ++} ++ ++static inline u64 binary_smooth(u64 old, u64 new, unsigned int smoothness) { ++ return (new + old * ((1 << smoothness) - 1)) >> smoothness; ++} ++ ++static inline void reset_burst(struct sched_entity *se) { ++ se->prev_burst_time = binary_smooth( ++ se->prev_burst_time, se->burst_time, sched_burst_smoothness); ++ se->burst_time = 0; ++} ++#endif // CONFIG_SCHED_BORE ++ + /* + * Update the current task's runtime statistics. + */ +@@ -908,6 +1017,13 @@ static void update_curr(struct cfs_rq *cfs_rq) + curr->sum_exec_runtime += delta_exec; + schedstat_add(cfs_rq->exec_clock, delta_exec); + ++#ifdef CONFIG_SCHED_BORE ++ curr->burst_time += delta_exec; ++ update_burst_score(curr); ++ if (sched_bore & 1) ++ curr->vruntime += calc_delta_fair_bscale(delta_exec, curr); ++ else ++#endif // CONFIG_SCHED_BORE + curr->vruntime += calc_delta_fair(delta_exec, curr); + update_min_vruntime(cfs_rq); + +@@ -4641,6 +4757,11 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) + se->prev_sum_exec_runtime = se->sum_exec_runtime; + } + ++#ifdef CONFIG_SCHED_BORE ++static int ++wakeup_preempt_entity_bscale(struct sched_entity *curr, ++ struct sched_entity *se, bool do_scale); ++#endif // CONFIG_SCHED_BORE + static int + wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se); + +@@ -4685,7 +4806,13 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr) + se = second; + } + +- if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, left) < 1) { ++#ifdef CONFIG_SCHED_BORE ++ if (cfs_rq->next && wakeup_preempt_entity_bscale( ++ cfs_rq->next, left, sched_bore & 2) < 1) ++#else // CONFIG_SCHED_BORE ++ if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, left) < 1) ++#endif // CONFIG_SCHED_BORE ++ { + /* + * Someone really wants this to run. If it's not unfair, run it. + */ +@@ -5831,6 +5958,9 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) + util_est_dequeue(&rq->cfs, p); + + for_each_sched_entity(se) { ++#ifdef CONFIG_SCHED_BORE ++ if (task_sleep) reset_burst(se); ++#endif // CONFIG_SCHED_BORE + cfs_rq = cfs_rq_of(se); + dequeue_entity(cfs_rq, se, flags); + +@@ -7182,7 +7312,12 @@ static unsigned long wakeup_gran(struct sched_entity *se) + * + */ + static int ++#ifdef CONFIG_SCHED_BORE ++wakeup_preempt_entity_bscale(struct sched_entity *curr, ++ struct sched_entity *se, bool do_scale) ++#else // CONFIG_SCHED_BORE + wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se) ++#endif // CONFIG_SCHED_BORE + { + s64 gran, vdiff = curr->vruntime - se->vruntime; + +@@ -7190,11 +7325,20 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se) + return -1; + + gran = wakeup_gran(se); ++#ifdef CONFIG_SCHED_BORE ++ if (do_scale) gran = burst_scale(gran, se); ++#endif // CONFIG_SCHED_BORE + if (vdiff > gran) + return 1; + + return 0; + } ++#ifdef CONFIG_SCHED_BORE ++static int wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se) ++{ ++ return wakeup_preempt_entity_bscale(curr, se, false); ++} ++#endif // CONFIG_SCHED_BORE + + static void set_last_buddy(struct sched_entity *se) + { +@@ -7294,7 +7438,12 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ + return; + + update_curr(cfs_rq_of(se)); +- if (wakeup_preempt_entity(se, pse) == 1) { ++#ifdef CONFIG_SCHED_BORE ++ if (wakeup_preempt_entity_bscale(se, pse, sched_bore & 2) == 1) ++#else // CONFIG_SCHED_BORE ++ if (wakeup_preempt_entity(se, pse) == 1) ++#endif // CONFIG_SCHED_BORE ++ { + /* + * Bias pick_next to pick the sched entity that is + * triggering this preemption. +@@ -7530,6 +7679,9 @@ static void yield_task_fair(struct rq *rq) + struct task_struct *curr = rq->curr; + struct cfs_rq *cfs_rq = task_cfs_rq(curr); + struct sched_entity *se = &curr->se; ++#ifdef CONFIG_SCHED_BORE ++ reset_burst(se); ++#endif // CONFIG_SCHED_BORE + + /* + * Are we the only task in the tree? +diff --git a/kernel/sched/features.h b/kernel/sched/features.h +index ee7f23c76..0f2396e52 100644 +--- a/kernel/sched/features.h ++++ b/kernel/sched/features.h +@@ -4,7 +4,11 @@ + * them to run sooner, but does not allow tons of sleepers to + * rip the spread apart. + */ ++#ifdef CONFIG_SCHED_BORE ++SCHED_FEAT(GENTLE_FAIR_SLEEPERS, false) ++#else // CONFIG_SCHED_BORE + SCHED_FEAT(GENTLE_FAIR_SLEEPERS, true) ++#endif // CONFIG_SCHED_BORE + + /* + * Place new tasks ahead so that they do not starve already running +-- +2.25.1 + diff --git a/0001-perf-urgent-2023-01-06_Intel-RAPL-updates-for-new-model-IDs.patch b/0001-perf-urgent-2023-01-06_Intel-RAPL-updates-for-new-model-IDs.patch new file mode 100644 index 000000000000..cfdd5df2262d --- /dev/null +++ b/0001-perf-urgent-2023-01-06_Intel-RAPL-updates-for-new-model-IDs.patch @@ -0,0 +1,30 @@ +From 57512b57dcfaf63c52d8ad2fb35321328cde31b0 Mon Sep 17 00:00:00 2001 +From: Zhang Rui <rui.zhang@intel.com> +Date: Wed, 4 Jan 2023 22:58:31 +0800 +Subject: perf/x86/rapl: Add support for Intel Emerald Rapids + +Emerald Rapids RAPL support is the same as previous Sapphire Rapids. +Add Emerald Rapids model for RAPL. + +Signed-off-by: Zhang Rui <rui.zhang@intel.com> +Signed-off-by: Ingo Molnar <mingo@kernel.org> +Link: https://lore.kernel.org/r/20230104145831.25498-2-rui.zhang@intel.com +--- + arch/x86/events/rapl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c +index 589c6885560d2..52e6e7ed4f78a 100644 +--- a/arch/x86/events/rapl.c ++++ b/arch/x86/events/rapl.c +@@ -806,6 +806,7 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = { + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &model_skl), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &model_skl), + X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &model_spr), ++ X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &model_spr), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &model_skl), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &model_skl), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &model_skl), +-- +cgit + diff --git a/0001-platform-x86-asus-wmi-Add-safety-checks-to-dgpu-egpu.patch b/0001-platform-x86-asus-wmi-Add-safety-checks-to-dgpu-egpu.patch new file mode 100644 index 000000000000..cef15e44df06 --- /dev/null +++ b/0001-platform-x86-asus-wmi-Add-safety-checks-to-dgpu-egpu.patch @@ -0,0 +1,87 @@ +From 9eccb147466f00a13c593ac078d8639e1eafe3a2 Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Fri, 14 Oct 2022 10:43:09 +1300 +Subject: [PATCH] platform/x86: asus-wmi: Add safety checks to dgpu/egpu/mux + methods + +The WMI methods for dgpu_disable, egpu_enable, and gpu_mux_mode have +no internal safety checks. This means it is possible for a user to +set the gpu mux to discreet mode and then disable the dgpu, resulting +in the user having no screen and very little chance of recovery. + +This commit adds checks to dgpu_disable and egpu_enable to ensure that +the dgpu can not be disabled if the MUX is in discreet mode, and a +check to gpu_mux_mode to prevent switching to discreet mode if +dgpu_disable is set. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/platform/x86/asus-wmi.c | 38 +++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 6e8e093f96b3..1afc4d40fa1a 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -615,6 +615,18 @@ static ssize_t dgpu_disable_store(struct device *dev, + if (disable > 1) + return -EINVAL; + ++ /* ++ * The GPU MUX must be checked first, if it is in discreet mode the ++ * dgpu_disable cannot be set to on or users can end up with no screen. ++ */ ++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX); ++ if (result < 0) ++ return result; ++ if (!result && disable) { ++ pr_warn("ASUS MUX is in discreet mode, can not set dgpu_disable on\n"); ++ return -EINVAL; ++ } ++ + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, disable, &result); + if (err) { + pr_warn("Failed to set dgpu disable: %d\n", err); +@@ -663,6 +675,19 @@ static ssize_t egpu_enable_store(struct device *dev, + if (enable > 1) + return -EINVAL; + ++ /* ++ * The GPU MUX must be checked first, if it is in discreet mode the ++ * egpu_enable cannot be set to on or users can end up with no screen. ++ * Note: egpu_enable method in WMI also sets dgpu_disable to on. ++ */ ++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX); ++ if (result < 0) ++ return result; ++ if (!result && enable) { ++ pr_warn("ASUS MUX is in discreet mode, can not set egpu_enable on\n"); ++ return -EINVAL; ++ } ++ + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, enable, &result); + if (err) { + pr_warn("Failed to set egpu disable: %d\n", err); +@@ -709,6 +734,19 @@ static ssize_t gpu_mux_mode_store(struct device *dev, + if (optimus > 1) + return -EINVAL; + ++ /* ++ * The dgpu_disable must be checked first, if it is enabled the ++ * gpu MUX can not be set to 0 or users can end up with no screen. ++ * Note: egpu_enable also switches dgpu_disable to 1 if enabled. ++ */ ++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_DGPU); ++ if (result < 0) ++ return result; ++ if (result && !optimus) { ++ pr_warn("ASUS dgpu_disable is set, can not switch MUX to discreet mode\n"); ++ return -EINVAL; ++ } ++ + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result); + if (err) { + dev_err(dev, "Failed to set GPU MUX mode: %d\n", err); +-- +2.37.3 + diff --git a/0002-mm-add-vma_has_recency.patch b/0002-mm-add-vma_has_recency.patch new file mode 100644 index 000000000000..a89e9dbfd430 --- /dev/null +++ b/0002-mm-add-vma_has_recency.patch @@ -0,0 +1,272 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <mm-commits-owner@vger.kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id CC018C4708D + for <mm-commits@archiver.kernel.org>; Fri, 6 Jan 2023 04:01:50 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230391AbjAFEBs (ORCPT <rfc822;mm-commits@archiver.kernel.org>); + Thu, 5 Jan 2023 23:01:48 -0500 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51158 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229451AbjAFEBr (ORCPT + <rfc822;mm-commits@vger.kernel.org>); Thu, 5 Jan 2023 23:01:47 -0500 +Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4B3F58823 + for <mm-commits@vger.kernel.org>; Thu, 5 Jan 2023 20:01:45 -0800 (PST) +Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by ams.source.kernel.org (Postfix) with ESMTPS id 140BEB81BF2 + for <mm-commits@vger.kernel.org>; Fri, 6 Jan 2023 04:01:44 +0000 (UTC) +Received: by smtp.kernel.org (Postfix) with ESMTPSA id B0003C433EF; + Fri, 6 Jan 2023 04:01:42 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; + s=korg; t=1672977702; + bh=7zSic2DGIWJrj3nEVeQolG37z5vgL/uWIN4VclkJKxs=; + h=Date:To:From:Subject:From; + b=sPtfupKVP7QuLG4IuLVrxCUgZYbLdgcREwcG3M29EV9ZD4LAJfXZAhFrvOzFvgE+j + Hw8zQCw8HdEK8WmVvXea4T4iJiNvfUfTI1nEDG+ja8BG28GBP+NQ0o18zQ/dJdWNQN + iOpXS1Sl970AE/6EmQ2xcu62Yk/BVTpgm5z1gexI= +Date: Thu, 05 Jan 2023 20:01:41 -0800 +To: mm-commits@vger.kernel.org, viro@zeniv.linux.org.uk, + Michael@MichaelLarabel.com, hannes@cmpxchg.org, + andrea.righi@canonical.com, yuzhao@google.com, + akpm@linux-foundation.org +From: Andrew Morton <akpm@linux-foundation.org> +Subject: + mm-add-vma_has_recency.patch added to mm-unstable branch +Message-Id: <20230106040142.B0003C433EF@smtp.kernel.org> +Precedence: bulk +Reply-To: linux-kernel@vger.kernel.org +List-ID: <mm-commits.vger.kernel.org> +X-Mailing-List: mm-commits@vger.kernel.org + + +The patch titled + Subject: mm: add vma_has_recency() +has been added to the -mm mm-unstable branch. Its filename is + mm-add-vma_has_recency.patch + +This patch will shortly appear at + https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-add-vma_has_recency.patch + +This patch will later appear in the mm-unstable branch at + git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm + +Before you just go and hit "reply", please: + a) Consider who else should be cc'ed + b) Prefer to cc a suitable mailing list as well + c) Ideally: find the original patch on the mailing list and do a + reply-to-all to that, adding suitable additional cc's + +*** Remember to use Documentation/process/submit-checklist.rst when testing your code *** + +The -mm tree is included into linux-next via the mm-everything +branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm +and is updated there every 2-3 working days + +------------------------------------------------------ +From: Yu Zhao <yuzhao@google.com> +Subject: mm: add vma_has_recency() +Date: Fri, 30 Dec 2022 14:52:51 -0700 + +Add vma_has_recency() to indicate whether a VMA may exhibit temporal +locality that the LRU algorithm relies on. + +This function returns false for VMAs marked by VM_SEQ_READ or +VM_RAND_READ. While the former flag indicates linear access, i.e., a +special case of spatial locality, both flags indicate a lack of temporal +locality, i.e., the reuse of an area within a relatively small duration. + +"Recency" is chosen over "locality" to avoid confusion between temporal +and spatial localities. + +Before this patch, the active/inactive LRU only ignored the accessed bit +from VMAs marked by VM_SEQ_READ. After this patch, the active/inactive +LRU and MGLRU share the same logic: they both ignore the accessed bit if +vma_has_recency() returns false. + +For the active/inactive LRU, the following fio test showed a [6, 8]% +increase in IOPS when randomly accessing mapped files under memory +pressure. + + kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo) + kb=$((kb - 8*1024*1024)) + + modprobe brd rd_nr=1 rd_size=$kb + dd if=/dev/zero of=/dev/ram0 bs=1M + + mkfs.ext4 /dev/ram0 + mount /dev/ram0 /mnt/ + swapoff -a + + fio --name=test --directory=/mnt/ --ioengine=mmap --numjobs=8 \ + --size=8G --rw=randrw --time_based --runtime=10m \ + --group_reporting + +The discussion that led to this patch is here [1]. Additional test +results are available in that thread. + +[1] https://lore.kernel.org/r/Y31s%2FK8T85jh05wH@google.com/ + +Link: https://lkml.kernel.org/r/20221230215252.2628425-1-yuzhao@google.com +Signed-off-by: Yu Zhao <yuzhao@google.com> +Cc: Alexander Viro <viro@zeniv.linux.org.uk> +Cc: Andrea Righi <andrea.righi@canonical.com> +Cc: Johannes Weiner <hannes@cmpxchg.org> +Cc: Michael Larabel <Michael@MichaelLarabel.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +--- + + include/linux/mm_inline.h | 8 ++++++ + mm/memory.c | 7 ++---- + mm/rmap.c | 42 +++++++++++++++--------------------- + mm/vmscan.c | 5 +++- + 4 files changed, 33 insertions(+), 29 deletions(-) + +--- a/include/linux/mm_inline.h~mm-add-vma_has_recency ++++ a/include/linux/mm_inline.h +@@ -594,4 +594,12 @@ pte_install_uffd_wp_if_needed(struct vm_ + #endif + } + ++static inline bool vma_has_recency(struct vm_area_struct *vma) ++{ ++ if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) ++ return false; ++ ++ return true; ++} ++ + #endif +--- a/mm/memory.c~mm-add-vma_has_recency ++++ a/mm/memory.c +@@ -1402,8 +1402,7 @@ again: + force_flush = 1; + } + } +- if (pte_young(ptent) && +- likely(!(vma->vm_flags & VM_SEQ_READ))) ++ if (pte_young(ptent) && likely(vma_has_recency(vma))) + mark_page_accessed(page); + } + rss[mm_counter(page)]--; +@@ -5118,8 +5117,8 @@ static inline void mm_account_fault(stru + #ifdef CONFIG_LRU_GEN + static void lru_gen_enter_fault(struct vm_area_struct *vma) + { +- /* the LRU algorithm doesn't apply to sequential or random reads */ +- current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)); ++ /* the LRU algorithm only applies to accesses with recency */ ++ current->in_lru_fault = vma_has_recency(vma); + } + + static void lru_gen_exit_fault(void) +--- a/mm/rmap.c~mm-add-vma_has_recency ++++ a/mm/rmap.c +@@ -824,25 +824,14 @@ static bool folio_referenced_one(struct + } + + if (pvmw.pte) { +- if (lru_gen_enabled() && pte_young(*pvmw.pte) && +- !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) { ++ if (lru_gen_enabled() && pte_young(*pvmw.pte)) { + lru_gen_look_around(&pvmw); + referenced++; + } + + if (ptep_clear_flush_young_notify(vma, address, +- pvmw.pte)) { +- /* +- * Don't treat a reference through +- * a sequentially read mapping as such. +- * If the folio has been used in another mapping, +- * we will catch it; if this other mapping is +- * already gone, the unmap path will have set +- * the referenced flag or activated the folio. +- */ +- if (likely(!(vma->vm_flags & VM_SEQ_READ))) +- referenced++; +- } ++ pvmw.pte)) ++ referenced++; + } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { + if (pmdp_clear_flush_young_notify(vma, address, + pvmw.pmd)) +@@ -876,7 +865,20 @@ static bool invalid_folio_referenced_vma + struct folio_referenced_arg *pra = arg; + struct mem_cgroup *memcg = pra->memcg; + +- if (!mm_match_cgroup(vma->vm_mm, memcg)) ++ /* ++ * Ignore references from this mapping if it has no recency. If the ++ * folio has been used in another mapping, we will catch it; if this ++ * other mapping is already gone, the unmap path will have set the ++ * referenced flag or activated the folio in zap_pte_range(). ++ */ ++ if (!vma_has_recency(vma)) ++ return true; ++ ++ /* ++ * If we are reclaiming on behalf of a cgroup, skip counting on behalf ++ * of references from different cgroups. ++ */ ++ if (memcg && !mm_match_cgroup(vma->vm_mm, memcg)) + return true; + + return false; +@@ -907,6 +909,7 @@ int folio_referenced(struct folio *folio + .arg = (void *)&pra, + .anon_lock = folio_lock_anon_vma_read, + .try_lock = true, ++ .invalid_vma = invalid_folio_referenced_vma, + }; + + *vm_flags = 0; +@@ -922,15 +925,6 @@ int folio_referenced(struct folio *folio + return 1; + } + +- /* +- * If we are reclaiming on behalf of a cgroup, skip +- * counting on behalf of references from different +- * cgroups +- */ +- if (memcg) { +- rwc.invalid_vma = invalid_folio_referenced_vma; +- } +- + rmap_walk(folio, &rwc); + *vm_flags = pra.vm_flags; + +--- a/mm/vmscan.c~mm-add-vma_has_recency ++++ a/mm/vmscan.c +@@ -3794,7 +3794,10 @@ static int should_skip_vma(unsigned long + if (is_vm_hugetlb_page(vma)) + return true; + +- if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ)) ++ if (!vma_has_recency(vma)) ++ return true; ++ ++ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) + return true; + + if (vma == get_gate_vma(vma->vm_mm)) +_ + +Patches currently in -mm which might be from yuzhao@google.com are + +mm-multi-gen-lru-rename-lru_gen_struct-to-lru_gen_folio.patch +mm-multi-gen-lru-rename-lrugen-lists-to-lrugen-folios.patch +mm-multi-gen-lru-remove-eviction-fairness-safeguard.patch +mm-multi-gen-lru-remove-aging-fairness-safeguard.patch +mm-multi-gen-lru-shuffle-should_run_aging.patch +mm-multi-gen-lru-per-node-lru_gen_folio-lists.patch +mm-multi-gen-lru-clarify-scan_control-flags.patch +mm-multi-gen-lru-simplify-arch_has_hw_pte_young-check.patch +mm-add-vma_has_recency.patch +mm-support-posix_fadv_noreuse.patch + + diff --git a/0019-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch b/0019-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch new file mode 100644 index 000000000000..4e587a119b0e --- /dev/null +++ b/0019-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch @@ -0,0 +1,174 @@ +From 802dfc514194e5459397f513b202031228b3315a Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Fri, 26 Aug 2022 12:25:12 +1200 +Subject: [PATCH 19/19] HID: amd_sfh: Add keyguard for ASUS ROG X13 tablet + +Add support for ROG X13 Flow 2-in-1 to disable the keyboard when +the lid is flipped. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 4 +++ + drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 1 + + .../hid_descriptor/amd_sfh_hid_desc.c | 27 +++++++++++++++++++ + .../hid_descriptor/amd_sfh_hid_desc.h | 8 ++++++ + .../hid_descriptor/amd_sfh_hid_report_desc.h | 19 +++++++++++++ + 5 files changed, 59 insertions(+) + +diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +index 4b90c86ee5f8..0f4db2ce076e 100644 +--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c ++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +@@ -27,6 +27,7 @@ + #define ACEL_EN BIT(0) + #define GYRO_EN BIT(1) + #define MAGNO_EN BIT(2) ++#define KBGUARD_EN BIT(15) + #define HPD_EN BIT(16) + #define ALS_EN BIT(19) + +@@ -233,6 +234,9 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) + if (HPD_EN & activestatus) + sensor_id[num_of_sensors++] = HPD_IDX; + ++ if (KBGUARD_EN & activestatus) ++ sensor_id[num_of_sensors++] = KBGUARD_IDX; ++ + return num_of_sensors; + } + +diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +index dfb7cabd82ef..5fa15eed43f3 100644 +--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h ++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h +@@ -23,6 +23,7 @@ + #define V2_STATUS 0x2 + + #define HPD_IDX 16 ++#define KBGUARD_IDX 15 + + #define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3) + #define SENSOR_DISCOVERY_STATUS_SHIFT 3 +diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c +index f9a8c02d5a7b..06487eb75dc8 100644 +--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c ++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c +@@ -57,6 +57,11 @@ static int get_report_descriptor(int sensor_idx, u8 *rep_desc) + memcpy(rep_desc, hpd_report_descriptor, + sizeof(hpd_report_descriptor)); + break; ++ case KBGUARD_IDX: /* kbguard ? */ ++ memset(rep_desc, 0, sizeof(kbguard_report_descriptor)); ++ memcpy(rep_desc, kbguard_report_descriptor, ++ sizeof(kbguard_report_descriptor)); ++ break; + default: + break; + } +@@ -116,6 +121,16 @@ static u32 get_descr_sz(int sensor_idx, int descriptor_name) + return sizeof(struct hpd_feature_report); + } + break; ++ case KBGUARD_IDX: ++ switch (descriptor_name) { ++ case descr_size: ++ return sizeof(kbguard_report_descriptor); ++ case input_size: ++ return sizeof(struct kbguard_input_report); ++ case feature_size: ++ return sizeof(struct kbguard_feature_report); ++ } ++ break; + + default: + break; +@@ -139,6 +154,7 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) + struct gyro_feature_report gyro_feature; + struct magno_feature_report magno_feature; + struct hpd_feature_report hpd_feature; ++ struct kbguard_feature_report kbguard_feature; + struct als_feature_report als_feature; + u8 report_size = 0; + +@@ -186,6 +202,11 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) + memcpy(feature_report, &hpd_feature, sizeof(hpd_feature)); + report_size = sizeof(hpd_feature); + break; ++ case KBGUARD_IDX: /* auto disable keyboard when flip out */ ++ get_common_features(&kbguard_feature.common_property, report_id); ++ memcpy(feature_report, &kbguard_feature, sizeof(kbguard_feature)); ++ report_size = sizeof(kbguard_feature); ++ break; + + default: + break; +@@ -211,6 +232,7 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id, + struct accel3_input_report acc_input; + struct gyro_input_report gyro_input; + struct hpd_input_report hpd_input; ++ struct kbguard_input_report kbguard_input; + struct als_input_report als_input; + struct hpd_status hpdstatus; + u8 report_size = 0; +@@ -263,6 +285,11 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id, + report_size = sizeof(hpd_input); + memcpy(input_report, &hpd_input, sizeof(hpd_input)); + break; ++ case KBGUARD_IDX: /* kb guard */ ++ get_common_inputs(&kbguard_input.common_property, report_id); ++ report_size = sizeof(kbguard_input); ++ memcpy(input_report, &kbguard_input, sizeof(kbguard_input)); ++break; + default: + break; + } +diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h +index ebd55675eb62..2f2ba9a0cfbc 100644 +--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h ++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h +@@ -111,4 +111,12 @@ struct hpd_input_report { + u8 human_presence; + } __packed; + ++struct kbguard_feature_report { ++ struct common_feature_property common_property; ++} __packed; ++ ++struct kbguard_input_report { ++ struct common_input_property common_property; ++} __packed; ++ + #endif +diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h +index 697f2791ea9c..7a62fcec2c73 100644 +--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h ++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h +@@ -644,6 +644,25 @@ static const u8 als_report_descriptor[] = { + 0xC0 /* HID end collection */ + }; + ++ ++static const u8 kbguard_report_descriptor[] = { ++0x06, 0x43, 0xFF, // Usage Page (Vendor Defined 0xFF43) ++0x0A, 0x02, 0x02, // Usage (0x0202) ++0xA1, 0x01, // Collection (Application) ++0x85, 0x11, // Report ID (17) ++0x15, 0x00, // Logical Minimum (0) ++0x25, 0x01, // Logical Maximum (1) ++0x35, 0x00, // Physical Minimum (0) ++0x45, 0x01, // Physical Maximum (1) ++0x65, 0x00, // Unit (None) ++0x55, 0x00, // Unit Exponent (0) ++0x75, 0x01, // Report Size (1) ++0x95, 0x98, // Report Count (-104) ++0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) ++0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) ++0xC1, 0x00, // End Collection ++}; ++ + /* BIOMETRIC PRESENCE*/ + static const u8 hpd_report_descriptor[] = { + 0x05, 0x20, /* Usage page */ +-- +2.37.2 + diff --git a/0024-V8-0-4-PCI-vmd-Enable-PCIe-ASPM-and-LTR-on-select-hardware.patch b/0024-V8-0-4-PCI-vmd-Enable-PCIe-ASPM-and-LTR-on-select-hardware.patch new file mode 100644 index 000000000000..b71f08daabeb --- /dev/null +++ b/0024-V8-0-4-PCI-vmd-Enable-PCIe-ASPM-and-LTR-on-select-hardware.patch @@ -0,0 +1,1420 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id AC0A9C4332F + for <linux-pci@archiver.kernel.org>; Thu, 3 Nov 2022 02:18:26 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229954AbiKCCSZ (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 2 Nov 2022 22:18:25 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56134 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229436AbiKCCSY (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 2 Nov 2022 22:18:24 -0400 +Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20F35E81; + Wed, 2 Nov 2022 19:18:23 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; + d=intel.com; i=@intel.com; q=dns/txt; s=Intel; + t=1667441903; x=1698977903; + h=from:to:cc:subject:date:message-id:mime-version: + content-transfer-encoding; + bh=dRTGogFr6yFQWzAu44s2Shz3Tuu+kZ6YaOpo+8VRwtE=; + b=DMcLu2BjDmudMN0UTyyA6FzOfZelhaQ8aXzibcjvThwM3TFZjGWBNUKD + wD87ecQD9wgkVeT9M0zQMQHf/V4yToaol98pmgAsEtm240ZjfYRyDfQly + +NXTn3/83rPUqYemS0WbI7mo8eLfSBqFbrU+1UlW3xI6xLFAjkgRLVzcD + lmBHge6U5cuhjmdnCeRUWNDjVAsqPDdObXWhbzy9XAVtP9ErHwqBTLJIf + 36fdHDJUNSglpacZiiJMinGpULwMqK6jKiWcXilzqmkjsqPfVl2BYXgG5 + oPLGYSWzARxBuTWWDlcWEmjHb9o7CLwNLG1Z8LkoRGkou1I6HEtWgummX + A==; +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="395875409" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="395875409" +Received: from orsmga004.jf.intel.com ([10.7.209.38]) + by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Nov 2022 19:18:22 -0700 +X-ExtLoop1: 1 +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="759771646" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="759771646" +Received: from linux.intel.com ([10.54.29.200]) + by orsmga004.jf.intel.com with ESMTP; 02 Nov 2022 19:18:22 -0700 +Received: from debox1-desk4.intel.com (unknown [10.212.195.54]) + by linux.intel.com (Postfix) with ESMTP id 38146580D42; + Wed, 2 Nov 2022 19:18:22 -0700 (PDT) +From: "David E. Box" <david.e.box@linux.intel.com> +To: nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, + lorenzo.pieralisi@arm.com, hch@infradead.org, kw@linux.com, + robh@kernel.org, bhelgaas@google.com, david.e.box@linux.intel.com, + michael.a.bottini@intel.com, rafael@kernel.org, me@adhityamohan.in +Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH V8 0/4] PCI: vmd: Enable PCIe ASPM and LTR on select hardware +Date: Wed, 2 Nov 2022 19:18:18 -0700 +Message-Id: <20221103021822.308586-1-david.e.box@linux.intel.com> +X-Mailer: git-send-email 2.25.1 +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +This series adds a work around for enabling PCIe ASPM and for setting PCIe +LTR values on VMD reserved root ports on select platforms. While +configuration of these capabilities is usually done by BIOS, on these +platforms these capabilities will not be configured because the ports are +not visible to BIOS. This was part of an initial design that expected the +driver to completely handle the ports, including power management. However +on Linux those ports are still managed by the PCIe core, which has the +expectation that they adhere to device standards including BIOS +configuration, leading to this problem. + +The target platforms are Tiger Lake, Alder Lake, and Raptor Lake though the +latter has already implemented support for configuring the LTR values. +Meteor Lake is expected add BIOS ASPM support, eliminating the future need +for this work around. + +Note, the driver programs the LTRs because BIOS would also normally do this +for devices that do not set them by default. Without this, SoC power +management would be blocked on those platform. This SoC specific value is +the maximum latency required to allow the SoC to enter the deepest power +state. + +This patch addresses the following open bugzillas on VMD enabled laptops +that cannot enter low power states. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=212355 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=215063 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=213717 + +David E. Box (3): + PCI: vmd: Use PCI_VDEVICE in device list + PCI: vmd: Create feature grouping for client products + PCI: vmd: Add quirk to configure PCIe ASPM and LTR + +Michael Bottini (1): + PCI/ASPM: Add pci_enable_link_state() + + drivers/pci/controller/vmd.c | 96 ++++++++++++++++++++++++++---------- + drivers/pci/pcie/aspm.c | 54 ++++++++++++++++++++ + include/linux/pci.h | 7 +++ + 3 files changed, 131 insertions(+), 26 deletions(-) + + +base-commit: 247f34f7b80357943234f93f247a1ae6b6c3a740 +-- +2.25.1 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id E6F34C433FE + for <linux-pci@archiver.kernel.org>; Thu, 3 Nov 2022 02:18:29 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230314AbiKCCS2 (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 2 Nov 2022 22:18:28 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56158 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230207AbiKCCS1 (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 2 Nov 2022 22:18:27 -0400 +Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 721852618; + Wed, 2 Nov 2022 19:18:24 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; + d=intel.com; i=@intel.com; q=dns/txt; s=Intel; + t=1667441905; x=1698977905; + h=from:to:cc:subject:date:message-id:in-reply-to: + references:mime-version:content-transfer-encoding; + bh=vzUI8zH+fYLJwczHSdbiw1/5l9LlQMI1ESll22EfjJI=; + b=QmTz1hTHIb+yN2slhY+HSOi6ZVrWLgup6gAHG1HZEUvZ8Opy1vOjOIY2 + gKpgQkAc1uo1WaKGsdQYFX+Yy/iq1MHzJgiiW2Jex5v4yW0QJd7VqrONf + 8WIQLCNduJnojVdWvt6nau5D9/c48X3KgTE2Tp3/CQ8eiUR6VxqFm9S8g + RViAPgyzk+++taagSjfQuZ6NJ9/alBW7e4FIvJanRsseUdzyK5MsPFI9P + WSXMt650HNIjiK9WB8UDB0+bWM3tu7AV7nCkB5ljpWDBfnrbOtITGyNW/ + Zj8+rbcuN44uwYh6KV/09XY9xIq02Q+HNVKjB4OUEKNJWuTZBbEl/43bd + g==; +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="373794791" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="373794791" +Received: from orsmga008.jf.intel.com ([10.7.209.65]) + by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Nov 2022 19:18:23 -0700 +X-ExtLoop1: 1 +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="665784357" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="665784357" +Received: from linux.intel.com ([10.54.29.200]) + by orsmga008.jf.intel.com with ESMTP; 02 Nov 2022 19:18:22 -0700 +Received: from debox1-desk4.intel.com (unknown [10.212.195.54]) + by linux.intel.com (Postfix) with ESMTP id 94B3B580B9E; + Wed, 2 Nov 2022 19:18:22 -0700 (PDT) +From: "David E. Box" <david.e.box@linux.intel.com> +To: nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, + lorenzo.pieralisi@arm.com, hch@infradead.org, kw@linux.com, + robh@kernel.org, bhelgaas@google.com, david.e.box@linux.intel.com, + michael.a.bottini@intel.com, rafael@kernel.org, me@adhityamohan.in +Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH V8 1/4] PCI/ASPM: Add pci_enable_link_state() +Date: Wed, 2 Nov 2022 19:18:19 -0700 +Message-Id: <20221103021822.308586-2-david.e.box@linux.intel.com> +X-Mailer: git-send-email 2.25.1 +In-Reply-To: <20221103021822.308586-1-david.e.box@linux.intel.com> +References: <20221103021822.308586-1-david.e.box@linux.intel.com> +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +From: Michael Bottini <michael.a.bottini@linux.intel.com> + +Add pci_enable_link_state() to allow devices to change the default BIOS +configured states. Clears the BIOS default settings then sets the new +states and reconfigures the link under the semaphore. Also add +PCIE_LINK_STATE_ALL macro for convenience for callers that want to enable +all link states. + +Signed-off-by: Michael Bottini <michael.a.bottini@linux.intel.com> +Signed-off-by: David E. Box <david.e.box@linux.intel.com> +Acked-by: Bjorn Helgaas <bhelgaas@google.com> +--- + V8 + - No change + + V7 + - Fix description as suggested by Bjorn + - Rename function to pci_enable_link_state + + V6 + - No change + V5 + - Rename to pci_enable_default_link_state and model after + pci_disable_link_state() as suggested by Bjorn. + - Add helper PCIE_LINK_STATE_ALL which sets bits for all links states and + clock pm. + - Clarify commit language to indicate the function changes the default + link states (not ASPM policy). + V4 + - Refactor vmd_enable_apsm() to exit early, making the lines shorter + and more readable. Suggested by Christoph. + V3 + - No changes + V2 + - Use return status to print pci_info message if ASPM cannot be enabled. + - Add missing static declaration, caught by lkp@intel.com + + drivers/pci/pcie/aspm.c | 54 +++++++++++++++++++++++++++++++++++++++++ + include/linux/pci.h | 7 ++++++ + 2 files changed, 61 insertions(+) + +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c +index 53a1fa306e1e..339c686a5094 100644 +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -1181,6 +1181,60 @@ int pci_disable_link_state(struct pci_dev *pdev, int state) + } + EXPORT_SYMBOL(pci_disable_link_state); + ++/** ++ * pci_enable_link_state - Clear and set the default device link state so that ++ * the link may be allowed to enter the specified states. Note that if the ++ * BIOS didn't grant ASPM control to the OS, this does nothing because we can't ++ * touch the LNKCTL register. Also note that this does not enable states ++ * disabled by pci_disable_link_state(). Return 0 or a negative errno. ++ * ++ * @pdev: PCI device ++ * @state: Mask of ASPM link states to enable ++ */ ++int pci_enable_link_state(struct pci_dev *pdev, int state) ++{ ++ struct pcie_link_state *link = pcie_aspm_get_link(pdev); ++ ++ if (!link) ++ return -EINVAL; ++ /* ++ * A driver requested that ASPM be enabled on this device, but ++ * if we don't have permission to manage ASPM (e.g., on ACPI ++ * systems we have to observe the FADT ACPI_FADT_NO_ASPM bit and ++ * the _OSC method), we can't honor that request. ++ */ ++ if (aspm_disabled) { ++ pci_warn(pdev, "can't override BIOS ASPM; OS doesn't have ASPM control\n"); ++ return -EPERM; ++ } ++ ++ down_read(&pci_bus_sem); ++ mutex_lock(&aspm_lock); ++ link->aspm_default = 0; ++ if (state & PCIE_LINK_STATE_L0S) ++ link->aspm_default |= ASPM_STATE_L0S; ++ if (state & PCIE_LINK_STATE_L1) ++ /* L1 PM substates require L1 */ ++ link->aspm_default |= ASPM_STATE_L1 | ASPM_STATE_L1SS; ++ if (state & PCIE_LINK_STATE_L1_1) ++ link->aspm_default |= ASPM_STATE_L1_1; ++ if (state & PCIE_LINK_STATE_L1_2) ++ link->aspm_default |= ASPM_STATE_L1_2; ++ if (state & PCIE_LINK_STATE_L1_1_PCIPM) ++ link->aspm_default |= ASPM_STATE_L1_1_PCIPM; ++ if (state & PCIE_LINK_STATE_L1_2_PCIPM) ++ link->aspm_default |= ASPM_STATE_L1_2_PCIPM; ++ pcie_config_aspm_link(link, policy_to_aspm_state(link)); ++ ++ link->clkpm_default = (state & PCIE_LINK_STATE_CLKPM) ? 1 : 0; ++ pcie_set_clkpm(link, policy_to_clkpm_state(link)); ++ mutex_unlock(&aspm_lock); ++ up_read(&pci_bus_sem); ++ ++ return 0; ++} ++EXPORT_SYMBOL(pci_enable_link_state); ++ + static int pcie_aspm_set_policy(const char *val, + const struct kernel_param *kp) + { +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 2bda4a4e47e8..8c35f15e6012 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1651,10 +1651,15 @@ extern bool pcie_ports_native; + #define PCIE_LINK_STATE_L1_2 BIT(4) + #define PCIE_LINK_STATE_L1_1_PCIPM BIT(5) + #define PCIE_LINK_STATE_L1_2_PCIPM BIT(6) ++#define PCIE_LINK_STATE_ALL (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |\ ++ PCIE_LINK_STATE_CLKPM | PCIE_LINK_STATE_L1_1 |\ ++ PCIE_LINK_STATE_L1_2 | PCIE_LINK_STATE_L1_1_PCIPM |\ ++ PCIE_LINK_STATE_L1_2_PCIPM) + + #ifdef CONFIG_PCIEASPM + int pci_disable_link_state(struct pci_dev *pdev, int state); + int pci_disable_link_state_locked(struct pci_dev *pdev, int state); ++int pci_enable_link_state(struct pci_dev *pdev, int state); + void pcie_no_aspm(void); + bool pcie_aspm_support_enabled(void); + bool pcie_aspm_enabled(struct pci_dev *pdev); +@@ -1663,6 +1668,8 @@ static inline int pci_disable_link_state(struct pci_dev *pdev, int state) + { return 0; } + static inline int pci_disable_link_state_locked(struct pci_dev *pdev, int state) + { return 0; } ++static inline int pci_enable_link_state(struct pci_dev *pdev, int state) ++{ return 0; } + static inline void pcie_no_aspm(void) { } + static inline bool pcie_aspm_support_enabled(void) { return false; } + static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; } +-- +2.25.1 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 62CFCC43219 + for <linux-pci@archiver.kernel.org>; Thu, 3 Nov 2022 02:18:31 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230384AbiKCCS3 (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 2 Nov 2022 22:18:29 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56162 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230274AbiKCCS1 (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 2 Nov 2022 22:18:27 -0400 +Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 561802619; + Wed, 2 Nov 2022 19:18:24 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; + d=intel.com; i=@intel.com; q=dns/txt; s=Intel; + t=1667441905; x=1698977905; + h=from:to:cc:subject:date:message-id:in-reply-to: + references:mime-version:content-transfer-encoding; + bh=lryJqhW0QO99aVIBqjyXzXFrtjj3i89vRFLmrilFP90=; + b=Df8sKKhA92/hom2M6lfSMoLfzheO17ovcECn6UnhcRkljtkYM5G8Bwti + 4imwXXERTkouM4GDl5zIi7807l2h0WaF1hhK7FnrEfbnnslMLN7fo/GOx + tJX3o2Rmi4D1MijqjZ8OCNbIyfbjpnnrsXK87bp9Yh8yDXM5SM9qYFCtW + znugRhwhEZSBAnZJwHjonuaSm+FRxtMHCRCiKW9wVvcnsyJ4QV8npONQR + sWm5W8mWbM0jX677X3OLQWQjTVdpav3LYiTQ/yoIniJvhM3A6eGA2dI7W + epYMuCTrGWAZh4qY1C0+5X59xMO5LdSbZSUkFc1uPJsshsWZahmc7sb/f + w==; +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="395875415" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="395875415" +Received: from orsmga004.jf.intel.com ([10.7.209.38]) + by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Nov 2022 19:18:23 -0700 +X-ExtLoop1: 1 +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="759771651" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="759771651" +Received: from linux.intel.com ([10.54.29.200]) + by orsmga004.jf.intel.com with ESMTP; 02 Nov 2022 19:18:23 -0700 +Received: from debox1-desk4.intel.com (unknown [10.212.195.54]) + by linux.intel.com (Postfix) with ESMTP id F23D7580DBD; + Wed, 2 Nov 2022 19:18:22 -0700 (PDT) +From: "David E. Box" <david.e.box@linux.intel.com> +To: nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, + lorenzo.pieralisi@arm.com, hch@infradead.org, kw@linux.com, + robh@kernel.org, bhelgaas@google.com, david.e.box@linux.intel.com, + michael.a.bottini@intel.com, rafael@kernel.org, me@adhityamohan.in +Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH V8 2/4] PCI: vmd: Use PCI_VDEVICE in device list +Date: Wed, 2 Nov 2022 19:18:20 -0700 +Message-Id: <20221103021822.308586-3-david.e.box@linux.intel.com> +X-Mailer: git-send-email 2.25.1 +In-Reply-To: <20221103021822.308586-1-david.e.box@linux.intel.com> +References: <20221103021822.308586-1-david.e.box@linux.intel.com> +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +Refactor the PCI ID list to use PCI_VDEVICE. + +Signed-off-by: David E. Box <david.e.box@linux.intel.com> +Reviewed-by: Jon Derrick <jonathan.derrick@linux.dev> +Reviewed-by: Nirmal Patel <nirmal.patel@linux.intel.com> +--- + V8 - No change + + V7 - New Patch. Separate patch suggested by Lorenzo + + drivers/pci/controller/vmd.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c +index e06e9f4fc50f..9dedca714c18 100644 +--- a/drivers/pci/controller/vmd.c ++++ b/drivers/pci/controller/vmd.c +@@ -994,33 +994,33 @@ static int vmd_resume(struct device *dev) + static SIMPLE_DEV_PM_OPS(vmd_dev_pm_ops, vmd_suspend, vmd_resume); + + static const struct pci_device_id vmd_ids[] = { +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VMD_201D), ++ {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_VMD_201D), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP,}, +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VMD_28C0), ++ {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_VMD_28C0), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW | + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_CAN_BYPASS_MSI_REMAP,}, +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x467f), ++ {PCI_VDEVICE(INTEL, 0x467f), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_OFFSET_FIRST_VECTOR,}, +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c3d), ++ {PCI_VDEVICE(INTEL, 0x4c3d), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_OFFSET_FIRST_VECTOR,}, +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa77f), ++ {PCI_VDEVICE(INTEL, 0xa77f), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_OFFSET_FIRST_VECTOR,}, +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7d0b), ++ {PCI_VDEVICE(INTEL, 0x7d0b), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_OFFSET_FIRST_VECTOR,}, +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xad0b), ++ {PCI_VDEVICE(INTEL, 0xad0b), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_OFFSET_FIRST_VECTOR,}, +- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VMD_9A0B), ++ {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_VMD_9A0B), + .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_OFFSET_FIRST_VECTOR,}, +-- +2.25.1 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 2C015C4332F + for <linux-pci@archiver.kernel.org>; Thu, 3 Nov 2022 02:18:35 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230353AbiKCCSa (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 2 Nov 2022 22:18:30 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56160 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230266AbiKCCS1 (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 2 Nov 2022 22:18:27 -0400 +Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 555FCE81; + Wed, 2 Nov 2022 19:18:24 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; + d=intel.com; i=@intel.com; q=dns/txt; s=Intel; + t=1667441905; x=1698977905; + h=from:to:cc:subject:date:message-id:in-reply-to: + references:mime-version:content-transfer-encoding; + bh=HPzcsAi/d9ZZUHE0bfR05SfFvSoDaIB+WYmjKiFqpy4=; + b=V33lj/7ygFrkVPShV+DmuCKKknUkX0Q7z9HbHDxn3ShOrOfFS2Rx4nM3 + xjl0IwcP/rEPGdhppTqNFW5NIerdyqTnmdg7YyQGxPyRTucNImawYYZRW + w/yiahAjImxpdSl7IS2lptgcDAGf47ICAq5JErYk1rvNLF39QLspv62DR + CC1HN6W1abC4BX/aRlEjSpdFE1vBYY6p1K5XihseccLQ3scRbxNXZHfce + ultbE/3pOXffkDVu0W9FauUZg7J2fpEAkxtc27cyKbQ9k99h8Bfhg/3cM + +CYz+uMa0lzXX/m6KXst/qVnsCsoPJb2lYrXIcHu+Q46hgUJKrph3wKRX + g==; +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="292886416" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="292886416" +Received: from orsmga007.jf.intel.com ([10.7.209.58]) + by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Nov 2022 19:18:23 -0700 +X-ExtLoop1: 1 +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="629175111" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="629175111" +Received: from linux.intel.com ([10.54.29.200]) + by orsmga007.jf.intel.com with ESMTP; 02 Nov 2022 19:18:23 -0700 +Received: from debox1-desk4.intel.com (unknown [10.212.195.54]) + by linux.intel.com (Postfix) with ESMTP id 56E3E580B9E; + Wed, 2 Nov 2022 19:18:23 -0700 (PDT) +From: "David E. Box" <david.e.box@linux.intel.com> +To: nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, + lorenzo.pieralisi@arm.com, hch@infradead.org, kw@linux.com, + robh@kernel.org, bhelgaas@google.com, david.e.box@linux.intel.com, + michael.a.bottini@intel.com, rafael@kernel.org, me@adhityamohan.in +Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH V8 3/4] PCI: vmd: Create feature grouping for client products +Date: Wed, 2 Nov 2022 19:18:21 -0700 +Message-Id: <20221103021822.308586-4-david.e.box@linux.intel.com> +X-Mailer: git-send-email 2.25.1 +In-Reply-To: <20221103021822.308586-1-david.e.box@linux.intel.com> +References: <20221103021822.308586-1-david.e.box@linux.intel.com> +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +Simplify the device ID list by creating a grouping of features shared by +client products. + +Suggested-by: Jon Derrick <jonathan.derrick@linux.dev> +Signed-off-by: David E. Box <david.e.box@linux.intel.com> +--- + + V8 - New patch. + + drivers/pci/controller/vmd.c | 28 ++++++++++------------------ + 1 file changed, 10 insertions(+), 18 deletions(-) + +diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c +index 9dedca714c18..86f3085db014 100644 +--- a/drivers/pci/controller/vmd.c ++++ b/drivers/pci/controller/vmd.c +@@ -68,6 +68,10 @@ enum vmd_features { + VMD_FEAT_CAN_BYPASS_MSI_REMAP = (1 << 4), + }; + ++#define VMD_FEATS_CLIENT (VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | \ ++ VMD_FEAT_HAS_BUS_RESTRICTIONS | \ ++ VMD_FEAT_OFFSET_FIRST_VECTOR) ++ + static DEFINE_IDA(vmd_instance_ida); + + /* +@@ -1001,29 +1005,17 @@ static const struct pci_device_id vmd_ids[] = { + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_CAN_BYPASS_MSI_REMAP,}, + {PCI_VDEVICE(INTEL, 0x467f), +- .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | +- VMD_FEAT_HAS_BUS_RESTRICTIONS | +- VMD_FEAT_OFFSET_FIRST_VECTOR,}, ++ .driver_data = VMD_FEATS_CLIENT,}, + {PCI_VDEVICE(INTEL, 0x4c3d), +- .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | +- VMD_FEAT_HAS_BUS_RESTRICTIONS | +- VMD_FEAT_OFFSET_FIRST_VECTOR,}, ++ .driver_data = VMD_FEATS_CLIENT,}, + {PCI_VDEVICE(INTEL, 0xa77f), +- .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | +- VMD_FEAT_HAS_BUS_RESTRICTIONS | +- VMD_FEAT_OFFSET_FIRST_VECTOR,}, ++ .driver_data = VMD_FEATS_CLIENT,}, + {PCI_VDEVICE(INTEL, 0x7d0b), +- .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | +- VMD_FEAT_HAS_BUS_RESTRICTIONS | +- VMD_FEAT_OFFSET_FIRST_VECTOR,}, ++ .driver_data = VMD_FEATS_CLIENT,}, + {PCI_VDEVICE(INTEL, 0xad0b), +- .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | +- VMD_FEAT_HAS_BUS_RESTRICTIONS | +- VMD_FEAT_OFFSET_FIRST_VECTOR,}, ++ .driver_data = VMD_FEATS_CLIENT,}, + {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_VMD_9A0B), +- .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | +- VMD_FEAT_HAS_BUS_RESTRICTIONS | +- VMD_FEAT_OFFSET_FIRST_VECTOR,}, ++ .driver_data = VMD_FEATS_CLIENT,}, + {0,} + }; + MODULE_DEVICE_TABLE(pci, vmd_ids); +-- +2.25.1 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 35523C43217 + for <linux-pci@archiver.kernel.org>; Thu, 3 Nov 2022 02:18:36 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230466AbiKCCSd (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 2 Nov 2022 22:18:33 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56188 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229436AbiKCCS2 (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 2 Nov 2022 22:18:28 -0400 +Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 119BE13D48; + Wed, 2 Nov 2022 19:18:27 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; + d=intel.com; i=@intel.com; q=dns/txt; s=Intel; + t=1667441907; x=1698977907; + h=from:to:cc:subject:date:message-id:in-reply-to: + references:mime-version:content-transfer-encoding; + bh=aEiHMG/t7yyno42B1YTG/JN48w91eX/H9maLsZ24Sp0=; + b=mMsfE7DPPMYcfi/Ii0kcUlolsfkUNNfdpDmA7EcRKiHEqsMbCdeVtIRk + Qs5CyXpnBkA+g4c0G+x9fNEu1vWUsI+KTzOrr8z1OZz/DMq0WfHO+gKcz + mdEZ75Y2AE4aUxEYeyqsGTU6FpnZ+WdR3jBbPoVBp1AcyA58dVZwMkSjs + UB3PQfdysXnrfSdgMTzZMlsBsSmohnLAtn1BeKgdZtH2AHPxO6wsv9TPY + NhcRZKWd2tVPfq77Qol0XDRGQZUdWXPFZfJHQ2b2GXkeCJ75rrHeEHVvU + Rfh+HEb7GDuHamdtXYPnlkaA183sJycUDR+Vv8rYICq0j7o7a6krxEExc + A==; +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="292886417" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="292886417" +Received: from orsmga003.jf.intel.com ([10.7.209.27]) + by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Nov 2022 19:18:24 -0700 +X-ExtLoop1: 1 +X-IronPort-AV: E=McAfee;i="6500,9779,10519"; a="585619408" +X-IronPort-AV: E=Sophos;i="5.95,235,1661842800"; + d="scan'208";a="585619408" +Received: from linux.intel.com ([10.54.29.200]) + by orsmga003.jf.intel.com with ESMTP; 02 Nov 2022 19:18:24 -0700 +Received: from debox1-desk4.intel.com (unknown [10.212.195.54]) + by linux.intel.com (Postfix) with ESMTP id B46F4580DBD; + Wed, 2 Nov 2022 19:18:23 -0700 (PDT) +From: "David E. Box" <david.e.box@linux.intel.com> +To: nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, + lorenzo.pieralisi@arm.com, hch@infradead.org, kw@linux.com, + robh@kernel.org, bhelgaas@google.com, david.e.box@linux.intel.com, + michael.a.bottini@intel.com, rafael@kernel.org, me@adhityamohan.in +Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH V8 4/4] PCI: vmd: Add quirk to configure PCIe ASPM and LTR +Date: Wed, 2 Nov 2022 19:18:22 -0700 +Message-Id: <20221103021822.308586-5-david.e.box@linux.intel.com> +X-Mailer: git-send-email 2.25.1 +In-Reply-To: <20221103021822.308586-1-david.e.box@linux.intel.com> +References: <20221103021822.308586-1-david.e.box@linux.intel.com> +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +PCIe ports reserved for VMD use are not visible to BIOS and therefore not +configured to enable PCIe ASPM or LTR values (which BIOS will configure if +they are not set). Lack of this programming results in high power +consumption on laptops as reported in bugzilla. For affected products use +pci_enable_link_state to set the allowed link states for devices on the +root ports. Also set the LTR value to the maximum value needed for the SoC. + +This is a workaround for products from Rocket Lake through Alder Lake. +Raptor Lake, the latest product at this time, has already implemented LTR +configuring in BIOS. Future products will move ASPM configuration back to +BIOS as well. As this solution is intended for laptops, support is not +added for hotplug or for devices downstream of a switch on the root port. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=212355 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=215063 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=213717 + +Signed-off-by: Michael Bottini <michael.a.bottini@linux.intel.com> +Signed-off-by: David E. Box <david.e.box@linux.intel.com> +Reviewed-by: Jon Derrick <jonathan.derrick@linux.dev> +Reviewed-by: Nirmal Patel <nirmal.patel@linux.intel.com> +--- + V8 + - Removed struct vmd_device_data patch. Instead use #define for the LTR + value which is the same across all products needing the quirk. + V7 + - No change + V6 + - Set ASPM first before setting LTR. This is needed because some + devices may only have LTR set by BIOS and not ASPM + - Skip setting the LTR if the current LTR in non-zero. + V5 + - Provide the LTR value as driver data. + - Use DWORD for the config space write to avoid PCI WORD access bug. + - Set ASPM links firsts, enabling all link states, before setting a + default LTR if the capability is present + - Add kernel message that VMD is setting the device LTR. + V4 + - Refactor vmd_enable_apsm() to exit early, making the lines shorter + and more readable. Suggested by Christoph. + V3 + - No changes + V2 + - Use return status to print pci_info message if ASPM cannot be enabled. + - Add missing static declaration, caught by lkp@intel.com + drivers/pci/controller/vmd.c | 64 ++++++++++++++++++++++++++++++++---- + 1 file changed, 58 insertions(+), 6 deletions(-) + +diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c +index 86f3085db014..cba57e3091f6 100644 +--- a/drivers/pci/controller/vmd.c ++++ b/drivers/pci/controller/vmd.c +@@ -66,12 +66,22 @@ enum vmd_features { + * interrupt handling. + */ + VMD_FEAT_CAN_BYPASS_MSI_REMAP = (1 << 4), ++ ++ /* ++ * Enable ASPM on the PCIE root ports and set the default LTR of the ++ * storage devices on platforms where these values are not configured by ++ * BIOS. This is needed for laptops, which require these settings for ++ * proper power management of the SoC. ++ */ ++ VMD_FEAT_BIOS_PM_QUIRK = (1 << 5), + }; + + #define VMD_FEATS_CLIENT (VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | \ + VMD_FEAT_HAS_BUS_RESTRICTIONS | \ + VMD_FEAT_OFFSET_FIRST_VECTOR) + ++#define VMD_BIOS_PM_QUIRK_LTR 0x1003 /* 3145728 ns */ ++ + static DEFINE_IDA(vmd_instance_ida); + + /* +@@ -713,6 +723,46 @@ static void vmd_copy_host_bridge_flags(struct pci_host_bridge *root_bridge, + vmd_bridge->native_dpc = root_bridge->native_dpc; + } + ++/* ++ * Enable ASPM and LTR settings on devices that aren't configured by BIOS. ++ */ ++static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata) ++{ ++ unsigned long features = *(unsigned long *)userdata; ++ u16 ltr = VMD_BIOS_PM_QUIRK_LTR; ++ u32 ltr_reg; ++ int pos; ++ ++ if (!(features & VMD_FEAT_BIOS_PM_QUIRK)) ++ return 0; ++ ++ pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL); ++ ++ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR); ++ if (!pos) ++ return 0; ++ ++ /* ++ * Skip if the max snoop LTR is non-zero, indicating BIOS has set it ++ * so the LTR quirk is not needed. ++ */ ++ pci_read_config_dword(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, <r_reg); ++ if (!!(ltr_reg & (PCI_LTR_VALUE_MASK | PCI_LTR_SCALE_MASK))) ++ return 0; ++ ++ /* ++ * Set the default values to the maximum required by the platform to ++ * allow the deepest power management savings. Write as a DWORD where ++ * the lower word is the max snoop latency and the upper word is the ++ * max non-snoop latency. ++ */ ++ ltr_reg = (ltr << 16) | ltr; ++ pci_write_config_dword(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, ltr_reg); ++ pci_info(pdev, "VMD: Default LTR value set by driver\n"); ++ ++ return 0; ++} ++ + static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) + { + struct pci_sysdata *sd = &vmd->sysdata; +@@ -867,6 +917,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) + pci_reset_bus(child->self); + pci_assign_unassigned_bus_resources(vmd->bus); + ++ pci_walk_bus(vmd->bus, vmd_pm_enable_quirk, &features); ++ + /* + * VMD root buses are virtual and don't return true on pci_is_pcie() + * and will fail pcie_bus_configure_settings() early. It can instead be +@@ -1005,17 +1057,17 @@ static const struct pci_device_id vmd_ids[] = { + VMD_FEAT_HAS_BUS_RESTRICTIONS | + VMD_FEAT_CAN_BYPASS_MSI_REMAP,}, + {PCI_VDEVICE(INTEL, 0x467f), +- .driver_data = VMD_FEATS_CLIENT,}, ++ .driver_data = VMD_FEATS_CLIENT | VMD_FEAT_BIOS_PM_QUIRK,}, + {PCI_VDEVICE(INTEL, 0x4c3d), +- .driver_data = VMD_FEATS_CLIENT,}, ++ .driver_data = VMD_FEATS_CLIENT | VMD_FEAT_BIOS_PM_QUIRK,}, + {PCI_VDEVICE(INTEL, 0xa77f), +- .driver_data = VMD_FEATS_CLIENT,}, ++ .driver_data = VMD_FEATS_CLIENT | VMD_FEAT_BIOS_PM_QUIRK,}, + {PCI_VDEVICE(INTEL, 0x7d0b), +- .driver_data = VMD_FEATS_CLIENT,}, ++ .driver_data = VMD_FEATS_CLIENT | VMD_FEAT_BIOS_PM_QUIRK,}, + {PCI_VDEVICE(INTEL, 0xad0b), +- .driver_data = VMD_FEATS_CLIENT,}, ++ .driver_data = VMD_FEATS_CLIENT | VMD_FEAT_BIOS_PM_QUIRK,}, + {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_VMD_9A0B), +- .driver_data = VMD_FEATS_CLIENT,}, ++ .driver_data = VMD_FEATS_CLIENT | VMD_FEAT_BIOS_PM_QUIRK,}, + {0,} + }; + MODULE_DEVICE_TABLE(pci, vmd_ids); +-- +2.25.1 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 9BE9DC43219 + for <linux-pci@archiver.kernel.org>; Wed, 23 Nov 2022 10:43:16 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S236342AbiKWKnN (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 23 Nov 2022 05:43:13 -0500 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44260 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S237953AbiKWKmY (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 23 Nov 2022 05:42:24 -0500 +Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0F3D769FC; + Wed, 23 Nov 2022 02:27:25 -0800 (PST) +Received: by mail-pj1-f53.google.com with SMTP id o5-20020a17090a678500b00218cd5a21c9so1425739pjj.4; + Wed, 23 Nov 2022 02:27:25 -0800 (PST) +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; + h=content-transfer-encoding:in-reply-to:from:references:cc:to + :content-language:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=pwpkG9G3xkjOyzikzQ4T/gV3SMpUqELfzhIlK43yLpY=; + b=jQXLGvDVVqf0LTqxfMq535ZmBr0TkT6RB8p0K8w8T4X78ujUSLrRE1BiKXSaqWNkmw + cAkayP69927XFP5BW+z1irjuWY5mWxL4XQ507eTgf2AzwJhLDBEP2gNyowTAh+MWX5YJ + DvlEpF45NCRkz+8Gm7+Cz4tyS2l9/XAiVpA7UMj0ODEclCcxmeXJwkN1+Z/oqKyAeSbw + 3+W9WGzmfnnF16NWn5dQpa3a8WYifXYRCN4bydwZ326GLbvuH8Zdo11ZhikVrjDkZ9vA + UHat2k1hFjfe0oXg7Vvg1dokDaesqRyGFwEHZSuiPBVZN3X5ZtEvPC9ueBWj3baE/vNn + vDVg== +X-Gm-Message-State: ANoB5pmNpoOo2LNpR3OgzqqEeSYg/jELrMBlhcX2HhIdcA9xj7wx9aA2 + v2LitFYUz66ji4yIFNDP7sk= +X-Google-Smtp-Source: AA0mqf79gqmDL9stZaRGjrZHLamllSmaeTB+6NNa9TcOtJrVW/NC2LzyXTItQ7A2l8c6qcAq/OLfbA== +X-Received: by 2002:a17:90b:484:b0:218:9d3d:71f4 with SMTP id bh4-20020a17090b048400b002189d3d71f4mr19624100pjb.148.1669199244920; + Wed, 23 Nov 2022 02:27:24 -0800 (PST) +Received: from [192.168.0.247] (61-227-110-150.dynamic-ip.hinet.net. [61.227.110.150]) + by smtp.gmail.com with ESMTPSA id i8-20020a170902c94800b00172fad607b3sm13969212pla.207.2022.11.23.02.27.20 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Wed, 23 Nov 2022 02:27:24 -0800 (PST) +Message-ID: <5c766840-e092-45ea-0664-7bbdb78b933a@canonical.com> +Date: Wed, 23 Nov 2022 18:27:18 +0800 +MIME-Version: 1.0 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 + Thunderbird/102.5.0 +Subject: Re: [PATCH V8 0/4] PCI: vmd: Enable PCIe ASPM and LTR on select + hardware +Content-Language: en-US +To: "David E. Box" <david.e.box@linux.intel.com> +Cc: michael.a.bottini@intel.com, linux-pci@vger.kernel.org, + linux-kernel@vger.kernel.org, me@adhityamohan.in, + rafael@kernel.org, hch@infradead.org, robh@kernel.org, + bhelgaas@google.com, kw@linux.com, lorenzo.pieralisi@arm.com, + nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev +References: <20221103021822.308586-1-david.e.box@linux.intel.com> +From: You-Sheng Yang <vicamo.yang@canonical.com> +In-Reply-To: <20221103021822.308586-1-david.e.box@linux.intel.com> +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +Hi David, + +On 11/3/22 10:18, David E. Box wrote: +> This series adds a work around for enabling PCIe ASPM and for setting PCIe +> LTR values on VMD reserved root ports on select platforms. While +> configuration of these capabilities is usually done by BIOS, on these +> platforms these capabilities will not be configured because the ports are +> not visible to BIOS. This was part of an initial design that expected the +> driver to completely handle the ports, including power management. However +> on Linux those ports are still managed by the PCIe core, which has the +> expectation that they adhere to device standards including BIOS +> configuration, leading to this problem. +> +> The target platforms are Tiger Lake, Alder Lake, and Raptor Lake though the +> latter has already implemented support for configuring the LTR values. +> Meteor Lake is expected add BIOS ASPM support, eliminating the future need +> for this work around. + + +It appears to me that this patch series works only on Tiger Lake. We +have tried to revert our current work-arounds in Ubuntu kernels +generic-5.15/oem-5.17/oem-6.0/unstable-6.1 and apply this series, the +prebuilt kernels can be found in: + + https://launchpad.net/~vicamo/+archive/ubuntu/ppa-1996620 + +However, only TGL can still enter PC10 as before. + + +ADL-M, RPL platforms will stay in PC3 with vmd LTR set, but ASPM +disabled. i915 RC6 blocked, too: + +$ sudo cat /sys/kernel/debug/dri/ + +0/i915_dmc_info +... +DC3CO count: 0 +DC3 -> DC5 count: 100 +DC5 -> DC6 count: 0 + + +> Note, the driver programs the LTRs because BIOS would also normally do this +> for devices that do not set them by default. Without this, SoC power +> management would be blocked on those platform. This SoC specific value is +> the maximum latency required to allow the SoC to enter the deepest power +> state. +> +> This patch addresses the following open bugzillas on VMD enabled laptops +> that cannot enter low power states. +> +> Link: https://bugzilla.kernel.org/show_bug.cgi?id=212355 +> Link: https://bugzilla.kernel.org/show_bug.cgi?id=215063 +> Link: https://bugzilla.kernel.org/show_bug.cgi?id=213717 +> +> David E. Box (3): +> PCI: vmd: Use PCI_VDEVICE in device list +> PCI: vmd: Create feature grouping for client products +> PCI: vmd: Add quirk to configure PCIe ASPM and LTR +> +> Michael Bottini (1): +> PCI/ASPM: Add pci_enable_link_state() +> +> drivers/pci/controller/vmd.c | 96 ++++++++++++++++++++++++++---------- +> drivers/pci/pcie/aspm.c | 54 ++++++++++++++++++++ +> include/linux/pci.h | 7 +++ +> 3 files changed, 131 insertions(+), 26 deletions(-) +> +> +> base-commit: 247f34f7b80357943234f93f247a1ae6b6c3a740 + + +Regards, +You-Sheng Yang + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 6B305C4332F + for <linux-pci@archiver.kernel.org>; Wed, 23 Nov 2022 16:10:05 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S238934AbiKWQKD (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 23 Nov 2022 11:10:03 -0500 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37158 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S238863AbiKWQKA (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 23 Nov 2022 11:10:00 -0500 +Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75D25C76BB; + Wed, 23 Nov 2022 08:09:56 -0800 (PST) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; + d=intel.com; i=@intel.com; q=dns/txt; s=Intel; + t=1669219796; x=1700755796; + h=message-id:subject:from:reply-to:to:cc:date:in-reply-to: + references:content-transfer-encoding:mime-version; + bh=41Amlkh3nNXXy8dAcUXdlKhcq7idpet7xOPClTf5RII=; + b=ioLNdzHN/4vRJQKS4hup4Bg24QU8kYQktqJU0/6SW3Y036oCQFdX/bS2 + OV6UHWmdGkS5jwdz+8Avou8tpNLdcs6uqaMFo2eM58+meR9kDDy5pBx6k + 5VxsFkNA+Qpjl70pJaMXqp/bK3oehRmeS5Y6JOUCr20yqF6UP1HDv6quc + ZSviqMMlMyDW7SIZU2JmboOjAZBUIWR6z8vwVacpSs0+vMDUPWZSo5+NM + rB5mc00bAq2vtFk2JINllWS/ant/9lPeAoAEbZDXyMStqDj67O453j0es + jKhxMgnwYtDUD599Kz36cWZoCOarzMTeNUAVcwpv1q2G6NZH3bbB8awqy + Q==; +X-IronPort-AV: E=McAfee;i="6500,9779,10540"; a="311729547" +X-IronPort-AV: E=Sophos;i="5.96,187,1665471600"; + d="scan'208";a="311729547" +Received: from fmsmga001.fm.intel.com ([10.253.24.23]) + by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2022 08:09:49 -0800 +X-ExtLoop1: 1 +X-IronPort-AV: E=McAfee;i="6500,9779,10540"; a="784293582" +X-IronPort-AV: E=Sophos;i="5.96,187,1665471600"; + d="scan'208";a="784293582" +Received: from linux.intel.com ([10.54.29.200]) + by fmsmga001.fm.intel.com with ESMTP; 23 Nov 2022 08:09:48 -0800 +Received: from brpivitt-mobl1.amr.corp.intel.com (unknown [10.252.128.124]) + by linux.intel.com (Postfix) with ESMTP id 61E4E580AFF; + Wed, 23 Nov 2022 08:09:48 -0800 (PST) +Message-ID: <17b05a72d2db1074cef9d5e9f85b347850f171d5.camel@linux.intel.com> +Subject: Re: [PATCH V8 0/4] PCI: vmd: Enable PCIe ASPM and LTR on select + hardware +From: "David E. Box" <david.e.box@linux.intel.com> +Reply-To: david.e.box@linux.intel.com +To: You-Sheng Yang <vicamo.yang@canonical.com> +Cc: michael.a.bottini@intel.com, linux-pci@vger.kernel.org, + linux-kernel@vger.kernel.org, me@adhityamohan.in, + rafael@kernel.org, hch@infradead.org, robh@kernel.org, + bhelgaas@google.com, kw@linux.com, lorenzo.pieralisi@arm.com, + nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev +Date: Wed, 23 Nov 2022 08:09:48 -0800 +In-Reply-To: <5c766840-e092-45ea-0664-7bbdb78b933a@canonical.com> +References: <20221103021822.308586-1-david.e.box@linux.intel.com> + <5c766840-e092-45ea-0664-7bbdb78b933a@canonical.com> +Organization: David E. Box +Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable +User-Agent: Evolution 3.44.4-0ubuntu1 +MIME-Version: 1.0 +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +Hi You-Sheng, + +On Wed, 2022-11-23 at 18:27 +0800, You-Sheng Yang wrote: +> Hi David, +>=20 +> On 11/3/22 10:18, David E. Box wrote: +> > This series adds a work around for enabling PCIe ASPM and for setting P= +CIe +> > LTR values on VMD reserved root ports on select platforms. While +> > configuration of these capabilities is usually done by BIOS, on these +> > platforms these capabilities will not be configured because the ports a= +re +> > not visible to BIOS. This was part of an initial design that expected t= +he +> > driver to completely handle the ports, including power management. Howe= +ver +> > on Linux those ports are still managed by the PCIe core, which has the +> > expectation that they adhere to device standards including BIOS +> > configuration, leading to this problem. +> >=20 +> > The target platforms are Tiger Lake, Alder Lake, and Raptor Lake though= + the +> > latter has already implemented support for configuring the LTR values. +> > Meteor Lake is expected add BIOS ASPM support, eliminating the future n= +eed +> > for this work around. +>=20 +>=20 +> It appears to me that this patch series works only on Tiger Lake. We=20 +> have tried to revert our current work-arounds in Ubuntu kernels=20 +> generic-5.15/oem-5.17/oem-6.0/unstable-6.1 and apply this series, the=20 +> prebuilt kernels can be found in: +>=20 +> =C2=A0=C2=A0 https://launchpad.net/~vicamo/+archive/ubuntu/ppa-1996620 +>=20 +> However, only TGL can still enter PC10 as before. +>=20 +>=20 +> ADL-M, RPL platforms will stay in PC3 with vmd LTR set, but ASPM=20 +> disabled. + +For the patch to work BIOS must allow the OS to control ASPM. If this is no= +t the +case then you will see the message "ACPI FADT declares the system doesn't +support PCIe ASPM, so disable it". Please check for this on the systems tha= +t +don't work. If so the only option is a BIOS change to enable it. + +David + +> i915 RC6 blocked, too: +>=20 +> $ sudo cat /sys/kernel/debug/dri/ +>=20 +> 0/i915_dmc_info +> ... +> DC3CO count: 0 +> DC3 -> DC5 count: 100 +> DC5 -> DC6 count: 0 +>=20 +>=20 +> > Note, the driver programs the LTRs because BIOS would also normally do = +this +> > for devices that do not set them by default. Without this, SoC power +> > management would be blocked on those platform. This SoC specific value = +is +> > the maximum latency required to allow the SoC to enter the deepest powe= +r +> > state. +> >=20 +> > This patch addresses the following open bugzillas on VMD enabled laptop= +s +> > that cannot enter low power states. +> >=20 +> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D212355 +> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D215063 +> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D213717 +> >=20 +> > David E. Box (3): +> > =C2=A0=C2=A0 PCI: vmd: Use PCI_VDEVICE in device list +> > =C2=A0=C2=A0 PCI: vmd: Create feature grouping for client products +> > =C2=A0=C2=A0 PCI: vmd: Add quirk to configure PCIe ASPM and LTR +> >=20 +> > Michael Bottini (1): +> > =C2=A0=C2=A0 PCI/ASPM: Add pci_enable_link_state() +> >=20 +> > =C2=A0 drivers/pci/controller/vmd.c | 96 ++++++++++++++++++++++++++----= +------ +> > =C2=A0 drivers/pci/pcie/aspm.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 54 +++++= ++++++++++++++++ +> > =C2=A0 include/linux/pci.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= +=A0=C2=A0 |=C2=A0 7 +++ +> > =C2=A0 3 files changed, 131 insertions(+), 26 deletions(-) +> >=20 +> >=20 +> > base-commit: 247f34f7b80357943234f93f247a1ae6b6c3a740 +>=20 +>=20 +> Regards, +> You-Sheng Yang +>=20 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id ABA40C433FE + for <linux-pci@archiver.kernel.org>; Thu, 24 Nov 2022 16:40:17 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229477AbiKXQkQ (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Thu, 24 Nov 2022 11:40:16 -0500 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38952 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229379AbiKXQkO (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Thu, 24 Nov 2022 11:40:14 -0500 +Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A39410CE82 + for <linux-pci@vger.kernel.org>; Thu, 24 Nov 2022 08:40:13 -0800 (PST) +Received: from mail-il1-f200.google.com (mail-il1-f200.google.com [209.85.166.200]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) + (No client certificate requested) + by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 192763F46A + for <linux-pci@vger.kernel.org>; Thu, 24 Nov 2022 16:40:11 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; + s=20210705; t=1669308011; + bh=rFBx8o9ACr2aE3UXlk16oilIXDTZ3TK8L+Ksy/y90RU=; + h=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject: + To:Cc:Content-Type; + b=b2hIghAdfhN+u1QlWRhqvH49RiP3lpueoPPYUViLjmuWE0Al+czHFB3IQnWqgH1e4 + 3Kuj+RqM3hAxbjlThDt2atBTSGcqINNsRKiAaRXT7Et9kUbUABoTWyHX9tgxqqyJ4h + zLF/C6XbBalqzA3L42ogy5LI20gK/qjDliYBeLrWUTGSz8NRGZQaejSlnpEX2r0YJf + 3uR9Rl+Erbvjs9Gh9NvVEhDHdTtQ8Cp5HQzMgGK7j80ySnkOTt+ww+3fMCJbrpgjIM + abtRqx8Q2fglJuPIeKb0oG20qd0fizYjUtSSJu17I81ShF+yWduw1O4a/R+5x1dWQW + tSVXNiAB8JUmQ== +Received: by mail-il1-f200.google.com with SMTP id k3-20020a92c243000000b0030201475a6bso1433616ilo.9 + for <linux-pci@vger.kernel.org>; Thu, 24 Nov 2022 08:40:11 -0800 (PST) +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; + h=cc:to:subject:message-id:date:from:in-reply-to:references + :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id + :reply-to; + bh=rFBx8o9ACr2aE3UXlk16oilIXDTZ3TK8L+Ksy/y90RU=; + b=5oO1UTG5GWs75QvhfQkgfvfcUjBX8FroWSSYuf6XiLkeBDzXmnkddKhGbLtAZgEKU2 + WDoBxaC831l2zBywqZV3hSEHn9rWwzYYplHdfZ4ruPBzLpE35N1ypD0Y2rarZWHmW/9r + g/okR9U9zTo/U6pyO6ZRjnLIhe8jXO5axTNcXkdzjC9806gGXh8h9EJd0hjlJaBOqktQ + 7ZZVlm6lpQNmlwnvCm7n4mRwDiE9HOj9UdWJdunbxDOantGvVz23KY4pkEV7aLBrbnlJ + F+NwHlGvubESgbJuNLnuYtcSmLOld7xNO8SuyVFQHLEFQ9faNHdUaIlF8+IqqImhHk/B + gHfw== +X-Gm-Message-State: ANoB5pkWthOW13SXoGsLHkDt4M0NKp6SAgiC2OROjsVUmsuLZmxU/K6R + QCRvV6XJmvtST+Jr6diNvUhD40VH216VUvStymK9NpQA2A1hlf+Qrccxaqy71zDldaGgK/GrTMz + o+LViVPjFvV036Dt83rks/0i2Gn21kVsURFitSWGSySt9ZgaNynGHVQ== +X-Received: by 2002:a6b:5904:0:b0:6af:ed54:1c81 with SMTP id n4-20020a6b5904000000b006afed541c81mr8426730iob.106.1669308009796; + Thu, 24 Nov 2022 08:40:09 -0800 (PST) +X-Google-Smtp-Source: AA0mqf6aovE2/ZA6S/DsuJGYDElLduwKMbC8q/hMU3FEu6WeD0yAmkdGpz22Y9xg5ahZfk76UnYd5HasZD8Lb1aFD9U= +X-Received: by 2002:a6b:5904:0:b0:6af:ed54:1c81 with SMTP id + n4-20020a6b5904000000b006afed541c81mr8426709iob.106.1669308009474; Thu, 24 + Nov 2022 08:40:09 -0800 (PST) +MIME-Version: 1.0 +References: <20221103021822.308586-1-david.e.box@linux.intel.com> + <5c766840-e092-45ea-0664-7bbdb78b933a@canonical.com> <17b05a72d2db1074cef9d5e9f85b347850f171d5.camel@linux.intel.com> +In-Reply-To: <17b05a72d2db1074cef9d5e9f85b347850f171d5.camel@linux.intel.com> +From: You-Sheng Yang <vicamo.yang@canonical.com> +Date: Fri, 25 Nov 2022 00:39:58 +0800 +Message-ID: <CA+rHWA+7KudasAMnO=dCUSQWb76Eu=DALA=1eLd_jjLw0dEMkA@mail.gmail.com> +Subject: Re: [PATCH V8 0/4] PCI: vmd: Enable PCIe ASPM and LTR on select hardware +To: david.e.box@linux.intel.com +Cc: michael.a.bottini@intel.com, linux-pci@vger.kernel.org, + linux-kernel@vger.kernel.org, me@adhityamohan.in, + rafael@kernel.org, hch@infradead.org, robh@kernel.org, + bhelgaas@google.com, kw@linux.com, lorenzo.pieralisi@arm.com, + nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev +Content-Type: text/plain; charset="UTF-8" +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +On Thu, Nov 24, 2022 at 12:09 AM David E. Box +<david.e.box@linux.intel.com> wrote: +> +> Hi You-Sheng, +> +> On Wed, 2022-11-23 at 18:27 +0800, You-Sheng Yang wrote: +> > Hi David, +> > +> > On 11/3/22 10:18, David E. Box wrote: +> > > This series adds a work around for enabling PCIe ASPM and for setting PCIe +> > > LTR values on VMD reserved root ports on select platforms. While +> > > configuration of these capabilities is usually done by BIOS, on these +> > > platforms these capabilities will not be configured because the ports are +> > > not visible to BIOS. This was part of an initial design that expected the +> > > driver to completely handle the ports, including power management. However +> > > on Linux those ports are still managed by the PCIe core, which has the +> > > expectation that they adhere to device standards including BIOS +> > > configuration, leading to this problem. +> > > +> > > The target platforms are Tiger Lake, Alder Lake, and Raptor Lake though the +> > > latter has already implemented support for configuring the LTR values. +> > > Meteor Lake is expected add BIOS ASPM support, eliminating the future need +> > > for this work around. +> > +> > +> > It appears to me that this patch series works only on Tiger Lake. We +> > have tried to revert our current work-arounds in Ubuntu kernels +> > generic-5.15/oem-5.17/oem-6.0/unstable-6.1 and apply this series, the +> > prebuilt kernels can be found in: +> > +> > https://launchpad.net/~vicamo/+archive/ubuntu/ppa-1996620 +> > +> > However, only TGL can still enter PC10 as before. +> > +> > +> > ADL-M, RPL platforms will stay in PC3 with vmd LTR set, but ASPM +> > disabled. +> +> For the patch to work BIOS must allow the OS to control ASPM. If this is not the +> case then you will see the message "ACPI FADT declares the system doesn't +> support PCIe ASPM, so disable it". Please check for this on the systems that +> don't work. If so the only option is a BIOS change to enable it. + +Thank you. It's exactly what you said. The ADL-M/RPL platforms I have +do not support OS PCIe ASPM. + +> David +> +> > i915 RC6 blocked, too: +> > +> > $ sudo cat /sys/kernel/debug/dri/ +> > +> > 0/i915_dmc_info +> > ... +> > DC3CO count: 0 +> > DC3 -> DC5 count: 100 +> > DC5 -> DC6 count: 0 +> > +> > +> > > Note, the driver programs the LTRs because BIOS would also normally do this +> > > for devices that do not set them by default. Without this, SoC power +> > > management would be blocked on those platform. This SoC specific value is +> > > the maximum latency required to allow the SoC to enter the deepest power +> > > state. +> > > +> > > This patch addresses the following open bugzillas on VMD enabled laptops +> > > that cannot enter low power states. +> > > +> > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=212355 +> > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=215063 +> > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=213717 +> > > +> > > David E. Box (3): +> > > PCI: vmd: Use PCI_VDEVICE in device list +> > > PCI: vmd: Create feature grouping for client products +> > > PCI: vmd: Add quirk to configure PCIe ASPM and LTR +> > > +> > > Michael Bottini (1): +> > > PCI/ASPM: Add pci_enable_link_state() +> > > +> > > drivers/pci/controller/vmd.c | 96 ++++++++++++++++++++++++++---------- +> > > drivers/pci/pcie/aspm.c | 54 ++++++++++++++++++++ +> > > include/linux/pci.h | 7 +++ +> > > 3 files changed, 131 insertions(+), 26 deletions(-) +> > > +> > > +> > > base-commit: 247f34f7b80357943234f93f247a1ae6b6c3a740 +> > +> > +> > Regards, +> > You-Sheng Yang +> > +> + + +-- +Regards, +You-Sheng Yang + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-pci-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 8481CC352A1 + for <linux-pci@archiver.kernel.org>; Wed, 7 Dec 2022 09:05:47 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229777AbiLGJFq (ORCPT <rfc822;linux-pci@archiver.kernel.org>); + Wed, 7 Dec 2022 04:05:46 -0500 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54240 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229515AbiLGJFp (ORCPT + <rfc822;linux-pci@vger.kernel.org>); Wed, 7 Dec 2022 04:05:45 -0500 +Received: from wout3-smtp.messagingengine.com (wout3-smtp.messagingengine.com [64.147.123.19]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DB6526AC2; + Wed, 7 Dec 2022 01:05:44 -0800 (PST) +Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) + by mailout.west.internal (Postfix) with ESMTP id B2C0F32009E1; + Wed, 7 Dec 2022 04:05:42 -0500 (EST) +Received: from mailfrontend1 ([10.202.2.162]) + by compute3.internal (MEProxy); Wed, 07 Dec 2022 04:05:43 -0500 +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ljones.dev; h=cc + :cc:content-transfer-encoding:content-type:date:date:from:from + :in-reply-to:in-reply-to:message-id:mime-version:references + :reply-to:sender:subject:subject:to:to; s=fm3; t=1670403942; x= + 1670490342; bh=JFoXxMClww2l4RygoD+XW2GsjAAbe5uznYYD7nEj5+A=; b=A + m+3Xd9pOm+9ctEko/ry4U6uTcBmcKTxoSXhrOYjFkNzs/UPFQ3eYMIW6MPgw2H6r + W71NHDCfNlVOyxGK6QEtxyF8rdWdUjylzGuvSzy+iI1cTIyDvUZOhVgBzXAR4pdP + zDSd0d9YPMphKkyku5QEjEG38WA26pdIxpRsHBm55ScFgaM4uCv5/xQ+rjaYprZL + A+fvdT8D23+KOupjIeylZk5InsaqGNrVUifuJpVIM5mUkn0HoOyyvrRmtFXSq5Yl + X1CHYaDxQcHEXMHnut+AsYWLGLPjewjytElsnMWmy1+yzdHdszmkfkCF+BE8Ba8Z + d1Ny7AxdMcZGwGVoyRnaA== +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= + messagingengine.com; h=cc:cc:content-transfer-encoding + :content-type:date:date:feedback-id:feedback-id:from:from + :in-reply-to:in-reply-to:message-id:mime-version:references + :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy + :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1670403942; x= + 1670490342; bh=JFoXxMClww2l4RygoD+XW2GsjAAbe5uznYYD7nEj5+A=; b=o + u/WWNWj8Jc92d/UtZbf4Nr+ZIPhRQ0768ZQ/Sf+INAMi26NBhtJLUu9aNRQpIK9I + Dam5k6gOJvt4nfYzC9GRZMJosLhHrmL/Pm/8dRS05pKgo6R9gGptihDfIDu9dNYb + HJvCMcVklYC9LtlK36zKlfetDEM/mF5y2GF8AGbWq1D7lUzoNiZJRbGbSlQDH9p5 + ACR3p5CiE0mnOoBA0RkzabymijwuKJmhCobq8TlPRt9je7WUgCesGxbKkEguZVG+ + l1xHMxvwWGFnyNSwJOpnHQtIhs6OMDxTKMQ74pAabh6fLRKqrS/w9WScvW5DyFCy + 4gxPK3Ki3pdCGhXaZWGPw== +X-ME-Sender: <xms:ZVeQY6JcmBl9r8UaSgPQlsL6kBpyH4upmsXGoJ4JZ0S4Apf8Uzw2tQ> + <xme:ZVeQYyIZZ_J4e1TTTEmsSwTW5tyJbARUJ4hEG-TJP_Lki94M9bKzSpCOlPByJH2t7 + pMAV4LFMsEEUlVV95U> +X-ME-Received: <xmr:ZVeQY6uXMnU1qz7wIIZC_5ZP-dESYU4i7Aar3YknT1ZO2v4AkA5mOobw-mndir-YpJ-2wA> +X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrudejgdduvdelucetufdoteggodetrfdotf + fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen + uceurghilhhouhhtmecufedttdenucenucfjughrpefkuffhvfevffgjfhgtgfgfggesth + hqredttderjeenucfhrhhomhepnfhukhgvucflohhnvghsuceolhhukhgvsehljhhonhgv + shdruggvvheqnecuggftrfgrthhtvghrnhepteegteefhefhteegleejudfffffghfekle + eijeeugfffteeiudefvdetteeuuedvnecuffhomhgrihhnpehkvghrnhgvlhdrohhrghen + ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehluhhkvg + eslhhjohhnvghsrdguvghv +X-ME-Proxy: <xmx:ZVeQY_ahVbtfiYjhg_k2eYSq-uPXq1xkiFLHac3vmlI3yXJqdoKeog> + <xmx:ZVeQYxa-BJIz-lhlN77iSktQ8_NETM1TjQY8KXMwVRQe91NiGV1Q5w> + <xmx:ZVeQY7BP-z-UuGNNFk8YZcB2ihklL1TIm-yrdTrk8nj3ewRVuCLcJA> + <xmx:ZleQY-QBDw9ZgrfCGBIIbxE3z6H9QizXgV3ZnQTGdJ6RWbka1UWQVQ> +Feedback-ID: i5ec1447f:Fastmail +Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, + 7 Dec 2022 04:05:35 -0500 (EST) +Message-ID: <8b8c7ae512291532ea227b8a1c3f87c460e11e2f.camel@ljones.dev> +Subject: Re: [PATCH V8 0/4] PCI: vmd: Enable PCIe ASPM and LTR on select + hardware +From: Luke Jones <luke@ljones.dev> +To: "David E. Box" <david.e.box@linux.intel.com>, + nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, + lorenzo.pieralisi@arm.com, hch@infradead.org, kw@linux.com, + robh@kernel.org, bhelgaas@google.com, michael.a.bottini@intel.com, + rafael@kernel.org, me@adhityamohan.in +Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org +Date: Wed, 07 Dec 2022 22:05:28 +1300 +In-Reply-To: <20221103021822.308586-1-david.e.box@linux.intel.com> +References: <20221103021822.308586-1-david.e.box@linux.intel.com> +Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable +User-Agent: Evolution 3.46.2 (by Flathub.org) +MIME-Version: 1.0 +Precedence: bulk +List-ID: <linux-pci.vger.kernel.org> +X-Mailing-List: linux-pci@vger.kernel.org + +On Wed, 2022-11-02 at 19:18 -0700, David E. Box wrote: +> This series adds a work around for enabling PCIe ASPM and for setting +> PCIe +> LTR values on VMD reserved root ports on select platforms. While +> configuration of these capabilities is usually done by BIOS, on these +> platforms these capabilities will not be configured because the ports +> are +> not visible to BIOS. This was part of an initial design that expected +> the +> driver to completely handle the ports, including power management. +> However +> on Linux those ports are still managed by the PCIe core, which has +> the +> expectation that they adhere to device standards including BIOS +> configuration, leading to this problem. +>=20 +> The target platforms are Tiger Lake, Alder Lake, and Raptor Lake +> though the +> latter has already implemented support for configuring the LTR +> values. +> Meteor Lake is expected add BIOS ASPM support, eliminating the future +> need +> for this work around. +>=20 +> Note, the driver programs the LTRs because BIOS would also normally +> do this +> for devices that do not set them by default. Without this, SoC power +> management would be blocked on those platform. This SoC specific +> value is +> the maximum latency required to allow the SoC to enter the deepest +> power +> state. +>=20 +> This patch addresses the following open bugzillas on VMD enabled +> laptops +> that cannot enter low power states. +>=20 +> Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D212355 +> Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D215063 +> Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D213717 +>=20 +> David E. Box (3): +> =C2=A0 PCI: vmd: Use PCI_VDEVICE in device list +> =C2=A0 PCI: vmd: Create feature grouping for client products +> =C2=A0 PCI: vmd: Add quirk to configure PCIe ASPM and LTR +>=20 +> Michael Bottini (1): +> =C2=A0 PCI/ASPM: Add pci_enable_link_state() +>=20 +> =C2=A0drivers/pci/controller/vmd.c | 96 ++++++++++++++++++++++++++-------= +- +> -- +> =C2=A0drivers/pci/pcie/aspm.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | 54 ++++++++= +++++++++++++ +> =C2=A0include/linux/pci.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= +=C2=A0 |=C2=A0 7 +++ +> =C2=A03 files changed, 131 insertions(+), 26 deletions(-) +>=20 +>=20 +> base-commit: 247f34f7b80357943234f93f247a1ae6b6c3a740 + +I'd like to confirm that this patch series solves the VMD power issues +present on the ASUS ROG M16 (GU603) laptop range (PCI dev ID =3D 467f). + +The difference is quite drastic. + + diff --git a/0027-mt76_-mt7921_-Disable-powersave-features-by-default.patch b/0027-mt76_-mt7921_-Disable-powersave-features-by-default.patch new file mode 100644 index 000000000000..099b4a4c686c --- /dev/null +++ b/0027-mt76_-mt7921_-Disable-powersave-features-by-default.patch @@ -0,0 +1,43 @@ +From ca89780690f7492c2d357e0ed2213a1d027341ae Mon Sep 17 00:00:00 2001 +From: Sultan Alsawaf <sultan@kerneltoast.com> +Date: Sun, 29 May 2022 01:32:19 -0700 +Subject: [PATCH] mt76: mt7921: Disable powersave features by default + +This brings WiFi latency down considerably and makes latency consistent by +disabling runtime PM and typical powersave features by default. The actual +power consumption difference is inconsequential on desktops and laptops, +while the performance difference is monumental. Latencies of 20+ ms are no +longer observed after this change, and the connection is much more stable. + +Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com> +--- + drivers/net/wireless/mediatek/mt76/mt7921/init.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c +index 91fc41922d95..cfa0bb51004d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c +@@ -67,7 +67,8 @@ + + wiphy->iface_combinations = if_comb; + wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP | +- WIPHY_FLAG_4ADDR_STATION); ++ WIPHY_FLAG_4ADDR_STATION | ++ WIPHY_FLAG_PS_ON_BY_DEFAULT); + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP); + wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); +@@ -266,12 +267,6 @@ int mt7921_register_device(struct mt7921_dev *dev) + dev->pm.idle_timeout = MT7921_PM_TIMEOUT; + dev->pm.stats.last_wake_event = jiffies; + dev->pm.stats.last_doze_event = jiffies; +- if (!mt76_is_usb(&dev->mt76)) { +- dev->pm.enable_user = true; +- dev->pm.enable = true; +- dev->pm.ds_enable_user = true; +- dev->pm.ds_enable = true; +- } + + if (!mt76_is_mmio(&dev->mt76)) + hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE; diff --git a/0028-patch01_gu604_alc285_fixes.patch b/0028-patch01_gu604_alc285_fixes.patch new file mode 100644 index 000000000000..f0443ffc2f02 --- /dev/null +++ b/0028-patch01_gu604_alc285_fixes.patch @@ -0,0 +1,42 @@ +--- a/sound/pci/hda/patch_realtek.c 2023-04-20 20:40:17.786527496 +0300 ++++ b/sound/pci/hda/patch_realtek.c 2023-04-20 20:25:02.524458831 +0300 +@@ -7061,6 +7061,8 @@ + ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC295_FIXUP_DISABLE_DAC3, + ALC285_FIXUP_SPEAKER2_TO_DAC1, ++ ALC285_FIXUP_ASUS_HEADSET_MIC, ++ ALC285_FIXUP_ASUS_SPEAKER2_TO_DAC1, + ALC280_FIXUP_HP_HEADSET_MIC, + ALC221_FIXUP_HP_FRONT_MIC, + ALC292_FIXUP_TPT460, +@@ -8008,6 +8010,22 @@ + .chained = true, + .chain_id = ALC269_FIXUP_THINKPAD_ACPI + }, ++ [ALC285_FIXUP_ASUS_HEADSET_MIC] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x19, 0x03a11050 }, ++ { 0x1b, 0x03a11c30 }, ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC245_FIXUP_CS35L41_SPI_2 ++ }, ++ [ALC285_FIXUP_ASUS_SPEAKER2_TO_DAC1] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc285_fixup_speaker2_to_dac1, ++ .chained = true, ++ .chain_id = ALC285_FIXUP_ASUS_HEADSET_MIC ++ }, + [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { +@@ -9512,6 +9530,7 @@ + SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), ++ SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_SPEAKER2_TO_DAC1), + SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), + SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), + SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), diff --git a/0029-HID-asus-Add-support-for-ASUS-ROG-Z13-keyboard.patch b/0029-HID-asus-Add-support-for-ASUS-ROG-Z13-keyboard.patch new file mode 100644 index 000000000000..8c62dd0bb5bd --- /dev/null +++ b/0029-HID-asus-Add-support-for-ASUS-ROG-Z13-keyboard.patch @@ -0,0 +1,42 @@ +From 797aa7ce7169594294cb78b358100f47ad2eb42e Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Wed, 19 Apr 2023 11:58:48 +1200 +Subject: [PATCH 1/2] HID: asus: Add support for ASUS ROG Z13 keyboard + +Add the ID of the Z13 keyboard and associated quirk. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/hid/hid-asus.c | 3 +++ + drivers/hid/hid-ids.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index d1094bb1aa42..ac93f987d822 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1267,6 +1267,9 @@ static const struct hid_device_id asus_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, ++ USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3), ++ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), + QUIRK_ROG_CLAYMORE_II_KEYBOARD }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index c2e9b6d1fd7d..a2d78d0cf425 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -207,6 +207,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 0x1822 + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866 + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 ++#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x18c6 + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 + +-- +2.40.0 + diff --git a/0030-HID-asus-Add-support-for-ASUS-ROG-Z13-ACRNM-keyboard.patch b/0030-HID-asus-Add-support-for-ASUS-ROG-Z13-ACRNM-keyboard.patch new file mode 100644 index 000000000000..fd08fdf49f79 --- /dev/null +++ b/0030-HID-asus-Add-support-for-ASUS-ROG-Z13-ACRNM-keyboard.patch @@ -0,0 +1,43 @@ +From 2f6412a2916ae214f4da8e1a3c7e93046ff12a7c Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Mon, 24 Apr 2023 11:16:24 +1200 +Subject: [PATCH 2/2] HID: asus: Add support for ASUS ROG Z13 ACRNM keyboard + +Add support for a second variant of the ROG Z13 keyboard, this one +is a custom one-off part for the ACRNM variant of the Z13. + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/hid/hid-asus.c | 3 +++ + drivers/hid/hid-ids.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index ac93f987d822..13e9bbc925e7 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1270,6 +1270,9 @@ static const struct hid_device_id asus_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, ++ USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD4), ++ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, + USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), + QUIRK_ROG_CLAYMORE_II_KEYBOARD }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index a2d78d0cf425..d1234bc2ec60 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -208,6 +208,7 @@ + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866 + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x18c6 ++#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD4 0x1a30 + #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 + +-- +2.40.0 + diff --git a/0031-HID-asus-Map-0xc7-key-event-to-KEY_KBDILLUMTOGGLE.patch b/0031-HID-asus-Map-0xc7-key-event-to-KEY_KBDILLUMTOGGLE.patch new file mode 100644 index 000000000000..c4ac3bf1a74d --- /dev/null +++ b/0031-HID-asus-Map-0xc7-key-event-to-KEY_KBDILLUMTOGGLE.patch @@ -0,0 +1,28 @@ +From ef51bbab598b014ee66b0794d06a6c105905b81c Mon Sep 17 00:00:00 2001 +From: "Luke D. Jones" <luke@ljones.dev> +Date: Mon, 24 Apr 2023 16:26:33 +1200 +Subject: [PATCH 3/3] HID: asus: Map 0xc7 key event to KEY_KBDILLUMTOGGLE + +Some fo the ROG Z13 series have only a single keyboard brightness +key whcih is expected to toggle the brightness up and cycle back to zero + +Signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + drivers/hid/hid-asus.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 13e9bbc925e7..279b8fe4f227 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -883,6 +883,7 @@ static int asus_input_mapping(struct hid_device *hdev, + case 0xb5: asus_map_key_clear(KEY_CALC); break; + case 0xc4: asus_map_key_clear(KEY_KBDILLUMUP); break; + case 0xc5: asus_map_key_clear(KEY_KBDILLUMDOWN); break; ++ case 0xc7: asus_map_key_clear(KEY_KBDILLUMTOGGLE); break; + + /* ASUS touchpad toggle */ + case 0x6b: asus_map_key_clear(KEY_F21); break; +-- +2.40.0 + @@ -1,8 +1,10 @@ -# Maintainer: Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> +# Maintainer: Gunnar Bretthauer <taijian@posteo.de> +# Contributor: Dragonn <dragonn@op.pl> +# Contributor: Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> pkgbase=linux-g14 -pkgver=5.14.9.arch1 -pkgrel=3 +pkgver=6.2.12.arch1 +pkgrel=2 pkgdesc='Linux' _srctag=v${pkgver%.*}-${pkgver##*.} url="https://gitlab.com/dragonn/linux-g14.git" @@ -16,72 +18,37 @@ makedepends=( ) options=('!strip') _srcname=archlinux-linux -_fedora_kernel_commit_id=e087e6d70c49c685b4d7cc7364496ade3aed3609 + source=( "$_srcname::git+https://github.com/archlinux/linux?signed#tag=$_srctag" config # the main kernel config file "choose-gcc-optimization.sh" - "sys-kernel_arch-sources-g14_files-0004-5.8+--more-uarches-for-kernel.patch"::"https://raw.githubusercontent.com/graysky2/kernel_compiler_patch/a8d200f422f4b2abeaa6cfcfa37136b308e6e33e/more-uarches-for-kernel-5.8%2B.patch" - "sys-kernel_arch-sources-g14_files-0005-lru-multi-generational.patch" - # mainlined - #"sys-kernel_arch-sources-g14_files-0006-fix-tigerlake-pin-mapping.patch" - - "https://gitlab.com/asus-linux/fedora-kernel/-/archive/$_fedora_kernel_commit_id/fedora-kernel-$_fedora_kernel_commit_id.zip" - - # for now let's just pull the 5 asus-linux patches we need directly and skip all of the git filtering - "sys-kernel_arch-sources-g14_files-0039-asus-wmi-Add-panel-overdrive-functionality.patch" - # pull newer version from fedora repo - #"sys-kernel_arch-sources-g14_files-0040-asus-wmi-Add-dgpu-disable-method.patch" - #"sys-kernel_arch-sources-g14_files-0041-asus-wmi-Add-egpu-enable-method.patch" - #"sys-kernel_arch-sources-g14_files-0042-HID-asus-Remove-check-for-same-LED-brightness-on-set.patch" - "sys-kernel_arch-sources-g14_files-0043-ALSA-hda-realtek-Fix-speakers-not-working-on-Asus-Fl.patch" - "sys-kernel_arch-sources-g14_files-0044-claymore.patch" - "sys-kernel_arch-sources-g14_files-0045-v5-asus-wmi-Add-support-for-platform_profile.patch" - "sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch" - "sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch" - "sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch" + "sys-kernel_arch-sources-g14_files-0004-5.17+--more-uarches-for-kernel.patch"::"https://raw.githubusercontent.com/graysky2/kernel_compiler_patch/master/more-uarches-for-kernel-5.17+.patch" - # k10temp support for Zen3 APUs - #"sys-kernel_arch-sources-g14_files-8001-x86-amd_nb-Add-AMD-family-19h-model-50h-PCI-ids.patch" - "sys-kernel_arch-sources-g14_files-8002-hwmon-k10temp-support-Zen3-APUs.patch" + 0001-acpi-proc-idle-skip-dummy-wait.patch - - # mediatek mt7921 bt/wifi patches - - "sys-kernel_arch-sources-g14_files-8011-Bluetooth-btusb-Enable-MSFT-extension-for-Mediatek-Chip-MT7921.patch" - "sys-kernel_arch-sources-g14_files-8012-mt76-mt7915-send-EAPOL-frames-at-lowest-rate.patch" - "sys-kernel_arch-sources-g14_files-8013-mt76-mt7921-robustify-hardware-initialization-flow.patch" - "sys-kernel_arch-sources-g14_files-8014-mt76-mt7921-fix-retrying-release-semaphore-without-end.patch" - "sys-kernel_arch-sources-g14_files-8015-mt76-mt7921-send-EAPOL-frames-at-lowest-rate.patch" - "sys-kernel_arch-sources-g14_files-8016-mt76-mt7921-Add-mt7922-support.patch" - "sys-kernel_arch-sources-g14_files-8017-mt76-mt7921-enable-VO-tx-aggregation.patch" - "sys-kernel_arch-sources-g14_files-8018-mt76-mt7921-fix-dma-hang-in-rmmod.patch" - "sys-kernel_arch-sources-g14_files-8019-mt76-mt7921-fix-firmware-usage-of-RA-info-using-legacy-rates.patch" - "sys-kernel_arch-sources-g14_files-8020-mt76-mt7921-Fix-out-of-order-process-by-invalid-even.patch" - "sys-kernel_arch-sources-g14_files-8021-mt76-mt7921-fix-the-inconsistent-state-between-bind-and-unbind.patch" - "sys-kernel_arch-sources-g14_files-8022-mt76-mt7921-report-HE-MU-radiotap.patch" - "sys-kernel_arch-sources-g14_files-8023-v2-mt76-mt7921-fix-kernel-warning-from-cfg80211_calculate_bitrate.patch" - "sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch" + 0019-HID-amd_sfh-Add-keyguard-for-ASUS-ROG-X13-tablet.patch + 0001-platform-x86-asus-wmi-Add-safety-checks-to-dgpu-egpu.patch + 0001-Revert-perf-x86-intel-Fix-unchecked-MSR-access-error.patch + 0024-V8-0-4-PCI-vmd-Enable-PCIe-ASPM-and-LTR-on-select-hardware.patch - #"sys-kernel_arch-sources-g14_files-8024-mediatek-19-09-2021-squashed.patch" + 0027-mt76_-mt7921_-Disable-powersave-features-by-default.patch - # squashed s0ix enablement through 2021-09-03 - "sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch" - #"sys-kernel_arch-sources-g14_files-9002-amd-pmc-delay-test.patch" - # a small amd_pmc SMU debugging patch per Mario Limonciello @AMD - #"sys-kernel_arch-sources-g14_files-9002-amd-pmc-smu-register-dump-for-diagnostics.patch" - - "sys-kernel_arch-sources-g14_files-9004-HID-asus-Reduce-object-size-by-consolidating-calls.patch" - "sys-kernel_arch-sources-g14_files-9005-acpi-battery-Always-read-fresh-battery-state-on-update.patch" + 0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch + 0001-linux6.0.y-bore1.7.5.patch - "sys-kernel_arch-sources-g14_files-9006-amd-c3-entry.patch" - - "sys-kernel_arch-sources-g14_files-9007-squashed-net-tcp_bbr-bbr2-for-5.14.y.patch" + 0002-mm-add-vma_has_recency.patch + + 0028-patch01_gu604_alc285_fixes.patch - "sys-kernel_arch-sources-g14_files-9008-fix-cpu-hotplug.patch" - "sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch" - "sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch" + 0029-HID-asus-Add-support-for-ASUS-ROG-Z13-keyboard.patch + 0030-HID-asus-Add-support-for-ASUS-ROG-Z13-ACRNM-keyboard.patch + 0031-HID-asus-Map-0xc7-key-event-to-KEY_KBDILLUMTOGGLE.patch + + "sys-kernel_arch-sources-g14_files-0047-asus-nb-wmi-Add-tablet_mode_sw-lid-flip.patch" + "sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch" + "sys-kernel_arch-sources-g14_files-0049-ALSA-hda-realtek-Add-quirk-for-ASUS-M16-GU603H.patch" ) validpgpkeys=( @@ -92,41 +59,25 @@ validpgpkeys=( ) sha256sums=('SKIP' - 'aa50b2ec33ce304f9b99ce80555a17ea18b1005dae147a560587acbdae00546f' - '1ac18cad2578df4a70f9346f7c6fccbb62f042a0ee0594817fdef9f2704904ee' - 'fa6cee9527d8e963d3398085d1862edc509a52e4540baec463edb8a9dd95bee0' - '69ecf5456468935958f2cbf35691c2533a56344005537902b6051b6323ffff1f' - '6806c034b7480245a0b9eec448bd79042ff5ff3f9f5efbf2af78227bc56004a8' - '1ab75535772c63567384eb2ac74753e4d5db2f3317cb265aedf6151b9f18c6c2' - '32bbcde83406810f41c9ed61206a7596eb43707a912ec9d870fd94f160d247c1' - 'e2d312ea95d18e91801d131a2b5d03cf2175d3088cac6f84a19410078a5b6b14' - '4ef12029ea73ca924b6397e1de4911e84d9e77ddaccdab1ef579823d848524e8' - '1e547bddf80d201f77da1d876cd280e4d40b377bbd8ebc218f0ba57cd959ff76' + '70cf3252ff877cb91ca7eba13439ae181e693513b09ff43e83c48d2b0b46d0f8' + '278118011d7a2eeca9971ac97b31bf0c55ab55e99c662ab9ae4717b55819c9a2' + 'dea86a521603414a8c7bf9cf1f41090d5d6f8035ce31407449e25964befb1e50' + '0a7ea482fe20c403788d290826cec42fe395e5a6eab07b88845f8b9a9829998d' + 'd45e2ae1d21b1dc8e0de94a4fa58e9a53d72306843f87d3cc49f5f641399d8e3' + '172dbc88d0a3cda78387f3c907fa4953c71cb1cb162f0b34f78b8b78924bc3d4' + '6739a42bf9d233cb58ae9a69c3f78959175de695e2d4a7e66bb9984fcf5c0f7e' + 'f036ac8a49153f66d7d8638508cfe0b4a158d12faf30d2c671b04a6b7b606b3b' + 'a691e7b22633fe0c458d140167d6d381b66149e05de3cb926b30a19fd43e78ce' + '7b16fce20b03babc9e149030f43e283534835bbd8835ba0a794fd0205fea1708' + 'bca0caa5efad45c0acde1e78d43f8ce1af6ebf3cbb0240b143be3e6486509970' + 'b6288935f2768a7023d11e9a200f47b087669ffd4d418f791ee71d5a51d0530e' + '5b19e3d557fbd52ef7e966b6d491c17a77769f03534b8cf9877fe3696e5d291f' + '1f63361ebbebecaaa3122ec174b39dfc346eda44592299a058b44bb4837b5d92' + '0febf2e8fee2e5c2222441464812aca66d21d714cd28aa7c218218b509d242fb' + '00feb23b3ed0983d13a8929ade35b3dcb23987d21f0e342db4dcb8292656a72e' '15e912a66e4bbce1cf0450f1dc6610653df29df8dd6d5426f9c1b039490436c8' - 'e9e4b03b836e1a86a2a5dc70b0d5512348eb19742f83bee794a3ab7d91bd41cf' - 'de8c9747637768c4356c06aa65c3f157c526aa420f21fdd5edd0ed06f720a62e' - '9f6b8c3ea6e1c285e0a7efda4d743dbae343bc6ee7ad599a4ab7d380c750bc83' - '4bfbff4eba07fc9de2ce78097a4a269509468ba0e24c15a82905cd94e093ad55' - 'c368cc4eefff20b7ae904eec686b7e72b46ff02b32c8a4fbd6bd4039f087e7ba' - '1a8639167a1ee1b66f580c0c6f8304e6ef359a68cfa3eb869d9200a9f0234098' - '021f8539ab2fb722b46937b95fdab22a2308236a24ecc1a9ea8db4853721dd39' - 'a01cf700d79b983807e2285be1b30df6e02db6adfd9c9027fe2dfa8ca5a74bc9' - '1ce9fd988201c4d2e48794c58acda5b768ec0fea1d29555e99d35cd2712281e4' - 'e7e37c7c433c58e2f5a79e2a7724823bef1dccaa01e857584397b4e3c837d991' - 'f075ac354acfd65dff4db49dc9798747cb9b7a3dd9839987bc46495bdbbd22dc' - '2163cb2e394a013042a40cd3b00dae788603284b20d71e262995366c5534e480' - '1770fec49335bc93194e9e55ced49e1cb67f2df4bf6948e80712a0b2ba50fa49' - '6da4010f86a74125969fd3dbc953da7b45209d33ff3d216474c3399e82e893ff' - 'eb391b6d1ebf7ef99ece00b23609b94180a1f3c0149bcf05f6bbeb74d0b724c7' - 'f7afab5f2d872dbb66774a189ed462750985aed0df1d81b3a49db9809e8557b6' - 'dd5b0df91e7c17e26af4839b3a23ba5e8850d329aeb28137ec6468502418f2bd' - '544464bf0807b324120767d55867f03014a9fda4e1804768ca341be902d7ade4' - 'f7a4bf6293912bfc4a20743e58a5a266be8c4dbe3c1862d196d3a3b45f2f7c90' - 'ee8794a551e33226900654d5c806183bf3b9b2e06f64fdc322987215d233d399' - '2d854fc70297bb52bbc27dbf35ca019800530e40565be9740704d7f81bc4c763' - '1cec0be41732a23c709e66d4a67e71bc5a75c77a3e4b73faafb5d7bfd3fafc0f' - '9025ca0788fbacea25200e6ac17036960000424843f544cdd781052231da7903' - 'e7bd53abc9fddc66790a2e63637b4e2b54ed541f41a2f0fb3aca91ea64ff90dc') + '444f2d86de8c2177655b01596f939f99c2e7abfa8efad8a509e0a334f42dfa85' + '982a31e47d3d586789e1b3cdda25f75e3b71d810e7494202089b8f2cef7c0ef9') # notable microarch levels: # @@ -140,33 +91,10 @@ if [ -z ${_microarchitecture+x} ]; then _microarchitecture=93 fi -_fedora_kernel_patch_skip_list=( - # fedora kernel patches to skip - # use plain file names or bash glob syntax, ** don't quote globs ** - - # multi-select and ranges examples - # 00{03,05,08}-drm-amdgpu*.patch - # 00{01..12}-drm-amdgpu*.patch - - "linux-kernel-test.patch" # test patch, please ignore - patch-*-redhat.patch # wildcard match any redhat patch version - - 0001-asus-wmi-Add-support-for-platform_profile.patch - 0001-asus-wmi-Add-panel-overdrive-functionality.patch - 0004-HID-asus-Remove-check-for-same-LED-brightness-on-set.patch - 0001-HID-asus-Prevent-Claymore-sending-suspend-event.patch - 0015-PCI-quirks-Quirk-PCI-d3hot-delay-for-AMD-xhci.patch -) - export KBUILD_BUILD_HOST=archlinux export KBUILD_BUILD_USER=$pkgbase export KBUILD_BUILD_TIMESTAMP="$(date -Ru${SOURCE_DATE_EPOCH:+d @$SOURCE_DATE_EPOCH})" -_fedora_patch_in_skip_list() { - for p in "${_fedora_kernel_patch_skip_list[@]}"; do [[ "$1" == $p ]] && return 0; done - return 1 -} - prepare() { cd $_srcname @@ -185,31 +113,6 @@ prepare() { patch -Np1 < "../$src" done - msg2 "Applying asus-linux patches..." - local p_err=() - local p_meh=() - - # this will apply only enabled patches from the fedora-linux kernel.spec - # this stops us from applying broken or in-progress patches that are in git but aren't actually in use - - local _fkernel_path="../fedora-kernel-${_fedora_kernel_commit_id}" - for src in $(awk -F ' ' '/^ApplyOptionalPatch.*(patch|diff)$/{print $2}' "${_fkernel_path}/kernel.spec"); do - src="${src##*/}" - _fedora_patch_in_skip_list "$src" && continue - echo "Applying patch $src..." - if OUT="$(patch --forward -Np1 < "${_fkernel_path}/$src")"; then - : #plain "Applied patch $src..." - else - # if you want to ignore a specific patch failure for some reason do it right here, then 'continue' - if { echo "$OUT" | grep -qiE 'hunk(|s) FAILED'; }; then - error "Patch failed $src" && echo "$OUT" && p_err+=("$src") && _throw=y - else - warning "Duplicate patch $src" && p_meh+=("$src") - fi - fi - done - (( ${#p_err[@]} > 0 )) && error "Failed patches:" && for p in ${p_err[@]}; do plain "$p"; done - (( ${#p_meh[@]} > 0 )) && warning "Duplicate patches:" && for p in ${p_meh[@]}; do plain "$p"; done # if throw is defined we had a hard patch failure, propagate it and stop so we can address [[ -z "$_throw" ]] @@ -225,13 +128,57 @@ prepare() { make -s kernelrelease > version echo "Prepared $pkgbase version $(<version)" - scripts/config --enable CONFIG_CMDLINE_BOOL \ - --set-str CONFIG_CMDLINE "pm_debug_messages amd_pmc.dyndbg=+p acpi.dyndbg=file drivers/acpi/x86/s2idle.c +p" \ - --disable CMDLINE_OVERRIDE - scripts/config --enable CONFIG_PINCTRL_AMD - scripts/config --module CONFIG_X86_AMD_PSTATE + scripts/config --enable CONFIG_X86_AMD_PSTATE scripts/config --module CONFIG_AMD_PMC + + scripts/config --disable CONFIG_MODULE_COMPRESS_NONE \ + --enable CONFIG_MODULE_COMPRESS_ZSTD + + ## SET default LRU parameters + scripts/config --enable CONFIG_LRU_GEN + scripts/config --enable CONFIG_LRU_GEN_ENABLED + scripts/config --disable CONFIG_LRU_GEN_STATS + scripts/config --set-val CONFIG_NR_LRU_GENS 7 + scripts/config --set-val CONFIG_TIERS_PER_GEN 4 + + # DISABLE not need modules on ROG laptops + # XXX: I'm going to make an opinionated decision here and save everyone some compilation time + # XXX: on drivers almost no-one is going to use; if you need any of theese turn them on in myconfig + scripts/config --disable CONFIG_INFINIBAND \ + --disable CONFIG_DRM_NOUVEAU \ + --disable CONFIG_PCMCIA_WL3501 \ + --disable CONFIG_PCMCIA_RAYCS \ + --disable CONFIG_IWL3945 \ + --disable CONFIG_IWL4965 \ + --disable CONFIG_IPW2200 \ + --disable CONFIG_IPW2100 \ + --disable CONFIG_FB_NVIDIA \ + --disable CONFIG_SENSORS_ASUS_EC \ + --disable CONFIG_SENSORS_ASUS_WMI_EC + + # select slightly more sane block device driver options; NVMe really should be built in + scripts/config --disable CONFIG_RAPIDIO \ + --module CONFIG_CDROM \ + --disable CONFIG_PARIDE \ + + # bake in s0ix debugging parameters so we get useful problem reports re: suspend + scripts/config --enable CONFIG_CMDLINE_BOOL \ + --set-str CONFIG_CMDLINE "makepkgplaceholderyolo" \ + --disable CMDLINE_OVERRIDE + + # enable back EFI_HANDOVER_PROTOCOL and EFI_STUB + scripts/config --enable CONFIG_EFI_HANDOVER_PROTOCOL \ + --enable CONFIG_EFI_STUB + + # HACK: forcibly fixup CONFIG_CMDLINE here as using scripts/config mangles escaped quotes + sed -i 's#makepkgplaceholderyolo#ibt=off pm_debug_messages amd_pmc.dyndbg=\\"+p\\" acpi.dyndbg=\\"file drivers/acpi/x86/s2idle.c +p\\"#' .config + + # Note the double escaped quotes above, sed strips one; the final result in .config needs to contain single slash + # escaped quotes (eg: `CONFIG_CMDLINE="foo.dyndbg=\"+p\""`) to avoid dyndbg parse errors at boot. This is impossible + # with the current kernel config script. + + } build() { @@ -284,6 +231,9 @@ _package-headers() { # add objtool for external module building and enabled VALIDATION_STACK option install -Dt "$builddir/tools/objtool" tools/objtool/objtool + # required when DEBUG_INFO_BTF_MODULES is enabled + install -Dt "$builddir/tools/bpf/resolve_btfids" tools/bpf/resolve_btfids/resolve_btfids + # add xfs and shmem for aufs building mkdir -p "$builddir"/{fs/xfs,mm} diff --git a/README b/README deleted file mode 100644 index 59c64360b06a..000000000000 --- a/README +++ /dev/null @@ -1,4 +0,0 @@ -This kernel contains miscellaneous patches for ASUS ROG Laptops (not only for G14) - -More information and recommend way to install this kernel can be found here https://asus-linux.org/wiki/arch-guide/ -AUR: https://aur.archlinux.org/packages/linux-g14/ (but recommend way is to use repo in the link above)
\ No newline at end of file diff --git a/choose-gcc-optimization.sh b/choose-gcc-optimization.sh index f10eec54b81d..140c4ac144ef 100755 --- a/choose-gcc-optimization.sh +++ b/choose-gcc-optimization.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash . /usr/share/makepkg/util/message.sh -colorize +[[ -t 1 ]] && colorize Detect_CPU=$(gcc -c -Q -march=native --help=target | grep march | awk '{print $2}' | head -1) @@ -134,6 +134,7 @@ msg "Building this package for microarchitecture: $Microarchitecture$default" sleep 5 sed -e 's|^CONFIG_GENERIC_CPU=y|# CONFIG_GENERIC_CPU is not set|g' -i .config +sed -e 's|^CONFIG_GENERIC_CPU2=y|# CONFIG_GENERIC_CPU2 is not set|g' -i .config sed -e "s|^# $Microarchitecture is not set|$Microarchitecture=y|g" -i .config echo @@ -1,22 +1,23 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 5.14.1-arch1 Kernel Configuration +# Linux/x86 6.1.1-arch1 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.1.0" +CONFIG_CC_VERSION_TEXT="gcc (GCC) 12.2.0" CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=110100 +CONFIG_GCC_VERSION=120200 CONFIG_CLANG_VERSION=0 CONFIG_AS_IS_GNU=y -CONFIG_AS_VERSION=23601 +CONFIG_AS_VERSION=23900 CONFIG_LD_IS_BFD=y -CONFIG_LD_VERSION=23601 +CONFIG_LD_VERSION=23900 CONFIG_LLD_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y -CONFIG_CC_HAS_ASM_GOTO=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y +CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_PAHOLE_VERSION=124 CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_TABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y @@ -26,6 +27,7 @@ CONFIG_THREAD_INFO_IN_TASK=y # CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_BUILD_SALT="" @@ -45,9 +47,9 @@ CONFIG_HAVE_KERNEL_ZSTD=y CONFIG_KERNEL_ZSTD=y CONFIG_DEFAULT_INIT="" CONFIG_DEFAULT_HOSTNAME="archlinux" -CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSVIPC_COMPAT=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_WATCH_QUEUE=y @@ -91,6 +93,8 @@ CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y # # Timers subsystem @@ -98,10 +102,13 @@ CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ_COMMON=y # CONFIG_HZ_PERIODIC is not set -CONFIG_NO_HZ_IDLE=y -# CONFIG_NO_HZ_FULL is not set +# CONFIG_NO_HZ_IDLE is not set +CONFIG_NO_HZ_FULL=y +CONFIG_CONTEXT_TRACKING_USER=y +# CONFIG_CONTEXT_TRACKING_USER_FORCE is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100 # end of Timers subsystem CONFIG_BPF=y @@ -115,13 +122,14 @@ CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y CONFIG_BPF_JIT_ALWAYS_ON=y CONFIG_BPF_JIT_DEFAULT_ON=y -# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +CONFIG_BPF_UNPRIV_DEFAULT_OFF=y CONFIG_USERMODE_DRIVER=y CONFIG_BPF_PRELOAD=y CONFIG_BPF_PRELOAD_UMD=m CONFIG_BPF_LSM=y # end of BPF subsystem +CONFIG_PREEMPT_BUILD=y # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y @@ -133,8 +141,8 @@ CONFIG_SCHED_CORE=y # # CPU/Task time and stats accounting # -CONFIG_TICK_CPU_ACCOUNTING=y -# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_SCHED_AVG_IRQ=y CONFIG_BSD_PROCESS_ACCT=y @@ -158,17 +166,22 @@ CONFIG_RCU_EXPERT=y CONFIG_SRCU=y CONFIG_TREE_SRCU=y CONFIG_TASKS_RCU_GENERIC=y +# CONFIG_FORCE_TASKS_RCU is not set CONFIG_TASKS_RCU=y +# CONFIG_FORCE_TASKS_RUDE_RCU is not set CONFIG_TASKS_RUDE_RCU=y +# CONFIG_FORCE_TASKS_TRACE_RCU is not set CONFIG_TASKS_TRACE_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y CONFIG_RCU_FANOUT=64 CONFIG_RCU_FANOUT_LEAF=16 -CONFIG_RCU_FAST_NO_HZ=y CONFIG_RCU_BOOST=y CONFIG_RCU_BOOST_DELAY=500 -# CONFIG_RCU_NOCB_CPU is not set +# CONFIG_RCU_EXP_KTHREAD is not set +CONFIG_RCU_NOCB_CPU=y +# CONFIG_RCU_NOCB_CPU_DEFAULT_ALL is not set +# CONFIG_RCU_NOCB_CPU_CB_BOOST is not set # CONFIG_TASKS_TRACE_RCU_READ_MB is not set # end of RCU Subsystem @@ -179,6 +192,7 @@ CONFIG_IKHEADERS=m CONFIG_LOG_BUF_SHIFT=17 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +CONFIG_PRINTK_INDEX=y CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y # @@ -191,13 +205,16 @@ CONFIG_UCLAMP_BUCKETS_COUNT=5 CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC12_NO_ARRAY_BOUNDS=y +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y +# CONFIG_CGROUP_FAVOR_DYNMODS is not set CONFIG_MEMCG=y -CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_KMEM=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y @@ -241,6 +258,8 @@ CONFIG_RD_LZO=y CONFIG_RD_LZ4=y CONFIG_RD_ZSTD=y CONFIG_BOOT_CONFIG=y +# CONFIG_BOOT_CONFIG_EMBED is not set +CONFIG_INITRAMFS_PRESERVE_MTIME=y CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_LD_ORPHAN_WARN=y @@ -256,7 +275,6 @@ CONFIG_SYSFS_SYSCALL=y CONFIG_FHANDLE=y CONFIG_POSIX_TIMERS=y CONFIG_PRINTK=y -CONFIG_PRINTK_NMI=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_PCSPKR_PLATFORM=y @@ -271,19 +289,17 @@ CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y -CONFIG_HAVE_ARCH_USERFAULTFD_WP=y -CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y CONFIG_KALLSYMS_BASE_RELATIVE=y -CONFIG_USERFAULTFD=y CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_KCMP=y CONFIG_RSEQ=y # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y +CONFIG_GUEST_PERF_EVENTS=y # # Kernel Performance Events And Counters @@ -292,16 +308,6 @@ CONFIG_PERF_EVENTS=y # CONFIG_DEBUG_PERF_USE_VMALLOC is not set # end of Kernel Performance Events And Counters -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_COMPAT_BRK is not set -# CONFIG_SLAB is not set -CONFIG_SLUB=y -CONFIG_SLAB_MERGE_DEFAULT=y -CONFIG_SLAB_FREELIST_RANDOM=y -CONFIG_SLAB_FREELIST_HARDENED=y -CONFIG_SHUFFLE_PAGE_ALLOCATOR=y -CONFIG_SLUB_CPU_PARTIAL=y CONFIG_SYSTEM_DATA_VERIFICATION=y CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y @@ -325,13 +331,9 @@ CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y -CONFIG_ARCH_HAS_FILTER_PGPROT=y -CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_NR_GPIO=1024 CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y CONFIG_AUDIT_ARCH=y CONFIG_HAVE_INTEL_TXT=y CONFIG_X86_64_SMP=y @@ -349,7 +351,6 @@ CONFIG_X86_FEATURE_NAMES=y CONFIG_X86_X2APIC=y CONFIG_X86_MPPARSE=y # CONFIG_GOLDFISH is not set -CONFIG_RETPOLINE=y CONFIG_X86_CPU_RESCTRL=y # CONFIG_X86_EXTENDED_PLATFORM is not set CONFIG_X86_INTEL_LPSS=y @@ -368,13 +369,15 @@ CONFIG_XEN=y CONFIG_XEN_PV=y CONFIG_XEN_512GB=y CONFIG_XEN_PV_SMP=y -CONFIG_XEN_DOM0=y +CONFIG_XEN_PV_DOM0=y CONFIG_XEN_PVHVM=y CONFIG_XEN_PVHVM_SMP=y CONFIG_XEN_PVHVM_GUEST=y CONFIG_XEN_SAVE_RESTORE=y # CONFIG_XEN_DEBUG_FS is not set CONFIG_XEN_PVH=y +CONFIG_XEN_DOM0=y +CONFIG_XEN_PV_MSR_SAFE=y CONFIG_KVM_GUEST=y CONFIG_ARCH_CPUIDLE_HALTPOLL=y CONFIG_PVH=y @@ -382,6 +385,7 @@ CONFIG_PARAVIRT_TIME_ACCOUNTING=y CONFIG_PARAVIRT_CLOCK=y CONFIG_JAILHOUSE_GUEST=y CONFIG_ACRN_GUEST=y +CONFIG_INTEL_TDX_GUEST=y # CONFIG_MK8 is not set # CONFIG_MPSC is not set # CONFIG_MCORE2 is not set @@ -405,11 +409,13 @@ CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_DMI=y # CONFIG_GART_IOMMU is not set +CONFIG_BOOT_VESA_SUPPORT=y # CONFIG_MAXSMP is not set CONFIG_NR_CPUS_RANGE_BEGIN=2 CONFIG_NR_CPUS_RANGE_END=512 CONFIG_NR_CPUS_DEFAULT=64 CONFIG_NR_CPUS=320 +CONFIG_SCHED_CLUSTER=y CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y CONFIG_SCHED_MC_PRIO=y @@ -430,22 +436,24 @@ CONFIG_PERF_EVENTS_INTEL_UNCORE=m CONFIG_PERF_EVENTS_INTEL_RAPL=m CONFIG_PERF_EVENTS_INTEL_CSTATE=m CONFIG_PERF_EVENTS_AMD_POWER=m +CONFIG_PERF_EVENTS_AMD_UNCORE=m +CONFIG_PERF_EVENTS_AMD_BRS=y # end of Performance monitoring CONFIG_X86_16BIT=y CONFIG_X86_ESPFIX64=y CONFIG_X86_VSYSCALL_EMULATION=y CONFIG_X86_IOPL_IOPERM=y -CONFIG_I8K=m CONFIG_MICROCODE=y CONFIG_MICROCODE_INTEL=y CONFIG_MICROCODE_AMD=y -# CONFIG_MICROCODE_OLD_INTERFACE is not set +# CONFIG_MICROCODE_LATE_LOADING is not set CONFIG_X86_MSR=y CONFIG_X86_CPUID=y CONFIG_X86_5LEVEL=y CONFIG_X86_DIRECT_GBPAGES=y CONFIG_X86_CPA_STATISTICS=y +CONFIG_X86_MEM_ENCRYPT=y CONFIG_AMD_MEM_ENCRYPT=y # CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT is not set CONFIG_NUMA=y @@ -455,7 +463,6 @@ CONFIG_X86_64_ACPI_NUMA=y CONFIG_NODES_SHIFT=5 CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y # CONFIG_ARCH_MEMORY_PROBE is not set CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 @@ -469,9 +476,9 @@ CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=0 CONFIG_X86_PAT=y CONFIG_ARCH_USES_PG_UNCACHED=y -CONFIG_ARCH_RANDOM=y -CONFIG_X86_SMAP=y CONFIG_X86_UMIP=y +CONFIG_CC_HAS_IBT=y +CONFIG_X86_KERNEL_IBT=y CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y # CONFIG_X86_INTEL_TSX_MODE_OFF is not set # CONFIG_X86_INTEL_TSX_MODE_ON is not set @@ -489,7 +496,9 @@ CONFIG_SCHED_HRTICK=y CONFIG_KEXEC=y CONFIG_KEXEC_FILE=y CONFIG_ARCH_HAS_KEXEC_PURGATORY=y -# CONFIG_KEXEC_SIG is not set +CONFIG_KEXEC_SIG=y +# CONFIG_KEXEC_SIG_FORCE is not set +CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y CONFIG_CRASH_DUMP=y CONFIG_KEXEC_JUMP=y CONFIG_PHYSICAL_START=0x1000000 @@ -504,18 +513,27 @@ CONFIG_HOTPLUG_CPU=y # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set # CONFIG_DEBUG_HOTPLUG_CPU0 is not set # CONFIG_COMPAT_VDSO is not set -# CONFIG_LEGACY_VSYSCALL_EMULATE is not set CONFIG_LEGACY_VSYSCALL_XONLY=y # CONFIG_LEGACY_VSYSCALL_NONE is not set # CONFIG_CMDLINE_BOOL is not set CONFIG_MODIFY_LDT_SYSCALL=y +# CONFIG_STRICT_SIGALTSTACK_SIZE is not set CONFIG_HAVE_LIVEPATCH=y # CONFIG_LIVEPATCH is not set # end of Processor type and features +CONFIG_CC_HAS_SLS=y +CONFIG_CC_HAS_RETURN_THUNK=y +CONFIG_SPECULATION_MITIGATIONS=y +CONFIG_PAGE_TABLE_ISOLATION=y +CONFIG_RETPOLINE=y +CONFIG_RETHUNK=y +CONFIG_CPU_UNRET_ENTRY=y +CONFIG_CPU_IBPB_ENTRY=y +CONFIG_CPU_IBRS_ENTRY=y +CONFIG_SLS=y CONFIG_ARCH_HAS_ADD_PAGES=y CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y -CONFIG_USE_PERCPU_NUMA_NODE_ID=y # # Power management and ACPI options @@ -530,6 +548,7 @@ CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y # CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set # CONFIG_PM_WAKELOCKS is not set CONFIG_PM=y CONFIG_PM_DEBUG=y @@ -548,6 +567,7 @@ CONFIG_ACPI=y CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y +CONFIG_ACPI_TABLE_LIB=y # CONFIG_ACPI_DEBUGGER is not set CONFIG_ACPI_SPCR_TABLE=y CONFIG_ACPI_FPDT=y @@ -602,6 +622,8 @@ CONFIG_ACPI_WATCHDOG=y CONFIG_ACPI_EXTLOG=m CONFIG_ACPI_ADXL=y CONFIG_ACPI_CONFIGFS=m +CONFIG_ACPI_PFRUT=m +CONFIG_ACPI_PCC=y CONFIG_PMIC_OPREGION=y CONFIG_BYTCRC_PMIC_OPREGION=y CONFIG_CHTCRC_PMIC_OPREGION=y @@ -611,8 +633,8 @@ CONFIG_CHT_WC_PMIC_OPREGION=y CONFIG_CHT_DC_TI_PMIC_OPREGION=y CONFIG_TPS68470_PMIC_OPREGION=y CONFIG_ACPI_VIOT=y -CONFIG_X86_PM_TIMER=y CONFIG_ACPI_PRMT=y +CONFIG_X86_PM_TIMER=y # # CPU Frequency scaling @@ -636,8 +658,8 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # CPU frequency scaling drivers # CONFIG_X86_INTEL_PSTATE=y -CONFIG_X86_AMD_PSTATE=y CONFIG_X86_PCC_CPUFREQ=m +CONFIG_X86_AMD_PSTATE=m CONFIG_X86_ACPI_CPUFREQ=m CONFIG_X86_ACPI_CPUFREQ_CPB=y CONFIG_X86_POWERNOW_K8=m @@ -674,80 +696,26 @@ CONFIG_PCI_XEN=y CONFIG_MMCONF_FAM10H=y CONFIG_ISA_DMA_API=y CONFIG_AMD_NB=y -# CONFIG_X86_SYSFB is not set # end of Bus options (PCI etc.) # # Binary Emulations # CONFIG_IA32_EMULATION=y -# CONFIG_X86_X32 is not set +# CONFIG_X86_X32_ABI is not set CONFIG_COMPAT_32=y CONFIG_COMPAT=y CONFIG_COMPAT_FOR_U64_ALIGNMENT=y -CONFIG_SYSVIPC_COMPAT=y # end of Binary Emulations -# -# Firmware Drivers -# -CONFIG_EDD=m -# CONFIG_EDD_OFF is not set -CONFIG_FIRMWARE_MEMMAP=y -CONFIG_DMIID=y -CONFIG_DMI_SYSFS=y -CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y -CONFIG_ISCSI_IBFT_FIND=y -CONFIG_ISCSI_IBFT=m -CONFIG_FW_CFG_SYSFS=m -# CONFIG_FW_CFG_SYSFS_CMDLINE is not set -CONFIG_GOOGLE_FIRMWARE=y -# CONFIG_GOOGLE_SMI is not set -CONFIG_GOOGLE_COREBOOT_TABLE=m -CONFIG_GOOGLE_MEMCONSOLE=m -# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set -CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT=m -CONFIG_GOOGLE_MEMCONSOLE_COREBOOT=m -CONFIG_GOOGLE_VPD=m - -# -# EFI (Extensible Firmware Interface) Support -# -# CONFIG_EFI_VARS is not set -CONFIG_EFI_ESRT=y -CONFIG_EFI_VARS_PSTORE=y -CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y -CONFIG_EFI_RUNTIME_MAP=y -# CONFIG_EFI_FAKE_MEMMAP is not set -CONFIG_EFI_SOFT_RESERVE=y -CONFIG_EFI_RUNTIME_WRAPPERS=y -CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y -CONFIG_EFI_BOOTLOADER_CONTROL=m -CONFIG_EFI_CAPSULE_LOADER=m -# CONFIG_EFI_TEST is not set -CONFIG_APPLE_PROPERTIES=y -# CONFIG_RESET_ATTACK_MITIGATION is not set -CONFIG_EFI_RCI2_TABLE=y -# CONFIG_EFI_DISABLE_PCI_DMA is not set -# end of EFI (Extensible Firmware Interface) Support - -CONFIG_EFI_EMBEDDED_FIRMWARE=y -CONFIG_UEFI_CPER=y -CONFIG_UEFI_CPER_X86=y -CONFIG_EFI_DEV_PATH_PARSER=y -CONFIG_EFI_EARLYCON=y -CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y - -# -# Tegra firmware driver -# -# end of Tegra firmware driver -# end of Firmware Drivers - CONFIG_HAVE_KVM=y +CONFIG_HAVE_KVM_PFNCACHE=y CONFIG_HAVE_KVM_IRQCHIP=y CONFIG_HAVE_KVM_IRQFD=y CONFIG_HAVE_KVM_IRQ_ROUTING=y +CONFIG_HAVE_KVM_DIRTY_RING=y +CONFIG_HAVE_KVM_DIRTY_RING_TSO=y +CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y CONFIG_HAVE_KVM_EVENTFD=y CONFIG_KVM_MMIO=y CONFIG_KVM_ASYNC_PF=y @@ -767,7 +735,7 @@ CONFIG_X86_SGX_KVM=y CONFIG_KVM_AMD=m CONFIG_KVM_AMD_SEV=y CONFIG_KVM_XEN=y -CONFIG_KVM_MMU_AUDIT=y +CONFIG_KVM_EXTERNAL_WRITE_TRACKING=y CONFIG_AS_AVX512=y CONFIG_AS_SHA1_NI=y CONFIG_AS_SHA256_NI=y @@ -790,14 +758,18 @@ CONFIG_UPROBES=y CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_KRETPROBES=y +CONFIG_KRETPROBE_ON_RETHOOK=y CONFIG_USER_RETURN_NOTIFIER=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_OPTPROBES=y CONFIG_HAVE_KPROBES_ON_FTRACE=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y @@ -810,6 +782,7 @@ CONFIG_ARCH_WANTS_NO_INSTR=y CONFIG_HAVE_ASM_MODVERSIONS=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_RUST=y CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y CONFIG_HAVE_HW_BREAKPOINT=y CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y @@ -822,6 +795,7 @@ CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y CONFIG_MMU_GATHER_TABLE_FREE=y CONFIG_MMU_GATHER_RCU_TABLE_FREE=y +CONFIG_MMU_GATHER_MERGE_VMAS=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y CONFIG_HAVE_CMPXCHG_LOCAL=y @@ -840,9 +814,10 @@ CONFIG_STACKPROTECTOR_STRONG=y CONFIG_ARCH_SUPPORTS_LTO_CLANG=y CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_CONTEXT_TRACKING_OFFSTACK=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y +CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_MOVE_PUD=y @@ -850,12 +825,14 @@ CONFIG_HAVE_MOVE_PMD=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_HAVE_ARCH_HUGE_VMALLOC=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_HAVE_ARCH_SOFT_DIRTY=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_HAVE_ARCH_MMAP_RND_BITS=y CONFIG_HAVE_EXIT_THREAD=y @@ -863,6 +840,13 @@ CONFIG_ARCH_MMAP_RND_BITS=28 CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y CONFIG_ARCH_MMAP_RND_COMPAT_BITS=8 CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_HAVE_OBJTOOL=y +CONFIG_HAVE_JUMP_LABEL_HACK=y +CONFIG_HAVE_NOINSTR_HACK=y +CONFIG_HAVE_NOINSTR_VALIDATION=y +CONFIG_HAVE_UACCESS_VALIDATION=y CONFIG_HAVE_STACK_VALIDATION=y CONFIG_HAVE_RELIABLE_STACKTRACE=y CONFIG_ISA_BUS_API=y @@ -872,6 +856,7 @@ CONFIG_COMPAT_32BIT_TIME=y CONFIG_HAVE_ARCH_VMAP_STACK=y CONFIG_VMAP_STACK=y CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET=y CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y CONFIG_STRICT_KERNEL_RWX=y @@ -881,12 +866,19 @@ CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y CONFIG_ARCH_USE_MEMREMAP_PROT=y CONFIG_LOCK_EVENT_COUNTS=y CONFIG_ARCH_HAS_MEM_ENCRYPT=y +CONFIG_ARCH_HAS_CC_PLATFORM=y CONFIG_HAVE_STATIC_CALL=y CONFIG_HAVE_STATIC_CALL_INLINE=y CONFIG_HAVE_PREEMPT_DYNAMIC=y +CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y CONFIG_ARCH_HAS_ELFCORE_COMPAT=y +CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y +CONFIG_DYNAMIC_SIGFRAME=y +CONFIG_HAVE_ARCH_NODE_DEV_GROUP=y +CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y # # GCOV-based kernel profiling @@ -898,7 +890,6 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y CONFIG_HAVE_GCC_PLUGINS=y CONFIG_GCC_PLUGINS=y # CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set -# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set # end of General architecture-dependent options CONFIG_RT_MUTEXES=y @@ -908,6 +899,7 @@ CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODULE_UNLOAD_TAINT_TRACKING=y # CONFIG_MODVERSIONS is not set CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_MODULE_SIG=y @@ -927,17 +919,17 @@ CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y CONFIG_MODPROBE_PATH="/sbin/modprobe" CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y CONFIG_BLK_RQ_ALLOC_TIME=y -CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_CGROUP_RWSTAT=y -CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_ICQ=y CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BLK_DEV_INTEGRITY_T10=y CONFIG_BLK_DEV_ZONED=y CONFIG_BLK_DEV_THROTTLING=y CONFIG_BLK_DEV_THROTTLING_LOW=y -# CONFIG_BLK_CMDLINE_PARSER is not set CONFIG_BLK_WBT=y CONFIG_BLK_WBT_MQ=y CONFIG_BLK_CGROUP_IOLATENCY=y @@ -981,6 +973,8 @@ CONFIG_BLK_MQ_PCI=y CONFIG_BLK_MQ_VIRTIO=y CONFIG_BLK_MQ_RDMA=y CONFIG_BLK_PM=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y +CONFIG_BLK_MQ_STACKING=y # # IO Schedulers @@ -1024,8 +1018,40 @@ CONFIG_COREDUMP=y # # Memory Management options # -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_SPARSEMEM_MANUAL=y +CONFIG_ZPOOL=y +CONFIG_SWAP=y +CONFIG_ZSWAP=y +CONFIG_ZSWAP_DEFAULT_ON=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lz4" +# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD is not set +CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD=y +# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set +CONFIG_ZSWAP_ZPOOL_DEFAULT="z3fold" +CONFIG_ZBUD=y +CONFIG_Z3FOLD=y +CONFIG_ZSMALLOC=y +# CONFIG_ZSMALLOC_STAT is not set + +# +# SLAB allocator options +# +# CONFIG_SLAB is not set +CONFIG_SLUB=y +CONFIG_SLAB_MERGE_DEFAULT=y +CONFIG_SLAB_FREELIST_RANDOM=y +CONFIG_SLAB_FREELIST_HARDENED=y +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# end of SLAB allocator options + +CONFIG_SHUFFLE_PAGE_ALLOCATOR=y +# CONFIG_COMPAT_BRK is not set CONFIG_SPARSEMEM=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y @@ -1033,12 +1059,12 @@ CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_HAVE_FAST_GUP=y CONFIG_NUMA_KEEP_MEMINFO=y CONFIG_MEMORY_ISOLATION=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_HAVE_BOOTMEM_INFO_NODE=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTPLUG=y -CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_MHP_MEMMAP_ON_MEMORY=y CONFIG_SPLIT_PTLOCK_CPUS=4 @@ -1046,25 +1072,31 @@ CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_PAGE_REPORTING=y CONFIG_MIGRATION=y +CONFIG_DEVICE_MIGRATION=y CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y CONFIG_ARCH_ENABLE_THP_MIGRATION=y CONFIG_CONTIG_ALLOC=y CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_VIRT_TO_BUS=y CONFIG_MMU_NOTIFIER=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y CONFIG_MEMORY_FAILURE=y CONFIG_HWPOISON_INJECT=m -CONFIG_TRANSPARENT_HUGEPAGE=y -# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set -CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set CONFIG_THP_SWAP=y -CONFIG_CLEANCACHE=y +CONFIG_READ_ONLY_THP_FOR_FS=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_FRONTSWAP=y CONFIG_CMA=y # CONFIG_CMA_DEBUG is not set @@ -1072,44 +1104,49 @@ CONFIG_CMA_DEBUGFS=y CONFIG_CMA_SYSFS=y CONFIG_CMA_AREAS=7 CONFIG_MEM_SOFT_DIRTY=y -CONFIG_ZSWAP=y -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set -CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4=y -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set -CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lz4" -# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD is not set -CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD=y -# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set -CONFIG_ZSWAP_ZPOOL_DEFAULT="z3fold" -CONFIG_ZSWAP_DEFAULT_ON=y -CONFIG_ZPOOL=y -CONFIG_ZBUD=y -CONFIG_Z3FOLD=y -CONFIG_ZSMALLOC=y -# CONFIG_ZSMALLOC_STAT is not set CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +CONFIG_PAGE_IDLE_FLAG=y CONFIG_IDLE_PAGE_TRACKING=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_ZONE_DMA=y CONFIG_ZONE_DMA32=y CONFIG_ZONE_DEVICE=y -CONFIG_DEV_PAGEMAP_OPS=y CONFIG_HMM_MIRROR=y +CONFIG_GET_FREE_REGION=y CONFIG_DEVICE_PRIVATE=y CONFIG_VMAP_PFN=y CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y CONFIG_ARCH_HAS_PKEYS=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_PERCPU_STATS is not set # CONFIG_GUP_TEST is not set -CONFIG_READ_ONLY_THP_FOR_FS=y CONFIG_ARCH_HAS_PTE_SPECIAL=y CONFIG_MAPPING_DIRTY_HELPERS=y CONFIG_SECRETMEM=y +CONFIG_ANON_VMA_NAME=y +CONFIG_USERFAULTFD=y +CONFIG_HAVE_ARCH_USERFAULTFD_WP=y +CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y +CONFIG_PTE_MARKER=y +CONFIG_PTE_MARKER_UFFD_WP=y +CONFIG_LRU_GEN=y +CONFIG_LRU_GEN_ENABLED=y +# CONFIG_LRU_GEN_STATS is not set + +# +# Data Access Monitoring +# +CONFIG_DAMON=y +CONFIG_DAMON_VADDR=y +CONFIG_DAMON_PADDR=y +CONFIG_DAMON_SYSFS=y +CONFIG_DAMON_DBGFS=y +CONFIG_DAMON_RECLAIM=y +CONFIG_DAMON_LRU_SORT=y +# end of Data Access Monitoring # end of Memory Management options CONFIG_NET=y @@ -1126,6 +1163,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y CONFIG_UNIX_DIAG=m CONFIG_TLS=m CONFIG_TLS_DEVICE=y @@ -1236,6 +1274,7 @@ CONFIG_IPV6_SEG6_LWTUNNEL=y CONFIG_IPV6_SEG6_HMAC=y CONFIG_IPV6_SEG6_BPF=y CONFIG_IPV6_RPL_LWTUNNEL=y +CONFIG_IPV6_IOAM6_LWTUNNEL=y CONFIG_NETLABEL=y CONFIG_MPTCP=y CONFIG_INET_MPTCP_DIAG=m @@ -1251,6 +1290,8 @@ CONFIG_BRIDGE_NETFILTER=m # Core Netfilter Configuration # CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_EGRESS=y +CONFIG_NETFILTER_SKIP_EGRESS=y CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_FAMILY_BRIDGE=y CONFIG_NETFILTER_FAMILY_ARP=y @@ -1304,7 +1345,6 @@ CONFIG_NF_TABLES_NETDEV=y CONFIG_NFT_NUMGEN=m CONFIG_NFT_CT=m CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NFT_COUNTER=m CONFIG_NFT_CONNLIMIT=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m @@ -1333,6 +1373,7 @@ CONFIG_NFT_FIB_NETDEV=m CONFIG_NFT_REJECT_NETDEV=m CONFIG_NF_FLOW_TABLE_INET=m CONFIG_NF_FLOW_TABLE=m +CONFIG_NF_FLOW_TABLE_PROCFS=y CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XTABLES_COMPAT=y @@ -1504,7 +1545,6 @@ CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m CONFIG_NF_TABLES_ARP=y -CONFIG_NF_FLOW_TABLE_IPV4=m CONFIG_NF_DUP_IPV4=m CONFIG_NF_LOG_ARP=m CONFIG_NF_LOG_IPV4=m @@ -1544,7 +1584,6 @@ CONFIG_NF_TABLES_IPV6=y CONFIG_NFT_REJECT_IPV6=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m -CONFIG_NF_FLOW_TABLE_IPV6=m CONFIG_NF_DUP_IPV6=m CONFIG_NF_REJECT_IPV6=m CONFIG_NF_LOG_IPV6=m @@ -1637,7 +1676,6 @@ CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y CONFIG_BRIDGE_CFM=y CONFIG_NET_DSA=m -CONFIG_NET_DSA_TAG_8021Q=m CONFIG_NET_DSA_TAG_AR9331=m CONFIG_NET_DSA_TAG_BRCM_COMMON=m CONFIG_NET_DSA_TAG_BRCM=m @@ -1650,10 +1688,12 @@ CONFIG_NET_DSA_TAG_DSA=m CONFIG_NET_DSA_TAG_EDSA=m CONFIG_NET_DSA_TAG_MTK=m CONFIG_NET_DSA_TAG_KSZ=m -CONFIG_NET_DSA_TAG_RTL4_A=m CONFIG_NET_DSA_TAG_OCELOT=m CONFIG_NET_DSA_TAG_OCELOT_8021Q=m CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_RTL4_A=m +CONFIG_NET_DSA_TAG_RTL8_4=m +CONFIG_NET_DSA_TAG_RZN1_A5PSW=m CONFIG_NET_DSA_TAG_LAN9303=m CONFIG_NET_DSA_TAG_SJA1105=m CONFIG_NET_DSA_TAG_TRAILER=m @@ -1661,7 +1701,6 @@ CONFIG_NET_DSA_TAG_XRS700X=m CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y -# CONFIG_DECNET is not set CONFIG_LLC=m CONFIG_LLC2=m CONFIG_ATALK=m @@ -1878,69 +1917,6 @@ CONFIG_CAN_BCM=m CONFIG_CAN_GW=m CONFIG_CAN_J1939=m CONFIG_CAN_ISOTP=m - -# -# CAN Device Drivers -# -CONFIG_CAN_VCAN=m -CONFIG_CAN_VXCAN=m -CONFIG_CAN_SLCAN=m -CONFIG_CAN_DEV=m -CONFIG_CAN_CALC_BITTIMING=y -CONFIG_CAN_JANZ_ICAN3=m -CONFIG_CAN_KVASER_PCIEFD=m -CONFIG_CAN_C_CAN=m -CONFIG_CAN_C_CAN_PLATFORM=m -CONFIG_CAN_C_CAN_PCI=m -CONFIG_CAN_CC770=m -# CONFIG_CAN_CC770_ISA is not set -CONFIG_CAN_CC770_PLATFORM=m -CONFIG_CAN_IFI_CANFD=m -CONFIG_CAN_M_CAN=m -CONFIG_CAN_M_CAN_PCI=m -CONFIG_CAN_M_CAN_PLATFORM=m -CONFIG_CAN_M_CAN_TCAN4X5X=m -CONFIG_CAN_PEAK_PCIEFD=m -CONFIG_CAN_SJA1000=m -CONFIG_CAN_EMS_PCI=m -# CONFIG_CAN_EMS_PCMCIA is not set -CONFIG_CAN_F81601=m -CONFIG_CAN_KVASER_PCI=m -CONFIG_CAN_PEAK_PCI=m -CONFIG_CAN_PEAK_PCIEC=y -CONFIG_CAN_PEAK_PCMCIA=m -CONFIG_CAN_PLX_PCI=m -# CONFIG_CAN_SJA1000_ISA is not set -CONFIG_CAN_SJA1000_PLATFORM=m -CONFIG_CAN_SOFTING=m -CONFIG_CAN_SOFTING_CS=m - -# -# CAN SPI interfaces -# -CONFIG_CAN_HI311X=m -CONFIG_CAN_MCP251X=m -CONFIG_CAN_MCP251XFD=m -# CONFIG_CAN_MCP251XFD_SANITY is not set -# end of CAN SPI interfaces - -# -# CAN USB interfaces -# -CONFIG_CAN_8DEV_USB=m -CONFIG_CAN_EMS_USB=m -CONFIG_CAN_ESD_USB2=m -CONFIG_CAN_ETAS_ES58X=m -CONFIG_CAN_GS_USB=m -CONFIG_CAN_KVASER_USB=m -CONFIG_CAN_MCBA_USB=m -CONFIG_CAN_PEAK_USB=m -CONFIG_CAN_UCAN=m -# end of CAN USB interfaces - -# CONFIG_CAN_DEBUG_DEVICES is not set -# end of CAN Device Drivers - CONFIG_BT=m CONFIG_BT_BREDR=y CONFIG_BT_RFCOMM=m @@ -1966,6 +1942,7 @@ CONFIG_BT_INTEL=m CONFIG_BT_BCM=m CONFIG_BT_RTL=m CONFIG_BT_QCA=m +CONFIG_BT_MTK=m CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y CONFIG_BT_HCIBTUSB_BCM=y @@ -2009,6 +1986,8 @@ CONFIG_AF_RXRPC_DEBUG=y CONFIG_RXKAD=y CONFIG_AF_KCM=m CONFIG_STREAM_PARSER=y +CONFIG_MCTP=y +CONFIG_MCTP_FLOWS=y CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y @@ -2047,6 +2026,7 @@ CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y CONFIG_RFKILL_GPIO=m CONFIG_NET_9P=m +CONFIG_NET_9P_FD=m CONFIG_NET_9P_VIRTIO=m CONFIG_NET_9P_XEN=m CONFIG_NET_9P_RDMA=m @@ -2112,6 +2092,7 @@ CONFIG_NET_SELFTESTS=m CONFIG_NET_SOCK_MSG=y CONFIG_NET_DEVLINK=y CONFIG_PAGE_POOL=y +# CONFIG_PAGE_POOL_STATS is not set CONFIG_FAILOVER=m CONFIG_ETHTOOL_NETLINK=y @@ -2146,6 +2127,7 @@ CONFIG_PCI_STUB=y CONFIG_PCI_PF_STUB=m CONFIG_XEN_PCIDEV_FRONTEND=m CONFIG_PCI_ATS=y +CONFIG_PCI_DOE=y CONFIG_PCI_LOCKLESS_CONFIG=y CONFIG_PCI_IOV=y CONFIG_PCI_PRI=y @@ -2153,6 +2135,8 @@ CONFIG_PCI_PASID=y CONFIG_PCI_P2PDMA=y CONFIG_PCI_LABEL=y CONFIG_PCI_HYPERV=m +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=10 CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_HOTPLUG_PCI_ACPI_IBM=m @@ -2201,10 +2185,14 @@ CONFIG_PCI_SW_SWITCHTEC=m # end of PCI switch controller drivers CONFIG_CXL_BUS=m -CONFIG_CXL_MEM=m +CONFIG_CXL_PCI=m # CONFIG_CXL_MEM_RAW_COMMANDS is not set CONFIG_CXL_ACPI=m CONFIG_CXL_PMEM=m +CONFIG_CXL_MEM=m +CONFIG_CXL_PORT=m +CONFIG_CXL_SUSPEND=y +CONFIG_CXL_REGION=y CONFIG_PCCARD=m CONFIG_PCMCIA=m CONFIG_PCMCIA_LOAD_CIS=y @@ -2231,6 +2219,7 @@ CONFIG_AUXILIARY_BUS=y # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DEVTMPFS_SAFE=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y @@ -2239,10 +2228,14 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y CONFIG_EXTRA_FIRMWARE="" # CONFIG_FW_LOADER_USER_HELPER is not set CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_XZ=y +CONFIG_FW_LOADER_COMPRESS_ZSTD=y CONFIG_FW_CACHE=y +CONFIG_FW_UPLOAD=y # end of Firmware loader CONFIG_WANT_DEV_COREDUMP=y @@ -2277,15 +2270,84 @@ CONFIG_DMA_SHARED_BUFFER=y CONFIG_MHI_BUS=m # CONFIG_MHI_BUS_DEBUG is not set CONFIG_MHI_BUS_PCI_GENERIC=m +CONFIG_MHI_BUS_EP=m # end of Bus devices CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +# end of ARM System Control and Management Interface Protocol + +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y +CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_IBFT=m +CONFIG_FW_CFG_SYSFS=m +# CONFIG_FW_CFG_SYSFS_CMDLINE is not set +CONFIG_SYSFB=y +# CONFIG_SYSFB_SIMPLEFB is not set +CONFIG_CS_DSP=m +CONFIG_GOOGLE_FIRMWARE=y +# CONFIG_GOOGLE_SMI is not set +CONFIG_GOOGLE_COREBOOT_TABLE=m +CONFIG_GOOGLE_MEMCONSOLE=m +# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set +CONFIG_GOOGLE_MEMCONSOLE_COREBOOT=m +CONFIG_GOOGLE_VPD=m + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_VARS_PSTORE=y +CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y +CONFIG_EFI_RUNTIME_MAP=y +# CONFIG_EFI_FAKE_MEMMAP is not set +CONFIG_EFI_SOFT_RESERVE=y +CONFIG_EFI_DXE_MEM_ATTRIBUTES=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y +CONFIG_EFI_BOOTLOADER_CONTROL=m +CONFIG_EFI_CAPSULE_LOADER=m +# CONFIG_EFI_TEST is not set +CONFIG_EFI_DEV_PATH_PARSER=y +CONFIG_APPLE_PROPERTIES=y +# CONFIG_RESET_ATTACK_MITIGATION is not set +CONFIG_EFI_RCI2_TABLE=y +# CONFIG_EFI_DISABLE_PCI_DMA is not set +CONFIG_EFI_EARLYCON=y +CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y +# CONFIG_EFI_DISABLE_RUNTIME is not set +CONFIG_EFI_COCO_SECRET=y +CONFIG_EFI_EMBEDDED_FIRMWARE=y +# end of EFI (Extensible Firmware Interface) Support + +CONFIG_UEFI_CPER=y +CONFIG_UEFI_CPER_X86=y + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + CONFIG_GNSS=m CONFIG_GNSS_SERIAL=m CONFIG_GNSS_MTK_SERIAL=m CONFIG_GNSS_SIRF_SERIAL=m CONFIG_GNSS_UBX_SERIAL=m +CONFIG_GNSS_USB=m CONFIG_MTD=m # CONFIG_MTD_TESTS is not set @@ -2303,6 +2365,10 @@ CONFIG_MTD=m CONFIG_MTD_BLKDEVS=m CONFIG_MTD_BLOCK=m # CONFIG_MTD_BLOCK_RO is not set + +# +# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK. +# # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set @@ -2310,8 +2376,9 @@ CONFIG_MTD_BLOCK=m # CONFIG_SSFDC is not set # CONFIG_SM_FTL is not set # CONFIG_MTD_OOPS is not set +CONFIG_MTD_PSTORE=m # CONFIG_MTD_SWAP is not set -# CONFIG_MTD_PARTITIONED_MASTER is not set +CONFIG_MTD_PARTITIONED_MASTER=y # # RAM/ROM/Flash chip drivers @@ -2323,7 +2390,7 @@ CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y -CONFIG_MTD_RAM=m +# CONFIG_MTD_RAM is not set CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set # end of RAM/ROM/Flash chip drivers @@ -2334,7 +2401,7 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_INTEL_VR_NOR is not set -CONFIG_MTD_PLATRAM=m +# CONFIG_MTD_PLATRAM is not set # end of Mapping drivers for chip access # @@ -2347,7 +2414,9 @@ CONFIG_MTD_PLATRAM=m # CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set CONFIG_MTD_PHRAM=m -# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 CONFIG_MTD_BLOCK2MTD=m # @@ -2388,6 +2457,7 @@ CONFIG_MTD_NAND_ECC=y CONFIG_MTD_NAND_ECC_SW_HAMMING=y CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y CONFIG_MTD_NAND_ECC_SW_BCH=y +CONFIG_MTD_NAND_ECC_MXIC=y # end of ECC engine support # end of NAND @@ -2402,9 +2472,6 @@ CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y # CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y # CONFIG_MTD_SPI_NOR_SWP_KEEP is not set -CONFIG_SPI_INTEL_SPI=m -CONFIG_SPI_INTEL_SPI_PCI=m -CONFIG_SPI_INTEL_SPI_PLATFORM=m CONFIG_MTD_UBI=m CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 @@ -2433,6 +2500,7 @@ CONFIG_PNPACPI=y CONFIG_BLK_DEV=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_FD_RAWCMD is not set CONFIG_CDROM=m # CONFIG_PARIDE is not set CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m @@ -2448,11 +2516,9 @@ CONFIG_ZRAM_WRITEBACK=y # CONFIG_ZRAM_MEMORY_TRACKING is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_LOOP_MIN_COUNT=0 -CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_DRBD=m # CONFIG_DRBD_FAULT_INJECTION is not set CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_SX8=m CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 @@ -2464,7 +2530,7 @@ CONFIG_XEN_BLKDEV_FRONTEND=m CONFIG_XEN_BLKDEV_BACKEND=m CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_RBD=m -CONFIG_BLK_DEV_RSXX=m +CONFIG_BLK_DEV_UBLK=m CONFIG_BLK_DEV_RNBD=y CONFIG_BLK_DEV_RNBD_CLIENT=m CONFIG_BLK_DEV_RNBD_SERVER=m @@ -2472,14 +2538,17 @@ CONFIG_BLK_DEV_RNBD_SERVER=m # # NVME Support # -CONFIG_NVME_CORE=y -CONFIG_BLK_DEV_NVME=y +CONFIG_NVME_COMMON=m +CONFIG_NVME_CORE=m +CONFIG_BLK_DEV_NVME=m CONFIG_NVME_MULTIPATH=y +CONFIG_NVME_VERBOSE_ERRORS=y CONFIG_NVME_HWMON=y CONFIG_NVME_FABRICS=m CONFIG_NVME_RDMA=m CONFIG_NVME_FC=m CONFIG_NVME_TCP=m +CONFIG_NVME_AUTH=y CONFIG_NVME_TARGET=m CONFIG_NVME_TARGET_PASSTHRU=y CONFIG_NVME_TARGET_LOOP=m @@ -2487,6 +2556,7 @@ CONFIG_NVME_TARGET_RDMA=m CONFIG_NVME_TARGET_FC=m CONFIG_NVME_TARGET_FCLOOP=m CONFIG_NVME_TARGET_TCP=m +CONFIG_NVME_TARGET_AUTH=y # end of NVME Support # @@ -2550,7 +2620,9 @@ CONFIG_ALTERA_STAPL=m CONFIG_INTEL_MEI=m CONFIG_INTEL_MEI_ME=m CONFIG_INTEL_MEI_TXE=m +CONFIG_INTEL_MEI_GSC=m CONFIG_INTEL_MEI_HDCP=m +CONFIG_INTEL_MEI_PXP=m CONFIG_VMWARE_VMCI=m CONFIG_GENWQE=m CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=0 @@ -2565,6 +2637,7 @@ CONFIG_UACCE=m CONFIG_PVPANIC=y CONFIG_PVPANIC_MMIO=m CONFIG_PVPANIC_PCI=m +CONFIG_GP_PCI1XXXX=m # end of Misc devices # @@ -2572,6 +2645,7 @@ CONFIG_PVPANIC_PCI=m # CONFIG_SCSI_MOD=y CONFIG_RAID_ATTRS=m +CONFIG_SCSI_COMMON=y CONFIG_SCSI=y CONFIG_SCSI_DMA=y CONFIG_SCSI_NETLINK=y @@ -2584,6 +2658,7 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m CONFIG_CHR_DEV_SG=m +CONFIG_BLK_DEV_BSG=y CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_ENCLOSURE=m CONFIG_SCSI_CONSTANTS=y @@ -2635,7 +2710,6 @@ CONFIG_SCSI_MVSAS=m CONFIG_SCSI_MVSAS_DEBUG=y CONFIG_SCSI_MVSAS_TASKLET=y CONFIG_SCSI_MVUMI=m -CONFIG_SCSI_DPT_I2O=m CONFIG_SCSI_ADVANSYS=m CONFIG_SCSI_ARCMSR=m CONFIG_SCSI_ESAS2R=m @@ -2650,14 +2724,6 @@ CONFIG_SCSI_MPT3SAS_MAX_SGE=128 CONFIG_SCSI_MPT2SAS=m CONFIG_SCSI_MPI3MR=m CONFIG_SCSI_SMARTPQI=m -CONFIG_SCSI_UFSHCD=m -CONFIG_SCSI_UFSHCD_PCI=m -# CONFIG_SCSI_UFS_DWC_TC_PCI is not set -CONFIG_SCSI_UFSHCD_PLATFORM=m -CONFIG_SCSI_UFS_CDNS_PLATFORM=m -# CONFIG_SCSI_UFS_DWC_TC_PLATFORM is not set -CONFIG_SCSI_UFS_BSG=y -CONFIG_SCSI_UFS_CRYPTO=y CONFIG_SCSI_HPTIOP=m CONFIG_SCSI_BUSLOGIC=m CONFIG_SCSI_FLASHPOINT=y @@ -2738,6 +2804,7 @@ CONFIG_SATA_PMP=y CONFIG_SATA_AHCI=y CONFIG_SATA_MOBILE_LPM_POLICY=3 CONFIG_SATA_AHCI_PLATFORM=m +CONFIG_AHCI_DWC=m CONFIG_SATA_INIC162X=m CONFIG_SATA_ACARD_AHCI=m CONFIG_SATA_SIL24=m @@ -2757,7 +2824,6 @@ CONFIG_ATA_BMDMA=y CONFIG_ATA_PIIX=m CONFIG_SATA_DWC=m # CONFIG_SATA_DWC_OLD_DMA is not set -# CONFIG_SATA_DWC_DEBUG is not set CONFIG_SATA_MV=m CONFIG_SATA_NV=m CONFIG_SATA_PROMISE=m @@ -2869,12 +2935,13 @@ CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m CONFIG_DM_VERITY=m CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y -# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING is not set +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING=y CONFIG_DM_VERITY_FEC=y CONFIG_DM_SWITCH=m CONFIG_DM_LOG_WRITES=m CONFIG_DM_INTEGRITY=m CONFIG_DM_ZONED=m +CONFIG_DM_AUDIT=y CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -2931,6 +2998,7 @@ CONFIG_VXLAN=m CONFIG_GENEVE=m CONFIG_BAREUDP=m CONFIG_GTP=m +CONFIG_AMT=m CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y @@ -2955,9 +3023,6 @@ CONFIG_ATM_LANAI=m CONFIG_ATM_ENI=m # CONFIG_ATM_ENI_DEBUG is not set # CONFIG_ATM_ENI_TUNE_BURST is not set -CONFIG_ATM_FIRESTREAM=m -CONFIG_ATM_ZATM=m -# CONFIG_ATM_ZATM_DEBUG is not set CONFIG_ATM_NICSTAR=m # CONFIG_ATM_NICSTAR_USE_SUNI is not set # CONFIG_ATM_NICSTAR_USE_IDT77105 is not set @@ -2965,10 +3030,6 @@ CONFIG_ATM_IDT77252=m # CONFIG_ATM_IDT77252_DEBUG is not set # CONFIG_ATM_IDT77252_RCV_ALL is not set CONFIG_ATM_IDT77252_USE_SUNI=y -CONFIG_ATM_AMBASSADOR=m -# CONFIG_ATM_AMBASSADOR_DEBUG is not set -CONFIG_ATM_HORIZON=m -# CONFIG_ATM_HORIZON_DEBUG is not set CONFIG_ATM_IA=m # CONFIG_ATM_IA_DEBUG is not set CONFIG_ATM_FORE200E=m @@ -2995,16 +3056,14 @@ CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m CONFIG_NET_DSA_MT7530=m CONFIG_NET_DSA_MV88E6060=m CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m -CONFIG_NET_DSA_MICROCHIP_KSZ9477=m CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m -CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m -CONFIG_NET_DSA_MICROCHIP_KSZ8795=m -CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_MV88E6XXX_PTP=y CONFIG_NET_DSA_MSCC_SEVILLE=m CONFIG_NET_DSA_AR9331=m +CONFIG_NET_DSA_QCA8K=m CONFIG_NET_DSA_SJA1105=m CONFIG_NET_DSA_SJA1105_PTP=y CONFIG_NET_DSA_SJA1105_TAS=y @@ -3012,8 +3071,11 @@ CONFIG_NET_DSA_SJA1105_VL=y CONFIG_NET_DSA_XRS700X=m CONFIG_NET_DSA_XRS700X_I2C=m CONFIG_NET_DSA_XRS700X_MDIO=m -CONFIG_NET_DSA_QCA8K=m -CONFIG_NET_DSA_REALTEK_SMI=m +CONFIG_NET_DSA_REALTEK=m +# CONFIG_NET_DSA_REALTEK_MDIO is not set +# CONFIG_NET_DSA_REALTEK_SMI is not set +CONFIG_NET_DSA_REALTEK_RTL8365MB=m +CONFIG_NET_DSA_REALTEK_RTL8366RB=m CONFIG_NET_DSA_SMSC_LAN9303=m CONFIG_NET_DSA_SMSC_LAN9303_I2C=m CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m @@ -3051,12 +3113,16 @@ CONFIG_AMD_XGBE_HAVE_ECC=y CONFIG_NET_VENDOR_AQUANTIA=y CONFIG_AQTION=m CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ASIX=y +CONFIG_SPI_AX88796C=m +CONFIG_SPI_AX88796C_COMPRESSION=y CONFIG_NET_VENDOR_ATHEROS=y CONFIG_ATL2=m CONFIG_ATL1=m CONFIG_ATL1E=m CONFIG_ATL1C=m CONFIG_ALX=m +CONFIG_CX_ECAT=m CONFIG_NET_VENDOR_BROADCOM=y CONFIG_B44=m CONFIG_B44_PCI_AUTOSELECT=y @@ -3075,8 +3141,6 @@ CONFIG_BNXT_SRIOV=y CONFIG_BNXT_FLOWER_OFFLOAD=y CONFIG_BNXT_DCB=y CONFIG_BNXT_HWMON=y -CONFIG_NET_VENDOR_BROCADE=y -CONFIG_BNA=m CONFIG_NET_VENDOR_CADENCE=y CONFIG_MACB=m CONFIG_MACB_USE_HWSTAMP=y @@ -3104,7 +3168,8 @@ CONFIG_CHELSIO_TLS_DEVICE=m CONFIG_NET_VENDOR_CISCO=y CONFIG_ENIC=m CONFIG_NET_VENDOR_CORTINA=y -CONFIG_CX_ECAT=m +CONFIG_NET_VENDOR_DAVICOM=y +CONFIG_DM9051=m CONFIG_DNET=m CONFIG_NET_VENDOR_DEC=y CONFIG_NET_TULIP=y @@ -3115,7 +3180,6 @@ CONFIG_TULIP_MWI=y CONFIG_TULIP_MMIO=y CONFIG_TULIP_NAPI=y CONFIG_TULIP_NAPI_HW_MITIGATION=y -CONFIG_DE4X5=m CONFIG_WINBOND_840=m CONFIG_DM9102=m CONFIG_ULI526X=m @@ -3131,9 +3195,15 @@ CONFIG_BE2NET_BE2=y CONFIG_BE2NET_BE3=y CONFIG_BE2NET_LANCER=y CONFIG_BE2NET_SKYHAWK=y +CONFIG_NET_VENDOR_ENGLEDER=y +CONFIG_TSNEP=m +# CONFIG_TSNEP_SELFTESTS is not set CONFIG_NET_VENDOR_EZCHIP=y CONFIG_NET_VENDOR_FUJITSU=y CONFIG_PCMCIA_FMVJ18X=m +CONFIG_NET_VENDOR_FUNGIBLE=y +CONFIG_FUN_CORE=m +CONFIG_FUN_ETH=m CONFIG_NET_VENDOR_GOOGLE=y CONFIG_GVE=m CONFIG_NET_VENDOR_HUAWEI=y @@ -3161,11 +3231,17 @@ CONFIG_I40E_DCB=y CONFIG_IAVF=m CONFIG_I40EVF=m CONFIG_ICE=m +CONFIG_ICE_SWITCHDEV=y +CONFIG_ICE_HWTS=y CONFIG_FM10K=m CONFIG_IGC=m -CONFIG_NET_VENDOR_MICROSOFT=y -CONFIG_MICROSOFT_MANA=m +CONFIG_NET_VENDOR_WANGXUN=y +CONFIG_NGBE=m +CONFIG_TXGBE=m CONFIG_JME=m +CONFIG_NET_VENDOR_ADI=y +CONFIG_ADIN1110=m +CONFIG_NET_VENDOR_LITEX=y CONFIG_NET_VENDOR_MARVELL=y CONFIG_MVMDIO=m CONFIG_SKGE=m @@ -3173,6 +3249,7 @@ CONFIG_SKGE=m CONFIG_SKGE_GENESIS=y CONFIG_SKY2=m # CONFIG_SKY2_DEBUG is not set +CONFIG_OCTEON_EP=m CONFIG_PRESTERA=m CONFIG_PRESTERA_PCI=m CONFIG_NET_VENDOR_MELLANOX=y @@ -3182,7 +3259,6 @@ CONFIG_MLX4_CORE=m CONFIG_MLX4_DEBUG=y CONFIG_MLX4_CORE_GEN2=y CONFIG_MLX5_CORE=m -CONFIG_MLX5_ACCEL=y CONFIG_MLX5_FPGA=y CONFIG_MLX5_CORE_EN=y CONFIG_MLX5_EN_ARFS=y @@ -3195,11 +3271,8 @@ CONFIG_MLX5_TC_CT=y CONFIG_MLX5_TC_SAMPLE=y CONFIG_MLX5_CORE_EN_DCB=y CONFIG_MLX5_CORE_IPOIB=y -CONFIG_MLX5_FPGA_IPSEC=y -CONFIG_MLX5_IPSEC=y +CONFIG_MLX5_EN_MACSEC=y CONFIG_MLX5_EN_IPSEC=y -CONFIG_MLX5_FPGA_TLS=y -CONFIG_MLX5_TLS=y CONFIG_MLX5_EN_TLS=y CONFIG_MLX5_SW_STEERING=y CONFIG_MLX5_SF=y @@ -3225,24 +3298,24 @@ CONFIG_ENCX24J600=m CONFIG_LAN743X=m CONFIG_NET_VENDOR_MICROSEMI=y CONFIG_MSCC_OCELOT_SWITCH_LIB=m +CONFIG_NET_VENDOR_MICROSOFT=y +CONFIG_MICROSOFT_MANA=m CONFIG_NET_VENDOR_MYRI=y CONFIG_MYRI10GE=m CONFIG_MYRI10GE_DCA=y CONFIG_FEALNX=m +CONFIG_NET_VENDOR_NI=y +CONFIG_NI_XGE_MANAGEMENT_ENET=m CONFIG_NET_VENDOR_NATSEMI=y CONFIG_NATSEMI=m CONFIG_NS83820=m CONFIG_NET_VENDOR_NETERION=y CONFIG_S2IO=m -CONFIG_VXGE=m -# CONFIG_VXGE_DEBUG_TRACE_ALL is not set CONFIG_NET_VENDOR_NETRONOME=y CONFIG_NFP=m CONFIG_NFP_APP_FLOWER=y CONFIG_NFP_APP_ABM_NIC=y # CONFIG_NFP_DEBUG is not set -CONFIG_NET_VENDOR_NI=y -CONFIG_NI_XGE_MANAGEMENT_ENET=m CONFIG_NET_VENDOR_8390=y CONFIG_PCMCIA_AXNET=m CONFIG_NE2K_PCI=m @@ -3271,6 +3344,8 @@ CONFIG_QED_RDMA=y CONFIG_QED_ISCSI=y CONFIG_QED_FCOE=y CONFIG_QED_OOO=y +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_BNA=m CONFIG_NET_VENDOR_QUALCOMM=y CONFIG_QCOM_EMAC=m CONFIG_RMNET=m @@ -3291,6 +3366,11 @@ CONFIG_ROCKER=m CONFIG_NET_VENDOR_SAMSUNG=y CONFIG_SXGBE_ETH=m CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +CONFIG_SC92031=m +CONFIG_NET_VENDOR_SIS=y +CONFIG_SIS900=m +CONFIG_SIS190=m CONFIG_NET_VENDOR_SOLARFLARE=y CONFIG_SFC=m CONFIG_SFC_MTD=y @@ -3299,11 +3379,11 @@ CONFIG_SFC_SRIOV=y CONFIG_SFC_MCDI_LOGGING=y CONFIG_SFC_FALCON=m CONFIG_SFC_FALCON_MTD=y -CONFIG_NET_VENDOR_SILAN=y -CONFIG_SC92031=m -CONFIG_NET_VENDOR_SIS=y -CONFIG_SIS900=m -CONFIG_SIS190=m +CONFIG_SFC_SIENA=m +CONFIG_SFC_SIENA_MTD=y +CONFIG_SFC_SIENA_MCDI_MON=y +CONFIG_SFC_SIENA_SRIOV=y +CONFIG_SFC_SIENA_MCDI_LOGGING=y CONFIG_NET_VENDOR_SMSC=y CONFIG_PCMCIA_SMC91C92=m CONFIG_EPIC100=m @@ -3331,6 +3411,8 @@ CONFIG_TEHUTI=m CONFIG_NET_VENDOR_TI=y # CONFIG_TI_CPSW_PHY_SEL is not set CONFIG_TLAN=m +CONFIG_NET_VENDOR_VERTEXCOM=y +CONFIG_MSE102X=m CONFIG_NET_VENDOR_VIA=y CONFIG_VIA_RHINE=m CONFIG_VIA_RHINE_MMIO=y @@ -3365,6 +3447,7 @@ CONFIG_SFP=m # CONFIG_AMD_PHY=m CONFIG_ADIN_PHY=m +CONFIG_ADIN1100_PHY=m CONFIG_AQUANTIA_PHY=m CONFIG_AX88796B_PHY=m CONFIG_BROADCOM_PHY=m @@ -3373,6 +3456,7 @@ CONFIG_BCM7XXX_PHY=m CONFIG_BCM84881_PHY=m CONFIG_BCM87XX_PHY=m CONFIG_BCM_NET_PHYLIB=m +CONFIG_BCM_NET_PHYPTP=m CONFIG_CICADA_PHY=m CONFIG_CORTINA_PHY=m CONFIG_DAVICOM_PHY=m @@ -3383,6 +3467,7 @@ CONFIG_LSI_ET1011C_PHY=m CONFIG_MARVELL_PHY=m CONFIG_MARVELL_10G_PHY=m CONFIG_MARVELL_88X2222_PHY=m +CONFIG_MAXLINEAR_GPHY=m CONFIG_MEDIATEK_GE_PHY=m CONFIG_MICREL_PHY=m CONFIG_MICROCHIP_PHY=m @@ -3405,9 +3490,82 @@ CONFIG_DP83TC811_PHY=m CONFIG_DP83848_PHY=m CONFIG_DP83867_PHY=m CONFIG_DP83869_PHY=m +CONFIG_DP83TD510_PHY=m CONFIG_VITESSE_PHY=m CONFIG_XILINX_GMII2RGMII=m CONFIG_MICREL_KS8995MA=m +CONFIG_PSE_CONTROLLER=y +CONFIG_PSE_REGULATOR=m +CONFIG_CAN_DEV=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_NETLINK=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_RX_OFFLOAD=y +CONFIG_CAN_CAN327=m +CONFIG_CAN_JANZ_ICAN3=m +CONFIG_CAN_KVASER_PCIEFD=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +CONFIG_CAN_C_CAN_PCI=m +CONFIG_CAN_CC770=m +# CONFIG_CAN_CC770_ISA is not set +CONFIG_CAN_CC770_PLATFORM=m +CONFIG_CAN_CTUCANFD=m +CONFIG_CAN_CTUCANFD_PCI=m +CONFIG_CAN_IFI_CANFD=m +CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PCI=m +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_M_CAN_TCAN4X5X=m +CONFIG_CAN_PEAK_PCIEFD=m +CONFIG_CAN_SJA1000=m +CONFIG_CAN_EMS_PCI=m +# CONFIG_CAN_EMS_PCMCIA is not set +CONFIG_CAN_F81601=m +CONFIG_CAN_KVASER_PCI=m +CONFIG_CAN_PEAK_PCI=m +CONFIG_CAN_PEAK_PCIEC=y +CONFIG_CAN_PEAK_PCMCIA=m +CONFIG_CAN_PLX_PCI=m +# CONFIG_CAN_SJA1000_ISA is not set +CONFIG_CAN_SJA1000_PLATFORM=m +CONFIG_CAN_SOFTING=m +CONFIG_CAN_SOFTING_CS=m + +# +# CAN SPI interfaces +# +CONFIG_CAN_HI311X=m +CONFIG_CAN_MCP251X=m +CONFIG_CAN_MCP251XFD=m +# CONFIG_CAN_MCP251XFD_SANITY is not set +# end of CAN SPI interfaces + +# +# CAN USB interfaces +# +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB=m +CONFIG_CAN_ETAS_ES58X=m +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_MCBA_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m +# end of CAN USB interfaces + +# CONFIG_CAN_DEBUG_DEVICES is not set + +# +# MCTP Device Drivers +# +CONFIG_MCTP_SERIAL=m +CONFIG_MCTP_TRANSPORT_I2C=m +# end of MCTP Device Drivers + CONFIG_MDIO_DEVICE=m CONFIG_MDIO_BUS=m CONFIG_FWNODE_MDIO=m @@ -3431,6 +3589,7 @@ CONFIG_MDIO_THUNDER=m # CONFIG_PCS_XPCS=m CONFIG_PCS_LYNX=m +CONFIG_PCS_ALTERA_TSE=m # end of PCS device drivers CONFIG_PLIP=m @@ -3596,6 +3755,7 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y # CONFIG_B43LEGACY_PIO_MODE is not set CONFIG_BRCMUTIL=m CONFIG_BRCMSMAC=m +CONFIG_BRCMSMAC_LEDS=y CONFIG_BRCMFMAC=m CONFIG_BRCMFMAC_PROTO_BCDC=y CONFIG_BRCMFMAC_PROTO_MSGBUF=y @@ -3635,7 +3795,6 @@ CONFIG_IWLWIFI_LEDS=y CONFIG_IWLDVM=m CONFIG_IWLMVM=m CONFIG_IWLWIFI_OPMODE_MODULAR=y -# CONFIG_IWLWIFI_BCAST_FILTERING is not set # # Debugging Options @@ -3668,7 +3827,6 @@ CONFIG_P54_PCI=m CONFIG_P54_SPI=m # CONFIG_P54_SPI_DEFAULT_EEPROM is not set CONFIG_P54_LEDS=y -CONFIG_PRISM54=m CONFIG_WLAN_VENDOR_MARVELL=y CONFIG_LIBERTAS=m CONFIG_LIBERTAS_USB=m @@ -3707,12 +3865,17 @@ CONFIG_MT7663_USB_SDIO_COMMON=m CONFIG_MT7663U=m CONFIG_MT7663S=m CONFIG_MT7915E=m +CONFIG_MT7921_COMMON=m CONFIG_MT7921E=m +CONFIG_MT7921S=m +CONFIG_MT7921U=m CONFIG_WLAN_VENDOR_MICROCHIP=y CONFIG_WILC1000=m CONFIG_WILC1000_SDIO=m CONFIG_WILC1000_SPI=m # CONFIG_WILC1000_HW_OOB_INTR is not set +CONFIG_WLAN_VENDOR_PURELIFI=y +CONFIG_PLFXLC=m CONFIG_WLAN_VENDOR_RALINK=y CONFIG_RT2X00=m CONFIG_RT2400PCI=m @@ -3779,12 +3942,24 @@ CONFIG_RTW88_8723DE=m CONFIG_RTW88_8821CE=m CONFIG_RTW88_DEBUG=y CONFIG_RTW88_DEBUGFS=y +CONFIG_RTW89=m +CONFIG_RTW89_CORE=m +CONFIG_RTW89_PCI=m +CONFIG_RTW89_8852A=m +CONFIG_RTW89_8852C=m +CONFIG_RTW89_8852AE=m +CONFIG_RTW89_8852CE=m +CONFIG_RTW89_DEBUG=y +CONFIG_RTW89_DEBUGMSG=y +CONFIG_RTW89_DEBUGFS=y CONFIG_WLAN_VENDOR_RSI=y CONFIG_RSI_91X=m CONFIG_RSI_DEBUGFS=y CONFIG_RSI_SDIO=m CONFIG_RSI_USB=m CONFIG_RSI_COEX=y +CONFIG_WLAN_VENDOR_SILABS=y +CONFIG_WFX=m CONFIG_WLAN_VENDOR_ST=y CONFIG_CW1200=m CONFIG_CW1200_WLAN_SDIO=m @@ -3814,7 +3989,6 @@ CONFIG_VIRT_WIFI=m CONFIG_IEEE802154_DRIVERS=m CONFIG_IEEE802154_FAKELB=m CONFIG_IEEE802154_AT86RF230=m -# CONFIG_IEEE802154_AT86RF230_DEBUGFS is not set CONFIG_IEEE802154_MRF24J40=m CONFIG_IEEE802154_CC2520=m CONFIG_IEEE802154_ATUSB=m @@ -3828,10 +4002,13 @@ CONFIG_IEEE802154_HWSIM=m # Wireless WAN # CONFIG_WWAN=y +CONFIG_WWAN_DEBUGFS=y CONFIG_WWAN_HWSIM=m CONFIG_MHI_WWAN_CTRL=m +CONFIG_MHI_WWAN_MBIM=m CONFIG_RPMSG_WWAN_CTRL=m CONFIG_IOSM=m +CONFIG_MTK_T7XX=m # end of Wireless WAN CONFIG_XEN_NETDEV_FRONTEND=m @@ -3864,9 +4041,6 @@ CONFIG_MISDN_NETJET=m CONFIG_MISDN_HDLC=m CONFIG_MISDN_IPAC=m CONFIG_MISDN_ISAR=m -CONFIG_NVM=y -CONFIG_NVM_PBLK=m -# CONFIG_NVM_PBLK_DEBUG is not set # # Input device support @@ -3876,6 +4050,7 @@ CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_SPARSEKMAP=m CONFIG_INPUT_MATRIXKMAP=m +CONFIG_INPUT_VIVALDIFMAP=m # # Userland interfaces @@ -3915,6 +4090,7 @@ CONFIG_KEYBOARD_MCS=m CONFIG_KEYBOARD_MPR121=m CONFIG_KEYBOARD_NEWTON=m CONFIG_KEYBOARD_OPENCORES=m +CONFIG_KEYBOARD_PINEPHONE=m CONFIG_KEYBOARD_SAMSUNG=m CONFIG_KEYBOARD_STOWAWAY=m CONFIG_KEYBOARD_SUNKBD=m @@ -3924,6 +4100,7 @@ CONFIG_KEYBOARD_TWL4030=m CONFIG_KEYBOARD_XTKBD=m CONFIG_KEYBOARD_CROS_EC=m CONFIG_KEYBOARD_MTK_PMIC=m +CONFIG_KEYBOARD_CYPRESS_SF=m CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m CONFIG_MOUSE_PS2_ALPS=y @@ -3989,6 +4166,7 @@ CONFIG_JOYSTICK_PSXPAD_SPI_FF=y CONFIG_JOYSTICK_PXRC=m CONFIG_JOYSTICK_QWIIC=m CONFIG_JOYSTICK_FSIA6B=m +CONFIG_JOYSTICK_SENSEHAT=m CONFIG_INPUT_TABLET=y CONFIG_TABLET_USB_ACECAD=m CONFIG_TABLET_USB_AIPTEK=m @@ -4044,6 +4222,7 @@ CONFIG_TOUCHSCREEN_MMS114=m CONFIG_TOUCHSCREEN_MELFAS_MIP4=m CONFIG_TOUCHSCREEN_MSG2638=m CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_IMAGIS=m CONFIG_TOUCHSCREEN_INEXIO=m CONFIG_TOUCHSCREEN_MK712=m CONFIG_TOUCHSCREEN_PENMOUNT=m @@ -4098,6 +4277,7 @@ CONFIG_TOUCHSCREEN_SX8654=m CONFIG_TOUCHSCREEN_TPS6507X=m CONFIG_TOUCHSCREEN_ZET6223=m CONFIG_TOUCHSCREEN_ZFORCE=m +CONFIG_TOUCHSCREEN_COLIBRI_VF50=m CONFIG_TOUCHSCREEN_ROHM_BU21023=m CONFIG_TOUCHSCREEN_IQS5XX=m CONFIG_TOUCHSCREEN_ZINITIX=m @@ -4150,9 +4330,11 @@ CONFIG_INPUT_PCAP=m CONFIG_INPUT_ADXL34X=m CONFIG_INPUT_ADXL34X_I2C=m CONFIG_INPUT_ADXL34X_SPI=m +CONFIG_INPUT_IBM_PANEL=m CONFIG_INPUT_IMS_PCU=m CONFIG_INPUT_IQS269A=m CONFIG_INPUT_IQS626A=m +CONFIG_INPUT_IQS7222=m CONFIG_INPUT_CMA3000=m CONFIG_INPUT_CMA3000_I2C=m CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m @@ -4162,6 +4344,7 @@ CONFIG_INPUT_DRV260X_HAPTICS=m CONFIG_INPUT_DRV2665_HAPTICS=m CONFIG_INPUT_DRV2667_HAPTICS=m CONFIG_INPUT_RAVE_SP_PWRBUTTON=m +CONFIG_INPUT_RT5120_PWRKEY=m CONFIG_RMI4_CORE=m CONFIG_RMI4_I2C=m CONFIG_RMI4_SPI=m @@ -4244,6 +4427,7 @@ CONFIG_SERIAL_8250_DW=m CONFIG_SERIAL_8250_RT288X=y CONFIG_SERIAL_8250_LPSS=y CONFIG_SERIAL_8250_MID=y +CONFIG_SERIAL_8250_PERICOM=y # # Non-8250 serial port support @@ -4261,7 +4445,6 @@ CONFIG_SERIAL_SC16IS7XX_CORE=m CONFIG_SERIAL_SC16IS7XX=m CONFIG_SERIAL_SC16IS7XX_I2C=y CONFIG_SERIAL_SC16IS7XX_SPI=y -# CONFIG_SERIAL_BCM63XX is not set CONFIG_SERIAL_ALTERA_JTAGUART=m CONFIG_SERIAL_ALTERA_UART=m CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 @@ -4271,6 +4454,7 @@ CONFIG_SERIAL_ARC_NR_PORTS=1 CONFIG_SERIAL_RP2=m CONFIG_SERIAL_RP2_NR_UARTS=32 CONFIG_SERIAL_FSL_LPUART=m +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y CONFIG_SERIAL_FSL_LINFLEXUART=m CONFIG_SERIAL_MEN_Z135=m CONFIG_SERIAL_SPRD=m @@ -4289,6 +4473,7 @@ CONFIG_HVC_DRIVER=y CONFIG_HVC_IRQ=y CONFIG_HVC_XEN=y CONFIG_HVC_XEN_FRONTEND=y +CONFIG_RPMSG_TTY=m CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_CTRL_TTYPORT=y CONFIG_PRINTER=m @@ -4302,6 +4487,7 @@ CONFIG_IPMI_PLAT_DATA=y CONFIG_IPMI_DEVICE_INTERFACE=m CONFIG_IPMI_SI=m CONFIG_IPMI_SSIF=m +CONFIG_IPMI_IPMB=m CONFIG_IPMI_WATCHDOG=m CONFIG_IPMI_POWEROFF=m CONFIG_IPMB_DEVICE_INTERFACE=m @@ -4338,6 +4524,7 @@ CONFIG_TCG_TIS_CORE=m CONFIG_TCG_TIS=m CONFIG_TCG_TIS_SPI=m CONFIG_TCG_TIS_SPI_CR50=y +CONFIG_TCG_TIS_I2C=m CONFIG_TCG_TIS_I2C_CR50=m CONFIG_TCG_TIS_I2C_ATMEL=m CONFIG_TCG_TIS_I2C_INFINEON=m @@ -4356,11 +4543,10 @@ CONFIG_XILLYBUS_CLASS=m CONFIG_XILLYBUS=m CONFIG_XILLYBUS_PCIE=m CONFIG_XILLYUSB=m +CONFIG_RANDOM_TRUST_CPU=y +CONFIG_RANDOM_TRUST_BOOTLOADER=y # end of Character devices -# CONFIG_RANDOM_TRUST_CPU is not set -# CONFIG_RANDOM_TRUST_BOOTLOADER is not set - # # I2C support # @@ -4384,7 +4570,7 @@ CONFIG_I2C_MUX_MLXCPLD=m CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_SMBUS=m -CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOBIT=y CONFIG_I2C_ALGOPCA=m # @@ -4394,6 +4580,7 @@ CONFIG_I2C_ALGOPCA=m # # PC SMBus host controller drivers # +CONFIG_I2C_CCGX_UCSI=y CONFIG_I2C_ALI1535=m CONFIG_I2C_ALI1563=m CONFIG_I2C_ALI15X3=m @@ -4427,6 +4614,7 @@ CONFIG_I2C_CBUS_GPIO=m CONFIG_I2C_DESIGNWARE_CORE=y CONFIG_I2C_DESIGNWARE_SLAVE=y CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_DESIGNWARE_AMDPSP=y CONFIG_I2C_DESIGNWARE_BAYTRAIL=y CONFIG_I2C_DESIGNWARE_PCI=y CONFIG_I2C_EMEV2=m @@ -4445,6 +4633,7 @@ CONFIG_I2C_DIOLAN_U2C=m CONFIG_I2C_DLN2=m CONFIG_I2C_CP2615=m CONFIG_I2C_PARPORT=m +CONFIG_I2C_PCI1XXXX=m CONFIG_I2C_ROBOTFUZZ_OSIF=m CONFIG_I2C_TAOS_EVM=m CONFIG_I2C_TINY_USB=m @@ -4455,6 +4644,7 @@ CONFIG_I2C_VIPERBOARD=m # CONFIG_I2C_MLXCPLD=m CONFIG_I2C_CROS_EC_TUNNEL=m +CONFIG_I2C_VIRTIO=m # end of I2C Hardware Bus support CONFIG_I2C_STUB=m @@ -4489,7 +4679,12 @@ CONFIG_SPI_DW_MMIO=m CONFIG_SPI_DLN2=m CONFIG_SPI_NXP_FLEXSPI=m CONFIG_SPI_GPIO=m +CONFIG_SPI_INTEL=m +CONFIG_SPI_INTEL_PCI=m +CONFIG_SPI_INTEL_PLATFORM=m CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MICROCHIP_CORE=m +CONFIG_SPI_MICROCHIP_CORE_QSPI=m # CONFIG_SPI_LANTIQ_SSC is not set CONFIG_SPI_OC_TINY=m CONFIG_SPI_PXA2XX=m @@ -4539,6 +4734,7 @@ CONFIG_PPS_CLIENT_GPIO=m # PTP clock support # CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_DP83640_PHY=m CONFIG_PTP_1588_CLOCK_INES=m CONFIG_PTP_1588_CLOCK_KVM=m @@ -4553,12 +4749,23 @@ CONFIG_PINMUX=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set -CONFIG_PINCTRL_AMD=m +CONFIG_PINCTRL_AMD=y +CONFIG_PINCTRL_CY8C95X0=m CONFIG_PINCTRL_DA9062=m CONFIG_PINCTRL_MCP23S08_I2C=m CONFIG_PINCTRL_MCP23S08_SPI=m CONFIG_PINCTRL_MCP23S08=m CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_MADERA=m +CONFIG_PINCTRL_CS47L15=y +CONFIG_PINCTRL_CS47L35=y +CONFIG_PINCTRL_CS47L85=y +CONFIG_PINCTRL_CS47L90=y +CONFIG_PINCTRL_CS47L92=y + +# +# Intel pinctrl drivers +# CONFIG_PINCTRL_BAYTRAIL=y CONFIG_PINCTRL_CHERRYVIEW=y CONFIG_PINCTRL_LYNXPOINT=y @@ -4575,20 +4782,16 @@ CONFIG_PINCTRL_ICELAKE=y CONFIG_PINCTRL_JASPERLAKE=y CONFIG_PINCTRL_LAKEFIELD=y CONFIG_PINCTRL_LEWISBURG=y +CONFIG_PINCTRL_METEORLAKE=y CONFIG_PINCTRL_SUNRISEPOINT=y CONFIG_PINCTRL_TIGERLAKE=y +# end of Intel pinctrl drivers # # Renesas pinctrl drivers # # end of Renesas pinctrl drivers -CONFIG_PINCTRL_MADERA=m -CONFIG_PINCTRL_CS47L15=y -CONFIG_PINCTRL_CS47L35=y -CONFIG_PINCTRL_CS47L85=y -CONFIG_PINCTRL_CS47L90=y -CONFIG_PINCTRL_CS47L92=y CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_GPIO_ACPI=y @@ -4628,7 +4831,6 @@ CONFIG_GPIO_WS16C48=m # # I2C GPIO expanders # -CONFIG_GPIO_ADP5588=m CONFIG_GPIO_MAX7300=m CONFIG_GPIO_MAX732X=m CONFIG_GPIO_PCA953X=m @@ -4659,7 +4861,7 @@ CONFIG_GPIO_TPS65086=m CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y CONFIG_GPIO_TPS65912=m -CONFIG_GPIO_TPS68470=y +CONFIG_GPIO_TPS68470=m CONFIG_GPIO_TQMX86=m CONFIG_GPIO_TWL4030=m CONFIG_GPIO_TWL6040=m @@ -4701,6 +4903,8 @@ CONFIG_GPIO_VIPERBOARD=m # CONFIG_GPIO_AGGREGATOR=m CONFIG_GPIO_MOCKUP=m +CONFIG_GPIO_VIRTIO=m +CONFIG_GPIO_SIM=m # end of Virtual GPIO drivers CONFIG_W1=m @@ -4745,11 +4949,13 @@ CONFIG_POWER_RESET=y CONFIG_POWER_RESET_ATC260X=m CONFIG_POWER_RESET_MT6323=y CONFIG_POWER_RESET_RESTART=y +CONFIG_POWER_RESET_TPS65086=y CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_POWER_SUPPLY_HWMON=y CONFIG_PDA_POWER=m CONFIG_GENERIC_ADC_BATTERY=m +CONFIG_IP5XXX_POWER=m CONFIG_MAX8925_POWER=m CONFIG_WM831X_BACKUP=m CONFIG_WM831X_POWER=m @@ -4762,6 +4968,7 @@ CONFIG_BATTERY_DS2760=m CONFIG_BATTERY_DS2780=m CONFIG_BATTERY_DS2781=m CONFIG_BATTERY_DS2782=m +# CONFIG_BATTERY_SAMSUNG_SDI is not set CONFIG_BATTERY_SBS=m CONFIG_CHARGER_SBS=m CONFIG_MANAGER_SBS=m @@ -4796,9 +5003,12 @@ CONFIG_CHARGER_LT3651=m CONFIG_CHARGER_LTC4162L=m CONFIG_CHARGER_MAX14577=m CONFIG_CHARGER_MAX77693=m +CONFIG_CHARGER_MAX77976=m CONFIG_CHARGER_MAX8997=m CONFIG_CHARGER_MAX8998=m CONFIG_CHARGER_MP2629=m +CONFIG_CHARGER_MT6360=m +CONFIG_CHARGER_MT6370=m CONFIG_CHARGER_BQ2415X=m CONFIG_CHARGER_BQ24190=m CONFIG_CHARGER_BQ24257=m @@ -4814,10 +5024,12 @@ CONFIG_BATTERY_GOLDFISH=m CONFIG_BATTERY_RT5033=m CONFIG_CHARGER_RT9455=m CONFIG_CHARGER_CROS_USBPD=m +CONFIG_CHARGER_CROS_PCHG=m CONFIG_CHARGER_BD99954=m CONFIG_CHARGER_WILCO=m CONFIG_BATTERY_SURFACE=m CONFIG_CHARGER_SURFACE=m +CONFIG_BATTERY_UG3105=m CONFIG_HWMON=y CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set @@ -4830,7 +5042,6 @@ CONFIG_SENSORS_ABITUGURU3=m CONFIG_SENSORS_AD7314=m CONFIG_SENSORS_AD7414=m CONFIG_SENSORS_AD7418=m -CONFIG_SENSORS_ADM1021=m CONFIG_SENSORS_ADM1025=m CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1029=m @@ -4845,6 +5056,7 @@ CONFIG_SENSORS_ADT7462=m CONFIG_SENSORS_ADT7470=m CONFIG_SENSORS_ADT7475=m CONFIG_SENSORS_AHT10=m +CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m CONFIG_SENSORS_AS370=m CONFIG_SENSORS_ASC7621=m CONFIG_SENSORS_AXI_FAN_CONTROL=m @@ -4853,7 +5065,6 @@ CONFIG_SENSORS_K10TEMP=m CONFIG_SENSORS_FAM15H_POWER=m CONFIG_SENSORS_APPLESMC=m CONFIG_SENSORS_ASB100=m -CONFIG_SENSORS_ASPEED=m CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_CORSAIR_CPRO=m CONFIG_SENSORS_CORSAIR_PSU=m @@ -4861,6 +5072,7 @@ CONFIG_SENSORS_DRIVETEMP=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m CONFIG_SENSORS_DELL_SMM=m +CONFIG_I8K=y CONFIG_SENSORS_DA9052_ADC=m CONFIG_SENSORS_DA9055=m CONFIG_SENSORS_I5K_AMB=m @@ -4904,9 +5116,10 @@ CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m CONFIG_SENSORS_MAX31730=m +CONFIG_SENSORS_MAX31760=m +CONFIG_SENSORS_MAX6620=m CONFIG_SENSORS_MAX6621=m CONFIG_SENSORS_MAX6639=m -CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m @@ -4937,11 +5150,14 @@ CONFIG_SENSORS_PC87360=m CONFIG_SENSORS_PC87427=m CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_NCT6683=m +CONFIG_SENSORS_NCT6775_CORE=m CONFIG_SENSORS_NCT6775=m +CONFIG_SENSORS_NCT6775_I2C=m CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m CONFIG_SENSORS_NZXT_KRAKEN2=m +CONFIG_SENSORS_NZXT_SMART2=m CONFIG_SENSORS_PCF8591=m CONFIG_PMBUS=m CONFIG_SENSORS_PMBUS=m @@ -4949,6 +5165,7 @@ CONFIG_SENSORS_ADM1266=m CONFIG_SENSORS_ADM1275=m CONFIG_SENSORS_BEL_PFE=m CONFIG_SENSORS_BPA_RS600=m +CONFIG_SENSORS_DELTA_AHE50DC_FAN=m CONFIG_SENSORS_FSP_3Y=m CONFIG_SENSORS_IBM_CFFPS=m CONFIG_SENSORS_DPS920AB=m @@ -4956,9 +5173,12 @@ CONFIG_SENSORS_INSPUR_IPSPS=m CONFIG_SENSORS_IR35221=m CONFIG_SENSORS_IR36021=m CONFIG_SENSORS_IR38064=m +CONFIG_SENSORS_IR38064_REGULATOR=y CONFIG_SENSORS_IRPS5401=m CONFIG_SENSORS_ISL68137=m CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LM25066_REGULATOR=y +CONFIG_SENSORS_LT7182S=m CONFIG_SENSORS_LTC2978=m # CONFIG_SENSORS_LTC2978_REGULATOR is not set CONFIG_SENSORS_LTC3815=m @@ -4972,27 +5192,36 @@ CONFIG_SENSORS_MAX34440=m CONFIG_SENSORS_MAX8688=m CONFIG_SENSORS_MP2888=m CONFIG_SENSORS_MP2975=m +CONFIG_SENSORS_MP5023=m CONFIG_SENSORS_PIM4328=m +CONFIG_SENSORS_PLI1209BC=m +CONFIG_SENSORS_PLI1209BC_REGULATOR=y CONFIG_SENSORS_PM6764TR=m CONFIG_SENSORS_PXE1610=m CONFIG_SENSORS_Q54SJ108A2=m CONFIG_SENSORS_STPDDC60=m CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_TPS53679=m +CONFIG_SENSORS_TPS546D24=m CONFIG_SENSORS_UCD9000=m CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_XDPE152=m CONFIG_SENSORS_XDPE122=m +CONFIG_SENSORS_XDPE122_REGULATOR=y CONFIG_SENSORS_ZL6100=m CONFIG_SENSORS_SBTSI=m +CONFIG_SENSORS_SBRMI=m CONFIG_SENSORS_SHT15=m CONFIG_SENSORS_SHT21=m CONFIG_SENSORS_SHT3x=m CONFIG_SENSORS_SHT4x=m CONFIG_SENSORS_SHTC1=m CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SY7636A=m CONFIG_SENSORS_DME1737=m CONFIG_SENSORS_EMC1403=m CONFIG_SENSORS_EMC2103=m +CONFIG_SENSORS_EMC2305=m CONFIG_SENSORS_EMC6W201=m CONFIG_SENSORS_SMSC47M1=m CONFIG_SENSORS_SMSC47M192=m @@ -5008,6 +5237,7 @@ CONFIG_SENSORS_ADS7871=m CONFIG_SENSORS_AMC6821=m CONFIG_SENSORS_INA209=m CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_INA238=m CONFIG_SENSORS_INA3221=m CONFIG_SENSORS_TC74=m CONFIG_SENSORS_THMC50=m @@ -5016,6 +5246,7 @@ CONFIG_SENSORS_TMP103=m CONFIG_SENSORS_TMP108=m CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_TMP464=m CONFIG_SENSORS_TMP513=m CONFIG_SENSORS_VIA_CPUTEMP=m CONFIG_SENSORS_VIA686A=m @@ -5042,6 +5273,8 @@ CONFIG_SENSORS_INTEL_M10_BMC_HWMON=m # CONFIG_SENSORS_ACPI_POWER=m CONFIG_SENSORS_ATK0110=m +CONFIG_SENSORS_ASUS_WMI=m +CONFIG_SENSORS_ASUS_EC=m CONFIG_THERMAL=y CONFIG_THERMAL_NETLINK=y # CONFIG_THERMAL_STATISTICS is not set @@ -5081,6 +5314,8 @@ CONFIG_PROC_THERMAL_MMIO_RAPL=m CONFIG_INTEL_BXT_PMIC_THERMAL=m CONFIG_INTEL_PCH_THERMAL=m CONFIG_INTEL_TCC_COOLING=m +CONFIG_INTEL_MENLOW=m +CONFIG_INTEL_HFI_THERMAL=y # end of Intel thermal drivers CONFIG_GENERIC_ADC_THERMAL=m @@ -5090,7 +5325,7 @@ CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y CONFIG_WATCHDOG_OPEN_TIMEOUT=0 CONFIG_WATCHDOG_SYSFS=y -CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT=y +# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set # # Watchdog Pretimeout Governors @@ -5130,6 +5365,7 @@ CONFIG_ADVANTECH_WDT=m CONFIG_ALIM1535_WDT=m CONFIG_ALIM7101_WDT=m CONFIG_EBC_C384_WDT=m +CONFIG_EXAR_WDT=m CONFIG_F71808E_WDT=m CONFIG_SP5100_TCO=m CONFIG_SBC_FITPC2_WATCHDOG=m @@ -5163,6 +5399,7 @@ CONFIG_SBC_EPX_C3_WATCHDOG=m CONFIG_INTEL_MEI_WDT=m CONFIG_NI903X_WDT=m CONFIG_NIC7018_WDT=m +CONFIG_SIEMENS_SIMATIC_IPC_WDT=m CONFIG_MEN_A21_WDT=m CONFIG_XEN_WDT=m @@ -5248,7 +5485,6 @@ CONFIG_MFD_INTEL_LPSS=m CONFIG_MFD_INTEL_LPSS_ACPI=m CONFIG_MFD_INTEL_LPSS_PCI=m CONFIG_MFD_INTEL_PMC_BXT=m -CONFIG_MFD_INTEL_PMT=m CONFIG_MFD_IQS62X=m CONFIG_MFD_JANZ_CMODIO=m CONFIG_MFD_KEMPLD=m @@ -5263,8 +5499,10 @@ CONFIG_MFD_MAX8925=y CONFIG_MFD_MAX8997=y CONFIG_MFD_MAX8998=y CONFIG_MFD_MT6360=m +CONFIG_MFD_MT6370=m CONFIG_MFD_MT6397=m CONFIG_MFD_MENF21BMC=m +CONFIG_MFD_OCELOT=m CONFIG_EZX_PCAP=y CONFIG_MFD_VIPERBOARD=m CONFIG_MFD_RETU=m @@ -5272,11 +5510,14 @@ CONFIG_MFD_PCF50633=m CONFIG_PCF50633_ADC=m CONFIG_PCF50633_GPIO=m CONFIG_UCB1400_CORE=m +CONFIG_MFD_SY7636A=m CONFIG_MFD_RDC321X=m CONFIG_MFD_RT4831=m CONFIG_MFD_RT5033=m +CONFIG_MFD_RT5120=m CONFIG_MFD_RC5T583=y CONFIG_MFD_SI476X_CORE=m +CONFIG_MFD_SIMPLE_MFD_I2C=m CONFIG_MFD_SM501=m CONFIG_MFD_SM501_GPIO=y CONFIG_MFD_SKY81452=m @@ -5297,7 +5538,6 @@ CONFIG_MFD_TPS65910=y CONFIG_MFD_TPS65912=m CONFIG_MFD_TPS65912_I2C=m CONFIG_MFD_TPS65912_SPI=m -CONFIG_MFD_TPS80031=y CONFIG_TWL4030_CORE=y CONFIG_MFD_TWL4030_AUDIO=y CONFIG_TWL6040_CORE=y @@ -5373,6 +5613,7 @@ CONFIG_REGULATOR_MAX8925=m CONFIG_REGULATOR_MAX8952=m CONFIG_REGULATOR_MAX8997=m CONFIG_REGULATOR_MAX8998=m +CONFIG_REGULATOR_MAX20086=m CONFIG_REGULATOR_MAX77693=m CONFIG_REGULATOR_MAX77826=m CONFIG_REGULATOR_MC13XXX_CORE=m @@ -5381,9 +5622,12 @@ CONFIG_REGULATOR_MC13892=m CONFIG_REGULATOR_MP8859=m CONFIG_REGULATOR_MT6311=m CONFIG_REGULATOR_MT6323=m +CONFIG_REGULATOR_MT6331=m +CONFIG_REGULATOR_MT6332=m CONFIG_REGULATOR_MT6358=m CONFIG_REGULATOR_MT6359=m CONFIG_REGULATOR_MT6360=m +CONFIG_REGULATOR_MT6370=m CONFIG_REGULATOR_MT6397=m CONFIG_REGULATOR_PALMAS=m CONFIG_REGULATOR_PCA9450=m @@ -5393,16 +5637,21 @@ CONFIG_REGULATOR_PV88060=m CONFIG_REGULATOR_PV88080=m CONFIG_REGULATOR_PV88090=m CONFIG_REGULATOR_PWM=m -CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=m CONFIG_REGULATOR_RC5T583=m CONFIG_REGULATOR_RT4801=m CONFIG_REGULATOR_RT4831=m CONFIG_REGULATOR_RT5033=m +CONFIG_REGULATOR_RT5120=m +CONFIG_REGULATOR_RT5190A=m +CONFIG_REGULATOR_RT5759=m CONFIG_REGULATOR_RT6160=m CONFIG_REGULATOR_RT6245=m +CONFIG_REGULATOR_RTQ2134=m CONFIG_REGULATOR_RTMV20=m +CONFIG_REGULATOR_RTQ6752=m CONFIG_REGULATOR_SKY81452=m CONFIG_REGULATOR_SLG51000=m +CONFIG_REGULATOR_SY7636A=m CONFIG_REGULATOR_TPS51632=m CONFIG_REGULATOR_TPS6105X=m CONFIG_REGULATOR_TPS62360=m @@ -5415,52 +5664,55 @@ CONFIG_REGULATOR_TPS6524X=m CONFIG_REGULATOR_TPS6586X=m CONFIG_REGULATOR_TPS65910=m CONFIG_REGULATOR_TPS65912=m -CONFIG_REGULATOR_TPS80031=m +CONFIG_REGULATOR_TPS68470=m CONFIG_REGULATOR_TWL4030=m CONFIG_REGULATOR_WM831X=m CONFIG_REGULATOR_WM8350=m CONFIG_REGULATOR_WM8400=m CONFIG_REGULATOR_WM8994=m CONFIG_RC_CORE=y -CONFIG_RC_MAP=m -CONFIG_LIRC=y CONFIG_BPF_LIRC_MODE2=y +CONFIG_LIRC=y +CONFIG_RC_MAP=m CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_NEC_DECODER=m CONFIG_IR_RC5_DECODER=m CONFIG_IR_RC6_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_SONY_DECODER=m +CONFIG_IR_RCMM_DECODER=m CONFIG_IR_SANYO_DECODER=m CONFIG_IR_SHARP_DECODER=m -CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_SONY_DECODER=m CONFIG_IR_XMP_DECODER=m -CONFIG_IR_IMON_DECODER=m -CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y -CONFIG_RC_ATI_REMOTE=m CONFIG_IR_ENE=m +CONFIG_IR_FINTEK=m +CONFIG_IR_IGORPLUGUSB=m +CONFIG_IR_IGUANA=m CONFIG_IR_IMON=m CONFIG_IR_IMON_RAW=m -CONFIG_IR_MCEUSB=m CONFIG_IR_ITE_CIR=m -CONFIG_IR_FINTEK=m +CONFIG_IR_MCEUSB=m CONFIG_IR_NUVOTON=m CONFIG_IR_REDRAT3=m +CONFIG_IR_SERIAL=m +CONFIG_IR_SERIAL_TRANSMITTER=y CONFIG_IR_STREAMZAP=m -CONFIG_IR_WINBOND_CIR=m -CONFIG_IR_IGORPLUGUSB=m -CONFIG_IR_IGUANA=m +CONFIG_IR_TOY=m CONFIG_IR_TTUSBIR=m +CONFIG_IR_WINBOND_CIR=m +CONFIG_RC_ATI_REMOTE=m CONFIG_RC_LOOPBACK=m -CONFIG_IR_SERIAL=m -CONFIG_IR_SERIAL_TRANSMITTER=y -CONFIG_IR_SIR=m CONFIG_RC_XBOX_DVD=m -CONFIG_IR_TOY=m CONFIG_CEC_CORE=m CONFIG_CEC_NOTIFIER=y CONFIG_CEC_PIN=y + +# +# CEC support +# CONFIG_MEDIA_CEC_RC=y # CONFIG_CEC_PIN_ERROR_INJ is not set CONFIG_MEDIA_CEC_SUPPORT=y @@ -5471,6 +5723,8 @@ CONFIG_CEC_SECO=m CONFIG_CEC_SECO_RC=y CONFIG_USB_PULSE8_CEC=m CONFIG_USB_RAINSHADOW_CEC=m +# end of CEC support + CONFIG_MEDIA_SUPPORT=m CONFIG_MEDIA_SUPPORT_FILTER=y CONFIG_MEDIA_SUBDRV_AUTOSELECT=y @@ -5494,7 +5748,6 @@ CONFIG_DVB_CORE=m # # Video4Linux options # -CONFIG_VIDEO_V4L2=m CONFIG_VIDEO_V4L2_I2C=y CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_VIDEO_ADV_DEBUG is not set @@ -5514,10 +5767,6 @@ CONFIG_VIDEOBUF_VMALLOC=m # CONFIG_MEDIA_CONTROLLER_DVB=y CONFIG_MEDIA_CONTROLLER_REQUEST_API=y - -# -# Please notice that the enabled Media controller Request API is EXPERIMENTAL -# # end of Media controller options # @@ -5538,17 +5787,16 @@ CONFIG_DVB_DYNAMIC_MINORS=y # # Drivers filtered as selected at 'Filter media drivers' # + +# +# Media drivers +# CONFIG_MEDIA_USB_SUPPORT=y # # Webcam devices # -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -CONFIG_USB_GL860=m CONFIG_USB_GSPCA_BENQ=m CONFIG_USB_GSPCA_CONEX=m CONFIG_USB_GSPCA_CPIA1=m @@ -5573,13 +5821,13 @@ CONFIG_USB_GSPCA_SN9C2028=m CONFIG_USB_GSPCA_SN9C20X=m CONFIG_USB_GSPCA_SONIXB=m CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA1528=m CONFIG_USB_GSPCA_SPCA500=m CONFIG_USB_GSPCA_SPCA501=m CONFIG_USB_GSPCA_SPCA505=m CONFIG_USB_GSPCA_SPCA506=m CONFIG_USB_GSPCA_SPCA508=m CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SPCA1528=m CONFIG_USB_GSPCA_SQ905=m CONFIG_USB_GSPCA_SQ905C=m CONFIG_USB_GSPCA_SQ930X=m @@ -5595,29 +5843,31 @@ CONFIG_USB_GSPCA_VC032X=m CONFIG_USB_GSPCA_VICAM=m CONFIG_USB_GSPCA_XIRLINK_CIT=m CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_GL860=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m CONFIG_USB_PWC=m # CONFIG_USB_PWC_DEBUG is not set CONFIG_USB_PWC_INPUT_EVDEV=y -CONFIG_VIDEO_CPIA2=m -CONFIG_USB_ZR364XX=m -CONFIG_USB_STKWEBCAM=m CONFIG_USB_S2255=m CONFIG_VIDEO_USBTV=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y # # Analog TV USB devices # +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_LOADER=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +CONFIG_VIDEO_HDPVR=m CONFIG_VIDEO_PVRUSB2=m CONFIG_VIDEO_PVRUSB2_SYSFS=y CONFIG_VIDEO_PVRUSB2_DVB=y # CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_HDPVR=m CONFIG_VIDEO_STK1160_COMMON=m CONFIG_VIDEO_STK1160=m -CONFIG_VIDEO_GO7007=m -CONFIG_VIDEO_GO7007_USB=m -CONFIG_VIDEO_GO7007_LOADER=m -CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m # # Analog/digital TV USB devices @@ -5629,41 +5879,13 @@ CONFIG_VIDEO_CX231XX=m CONFIG_VIDEO_CX231XX_RC=y CONFIG_VIDEO_CX231XX_ALSA=m CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_VIDEO_TM6000=m -CONFIG_VIDEO_TM6000_ALSA=m -CONFIG_VIDEO_TM6000_DVB=m # # Digital TV USB devices # -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_DIB3000MC=m -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_CXUSB_ANALOG=y -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_AS102=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set CONFIG_DVB_USB_V2=m CONFIG_DVB_USB_AF9015=m CONFIG_DVB_USB_AF9035=m @@ -5671,19 +5893,44 @@ CONFIG_DVB_USB_ANYSEE=m CONFIG_DVB_USB_AU6610=m CONFIG_DVB_USB_AZ6007=m CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_DVBSKY=m CONFIG_DVB_USB_EC168=m CONFIG_DVB_USB_GL861=m CONFIG_DVB_USB_LME2510=m CONFIG_DVB_USB_MXL111SF=m CONFIG_DVB_USB_RTL28XXU=m -CONFIG_DVB_USB_DVBSKY=m CONFIG_DVB_USB_ZD1301=m +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_CXUSB_ANALOG=y +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIB3000MC=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_SMS_USB_DRV=m CONFIG_DVB_TTUSB_BUDGET=m CONFIG_DVB_TTUSB_DEC=m -CONFIG_SMS_USB_DRV=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set -CONFIG_DVB_AS102=m # # Webcam, TV (analog/digital) USB devices @@ -5698,27 +5945,25 @@ CONFIG_MEDIA_PCI_SUPPORT=y # # Media capture support # -CONFIG_VIDEO_MEYE=m CONFIG_VIDEO_SOLO6X10=m CONFIG_VIDEO_TW5864=m CONFIG_VIDEO_TW68=m CONFIG_VIDEO_TW686X=m +# CONFIG_VIDEO_ZORAN is not set # # Media capture/analog TV support # +CONFIG_VIDEO_DT3155=m CONFIG_VIDEO_IVTV=m CONFIG_VIDEO_IVTV_ALSA=m -CONFIG_VIDEO_FB_IVTV=m -# CONFIG_VIDEO_FB_IVTV_FORCE_PAT is not set -CONFIG_VIDEO_HEXIUM_GEMINI=m -CONFIG_VIDEO_HEXIUM_ORION=m -CONFIG_VIDEO_MXB=m -CONFIG_VIDEO_DT3155=m +# CONFIG_VIDEO_FB_IVTV is not set # # Media capture/analog/hybrid TV support # +CONFIG_VIDEO_BT848=m +CONFIG_DVB_BT8XX=m CONFIG_VIDEO_CX18=m CONFIG_VIDEO_CX18_ALSA=m CONFIG_VIDEO_CX23885=m @@ -5732,8 +5977,6 @@ CONFIG_VIDEO_CX88_DVB=m CONFIG_VIDEO_CX88_ENABLE_VP3054=y CONFIG_VIDEO_CX88_VP3054=m CONFIG_VIDEO_CX88_MPEG=m -CONFIG_VIDEO_BT848=m -CONFIG_DVB_BT8XX=m CONFIG_VIDEO_SAA7134=m CONFIG_VIDEO_SAA7134_ALSA=m CONFIG_VIDEO_SAA7134_RC=y @@ -5744,93 +5987,154 @@ CONFIG_VIDEO_SAA7164=m # # Media digital TV PCI Adapters # -CONFIG_DVB_BUDGET_CORE=m -CONFIG_DVB_BUDGET=m -CONFIG_DVB_BUDGET_CI=m -CONFIG_DVB_BUDGET_AV=m CONFIG_DVB_B2C2_FLEXCOP_PCI=m # CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set -CONFIG_DVB_PLUTO2=m +CONFIG_DVB_DDBRIDGE=m +# CONFIG_DVB_DDBRIDGE_MSIENABLE is not set CONFIG_DVB_DM1105=m -CONFIG_DVB_PT1=m -CONFIG_DVB_PT3=m CONFIG_MANTIS_CORE=m CONFIG_DVB_MANTIS=m CONFIG_DVB_HOPPER=m +CONFIG_DVB_NETUP_UNIDVB=m CONFIG_DVB_NGENE=m -CONFIG_DVB_DDBRIDGE=m -# CONFIG_DVB_DDBRIDGE_MSIENABLE is not set +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_PT1=m +CONFIG_DVB_PT3=m CONFIG_DVB_SMIPCIE=m -CONFIG_DVB_NETUP_UNIDVB=m CONFIG_VIDEO_IPU3_CIO2=m CONFIG_CIO2_BRIDGE=y -CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_ADAPTERS=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_SAA7706H=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_RADIO_SI4713=m +CONFIG_RADIO_SI476X=m CONFIG_RADIO_TEA575X=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_TEF6862=m +CONFIG_RADIO_WL1273=m +CONFIG_USB_DSBR=m +CONFIG_USB_KEENE=m +CONFIG_USB_MA901=m +CONFIG_USB_MR800=m +CONFIG_USB_RAREMONO=m CONFIG_RADIO_SI470X=m CONFIG_USB_SI470X=m CONFIG_I2C_SI470X=m -CONFIG_RADIO_SI4713=m CONFIG_USB_SI4713=m CONFIG_PLATFORM_SI4713=m CONFIG_I2C_SI4713=m -CONFIG_RADIO_SI476X=m -CONFIG_USB_MR800=m -CONFIG_USB_DSBR=m -CONFIG_RADIO_MAXIRADIO=m -CONFIG_RADIO_SHARK=m -CONFIG_RADIO_SHARK2=m -CONFIG_USB_KEENE=m -CONFIG_USB_RAREMONO=m -CONFIG_USB_MA901=m -CONFIG_RADIO_TEA5764=m -CONFIG_RADIO_SAA7706H=m -CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m CONFIG_RADIO_WL128X=m -CONFIG_MEDIA_COMMON_OPTIONS=y +CONFIG_MEDIA_PLATFORM_DRIVERS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_DVB_PLATFORM_DRIVERS=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m # -# common driver options +# Allegro DVT media platform drivers +# + +# +# Amlogic media platform drivers +# + +# +# Amphion drivers +# + +# +# Aspeed media platform drivers +# +CONFIG_VIDEO_ASPEED=m + +# +# Atmel media platform drivers +# + +# +# Cadence media platform drivers # -CONFIG_VIDEO_CX2341X=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_TTPCI_EEPROM=m -CONFIG_CYPRESS_FIRMWARE=m -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_V4L2=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_DMA_CONTIG=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEOBUF2_DMA_SG=m -CONFIG_VIDEOBUF2_DVB=m -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_VIDEO_SAA7146=m -CONFIG_VIDEO_SAA7146_VV=m -CONFIG_SMS_SIANO_MDTV=m -CONFIG_SMS_SIANO_RC=y -# CONFIG_SMS_SIANO_DEBUGFS is not set -CONFIG_VIDEO_V4L2_TPG=m -CONFIG_V4L_PLATFORM_DRIVERS=y -CONFIG_VIDEO_CAFE_CCIC=m -CONFIG_VIDEO_CADENCE=y CONFIG_VIDEO_CADENCE_CSI2RX=m CONFIG_VIDEO_CADENCE_CSI2TX=m -CONFIG_VIDEO_ASPEED=m -CONFIG_V4L_MEM2MEM_DRIVERS=y -CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m -CONFIG_DVB_PLATFORM_DRIVERS=y + +# +# Chips&Media media platform drivers +# + +# +# Intel media platform drivers +# + +# +# Marvell media platform drivers +# +CONFIG_VIDEO_CAFE_CCIC=m + +# +# Mediatek media platform drivers +# + +# +# NVidia media platform drivers +# + +# +# NXP media platform drivers +# + +# +# Qualcomm media platform drivers +# + +# +# Renesas media platform drivers +# + +# +# Rockchip media platform drivers +# + +# +# Samsung media platform drivers +# + +# +# STMicroelectronics media platform drivers +# + +# +# Sunxi media platform drivers +# + +# +# Texas Instruments drivers +# + +# +# Verisilicon media platform drivers +# + +# +# VIA media platform drivers +# + +# +# Xilinx media platform drivers +# # # MMC/SDIO DVB adapters # CONFIG_SMS_SDIO_DRV=m CONFIG_V4L_TEST_DRIVERS=y +CONFIG_VIDEO_VIM2M=m +CONFIG_VIDEO_VICODEC=m CONFIG_VIDEO_VIMC=m CONFIG_VIDEO_VIVID=m CONFIG_VIDEO_VIVID_CEC=y CONFIG_VIDEO_VIVID_MAX_DEVS=64 -CONFIG_VIDEO_VIM2M=m -CONFIG_VIDEO_VICODEC=m CONFIG_DVB_TEST_DRIVERS=y CONFIG_DVB_VIDTV=m @@ -5839,6 +6143,27 @@ CONFIG_DVB_VIDTV=m # CONFIG_DVB_FIREDTV=m CONFIG_DVB_FIREDTV_INPUT=y +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_TTPCI_EEPROM=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y +# CONFIG_SMS_SIANO_DEBUGFS is not set +CONFIG_VIDEO_V4L2_TPG=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_V4L2=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=m +CONFIG_VIDEOBUF2_DVB=m # end of Media drivers CONFIG_MEDIA_HIDE_ANCILLARY_SUBDRV=y @@ -5854,46 +6179,14 @@ CONFIG_MEDIA_ATTACH=y CONFIG_VIDEO_IR_I2C=m # -# audio, video and radio I2C drivers auto-selected by 'Autoselect ancillary drivers' -# -CONFIG_VIDEO_TVAUDIO=m -CONFIG_VIDEO_TDA7432=m -CONFIG_VIDEO_TDA9840=m -CONFIG_VIDEO_TEA6415C=m -CONFIG_VIDEO_TEA6420=m -CONFIG_VIDEO_MSP3400=m -CONFIG_VIDEO_CS3308=m -CONFIG_VIDEO_CS5345=m -CONFIG_VIDEO_CS53L32A=m -CONFIG_VIDEO_UDA1342=m -CONFIG_VIDEO_WM8775=m -CONFIG_VIDEO_WM8739=m -CONFIG_VIDEO_VP27SMPX=m -CONFIG_VIDEO_SONY_BTF_MPX=m -CONFIG_VIDEO_SAA6588=m -CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_TVP5150=m -CONFIG_VIDEO_TW2804=m -CONFIG_VIDEO_TW9903=m -CONFIG_VIDEO_TW9906=m - -# -# Video and audio decoders -# -CONFIG_VIDEO_SAA717X=m -CONFIG_VIDEO_CX25840=m -CONFIG_VIDEO_SAA7127=m -CONFIG_VIDEO_UPD64031A=m -CONFIG_VIDEO_UPD64083=m -CONFIG_VIDEO_SAA6752HS=m -CONFIG_VIDEO_M52790=m - -# # Camera sensor devices # CONFIG_VIDEO_APTINA_PLL=m CONFIG_VIDEO_CCS_PLL=m +CONFIG_VIDEO_AR0521=m CONFIG_VIDEO_HI556=m +CONFIG_VIDEO_HI846=m +CONFIG_VIDEO_HI847=m CONFIG_VIDEO_IMX208=m CONFIG_VIDEO_IMX214=m CONFIG_VIDEO_IMX219=m @@ -5902,7 +6195,22 @@ CONFIG_VIDEO_IMX274=m CONFIG_VIDEO_IMX290=m CONFIG_VIDEO_IMX319=m CONFIG_VIDEO_IMX355=m +CONFIG_VIDEO_MAX9271_LIB=m +CONFIG_VIDEO_MT9M001=m +CONFIG_VIDEO_MT9M032=m +CONFIG_VIDEO_MT9M111=m +CONFIG_VIDEO_MT9P031=m +CONFIG_VIDEO_MT9T001=m +CONFIG_VIDEO_MT9T112=m +CONFIG_VIDEO_MT9V011=m +CONFIG_VIDEO_MT9V032=m +CONFIG_VIDEO_MT9V111=m +CONFIG_VIDEO_NOON010PC30=m +CONFIG_VIDEO_OG01A1B=m CONFIG_VIDEO_OV02A10=m +CONFIG_VIDEO_OV08D10=m +CONFIG_VIDEO_OV13858=m +CONFIG_VIDEO_OV13B10=m CONFIG_VIDEO_OV2640=m CONFIG_VIDEO_OV2659=m CONFIG_VIDEO_OV2680=m @@ -5910,45 +6218,34 @@ CONFIG_VIDEO_OV2685=m CONFIG_VIDEO_OV2740=m CONFIG_VIDEO_OV5647=m CONFIG_VIDEO_OV5648=m -CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV5670=m CONFIG_VIDEO_OV5675=m +CONFIG_VIDEO_OV5693=m CONFIG_VIDEO_OV5695=m +CONFIG_VIDEO_OV6650=m CONFIG_VIDEO_OV7251=m -CONFIG_VIDEO_OV772X=m CONFIG_VIDEO_OV7640=m CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OV772X=m CONFIG_VIDEO_OV7740=m CONFIG_VIDEO_OV8856=m CONFIG_VIDEO_OV8865=m CONFIG_VIDEO_OV9640=m CONFIG_VIDEO_OV9650=m CONFIG_VIDEO_OV9734=m -CONFIG_VIDEO_OV13858=m -CONFIG_VIDEO_VS6624=m -CONFIG_VIDEO_MT9M001=m -CONFIG_VIDEO_MT9M032=m -CONFIG_VIDEO_MT9M111=m -CONFIG_VIDEO_MT9P031=m -CONFIG_VIDEO_MT9T001=m -CONFIG_VIDEO_MT9T112=m -CONFIG_VIDEO_MT9V011=m -CONFIG_VIDEO_MT9V032=m -CONFIG_VIDEO_MT9V111=m -CONFIG_VIDEO_SR030PC30=m -CONFIG_VIDEO_NOON010PC30=m -CONFIG_VIDEO_M5MOLS=m -CONFIG_VIDEO_MAX9271_LIB=m CONFIG_VIDEO_RDACM20=m CONFIG_VIDEO_RDACM21=m CONFIG_VIDEO_RJ54N1=m -CONFIG_VIDEO_S5K6AA=m -CONFIG_VIDEO_S5K6A3=m +CONFIG_VIDEO_S5C73M3=m CONFIG_VIDEO_S5K4ECGX=m CONFIG_VIDEO_S5K5BAF=m +CONFIG_VIDEO_S5K6A3=m +CONFIG_VIDEO_S5K6AA=m +CONFIG_VIDEO_SR030PC30=m +CONFIG_VIDEO_VS6624=m CONFIG_VIDEO_CCS=m CONFIG_VIDEO_ET8EK8=m -CONFIG_VIDEO_S5C73M3=m +CONFIG_VIDEO_M5MOLS=m # end of Camera sensor devices # @@ -5970,6 +6267,38 @@ CONFIG_VIDEO_LM3646=m # end of Flash devices # +# audio, video and radio I2C drivers auto-selected by 'Autoselect ancillary drivers' +# +CONFIG_VIDEO_CS3308=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_SONY_BTF_MPX=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_UDA1342=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_SAA6752HS=m +CONFIG_VIDEO_M52790=m + +# # SPI I2C drivers auto-selected by 'Autoselect ancillary drivers' # @@ -5977,6 +6306,7 @@ CONFIG_VIDEO_LM3646=m # Media SPI Adapters # CONFIG_CXD2880_SPI_DRV=m +CONFIG_VIDEO_GS1662=m # end of Media SPI Adapters CONFIG_MEDIA_TUNER=m @@ -5984,42 +6314,42 @@ CONFIG_MEDIA_TUNER=m # # Tuner drivers auto-selected by 'Autoselect ancillary drivers' # +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_M88RS6000T=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL301RF=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QM1D1B0004=m +CONFIG_MEDIA_TUNER_QM1D1C0042=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_SI2157=m CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_TDA18218=m CONFIG_MEDIA_TUNER_TDA18250=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m CONFIG_MEDIA_TUNER_TDA9887=m CONFIG_MEDIA_TUNER_TEA5761=m CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2063=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_TUA9001=m CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m CONFIG_MEDIA_TUNER_XC4000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_MEDIA_TUNER_FC0011=m -CONFIG_MEDIA_TUNER_FC0012=m -CONFIG_MEDIA_TUNER_FC0013=m -CONFIG_MEDIA_TUNER_TDA18212=m -CONFIG_MEDIA_TUNER_E4000=m -CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_M88RS6000T=m -CONFIG_MEDIA_TUNER_TUA9001=m -CONFIG_MEDIA_TUNER_SI2157=m -CONFIG_MEDIA_TUNER_IT913X=m -CONFIG_MEDIA_TUNER_R820T=m -CONFIG_MEDIA_TUNER_MXL301RF=m -CONFIG_MEDIA_TUNER_QM1D1C0042=m -CONFIG_MEDIA_TUNER_QM1D1B0004=m +CONFIG_MEDIA_TUNER_XC5000=m # # DVB Frontend drivers auto-selected by 'Autoselect ancillary drivers' @@ -6028,116 +6358,112 @@ CONFIG_MEDIA_TUNER_QM1D1B0004=m # # Multistandard (satellite) frontends # +CONFIG_DVB_M88DS3103=m +CONFIG_DVB_MXL5XX=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV6111=m -CONFIG_DVB_MXL5XX=m -CONFIG_DVB_M88DS3103=m # # Multistandard (cable + terrestrial) frontends # CONFIG_DVB_DRXK=m -CONFIG_DVB_TDA18271C2DD=m -CONFIG_DVB_SI2165=m CONFIG_DVB_MN88472=m CONFIG_DVB_MN88473=m +CONFIG_DVB_SI2165=m +CONFIG_DVB_TDA18271C2DD=m # # DVB-S (satellite) frontends # CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24117=m +CONFIG_DVB_CX24120=m CONFIG_DVB_CX24123=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10036=m -CONFIG_DVB_ZL10039=m CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m +CONFIG_DVB_SI21XX=m CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA8083=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_TDA10071=m CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA8083=m CONFIG_DVB_TDA826X=m -CONFIG_DVB_TUA6100=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_CX24117=m -CONFIG_DVB_CX24120=m -CONFIG_DVB_SI21XX=m CONFIG_DVB_TS2020=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_MB86A16=m -CONFIG_DVB_TDA10071=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m # # DVB-T (terrestrial) frontends # -CONFIG_DVB_SP887X=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_AS102_FE=m CONFIG_DVB_CX22700=m CONFIG_DVB_CX22702=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_L64781=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_CXD2841ER=m CONFIG_DVB_DIB3000MB=m CONFIG_DVB_DIB3000MC=m CONFIG_DVB_DIB7000M=m CONFIG_DVB_DIB7000P=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m +CONFIG_DVB_DRXD=m CONFIG_DVB_EC100=m -CONFIG_DVB_STV0367=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_CXD2841ER=m +CONFIG_DVB_GP8PSK_FE=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT6000=m CONFIG_DVB_RTL2830=m CONFIG_DVB_RTL2832=m CONFIG_DVB_SI2168=m -CONFIG_DVB_AS102_FE=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m CONFIG_DVB_ZD1301_DEMOD=m -CONFIG_DVB_GP8PSK_FE=m +CONFIG_DVB_ZL10353=m # # DVB-C (cable) frontends # -CONFIG_DVB_VES1820=m +CONFIG_DVB_STV0297=m CONFIG_DVB_TDA10021=m CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m +CONFIG_DVB_VES1820=m # # ATSC (North American/Korean Terrestrial/Cable DTV) frontends # -CONFIG_DVB_NXT200X=m -CONFIG_DVB_OR51211=m -CONFIG_DVB_OR51132=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LG2160=m CONFIG_DVB_LGDT3305=m CONFIG_DVB_LGDT3306A=m -CONFIG_DVB_LG2160=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_MXL692=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m CONFIG_DVB_S5H1409=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_AU8522_DTV=m -CONFIG_DVB_AU8522_V4L=m CONFIG_DVB_S5H1411=m -CONFIG_DVB_MXL692=m # # ISDB-T (terrestrial) frontends # -CONFIG_DVB_S921=m CONFIG_DVB_DIB8000=m CONFIG_DVB_MB86A20S=m +CONFIG_DVB_S921=m # # ISDB-S (satellite) & ISDB-T (terrestrial) frontends @@ -6154,23 +6480,23 @@ CONFIG_DVB_TUNER_DIB0090=m # # SEC control devices for DVB-S # -CONFIG_DVB_DRX39XYJ=m -CONFIG_DVB_LNBH25=m -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m +CONFIG_DVB_A8293=m +CONFIG_DVB_AF9033=m +CONFIG_DVB_ASCOT2E=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_HELENE=m +CONFIG_DVB_HORUS3A=m CONFIG_DVB_ISL6405=m CONFIG_DVB_ISL6421=m CONFIG_DVB_ISL6423=m -CONFIG_DVB_A8293=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_TDA665x=m CONFIG_DVB_IX2505V=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_LNBH25=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m CONFIG_DVB_M88RS2000=m -CONFIG_DVB_AF9033=m -CONFIG_DVB_HORUS3A=m -CONFIG_DVB_ASCOT2E=m -CONFIG_DVB_HELENE=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_DRX39XYJ=m # # Common Interface (EN50221) controller drivers @@ -6187,30 +6513,34 @@ CONFIG_DVB_DUMMY_FE=m # # Graphics support # -CONFIG_AGP=m +CONFIG_APERTURE_HELPERS=y +CONFIG_AGP=y CONFIG_AGP_AMD64=m CONFIG_AGP_INTEL=m CONFIG_AGP_SIS=m CONFIG_AGP_VIA=m CONFIG_INTEL_GTT=m -CONFIG_VGA_ARB=y -CONFIG_VGA_ARB_MAX_GPUS=10 CONFIG_VGA_SWITCHEROO=y -CONFIG_DRM=m +CONFIG_DRM=y CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y -CONFIG_DRM_DP_AUX_CHARDEV=y -# CONFIG_DRM_DEBUG_SELFTEST is not set -CONFIG_DRM_KMS_HELPER=m +# CONFIG_DRM_DEBUG_MM is not set +CONFIG_DRM_USE_DYNAMIC_DEBUG=y +CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_DISPLAY_HELPER=m +CONFIG_DRM_DISPLAY_DP_HELPER=y +CONFIG_DRM_DISPLAY_HDCP_HELPER=y +CONFIG_DRM_DISPLAY_HDMI_HELPER=y +CONFIG_DRM_DP_AUX_CHARDEV=y CONFIG_DRM_DP_CEC=y CONFIG_DRM_TTM=m +CONFIG_DRM_BUDDY=m CONFIG_DRM_VRAM_HELPER=m CONFIG_DRM_TTM_HELPER=m -CONFIG_DRM_GEM_CMA_HELPER=y -CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_GEM_DMA_HELPER=m CONFIG_DRM_GEM_SHMEM_HELPER=y CONFIG_DRM_SCHED=m @@ -6268,6 +6598,7 @@ CONFIG_DRM_I915_COMPRESS_ERROR=y CONFIG_DRM_I915_USERPTR=y CONFIG_DRM_I915_GVT=y CONFIG_DRM_I915_GVT_KVMGT=m +CONFIG_DRM_I915_PXP=y CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 CONFIG_DRM_I915_FENCE_TIMEOUT=10000 CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250 @@ -6280,12 +6611,12 @@ CONFIG_DRM_VGEM=m CONFIG_DRM_VKMS=m CONFIG_DRM_VMWGFX=m CONFIG_DRM_VMWGFX_FBCON=y +CONFIG_DRM_VMWGFX_MKSSTATS=y CONFIG_DRM_GMA500=m CONFIG_DRM_UDL=m CONFIG_DRM_AST=m CONFIG_DRM_MGAG200=m CONFIG_DRM_QXL=m -CONFIG_DRM_BOCHS=m CONFIG_DRM_VIRTIO_GPU=m CONFIG_DRM_PANEL=y @@ -6293,6 +6624,7 @@ CONFIG_DRM_PANEL=y # Display Panels # CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_PANEL_WIDECHIPS_WS2401=m # end of Display Panels CONFIG_DRM_BRIDGE=y @@ -6306,10 +6638,13 @@ CONFIG_DRM_ANALOGIX_DP=m # end of Display Interface Bridges # CONFIG_DRM_ETNAVIV is not set +CONFIG_DRM_BOCHS=m CONFIG_DRM_CIRRUS_QEMU=m CONFIG_DRM_GM12U320=m -CONFIG_DRM_SIMPLEDRM=m +CONFIG_DRM_PANEL_MIPI_DBI=m +CONFIG_DRM_SIMPLEDRM=y CONFIG_TINYDRM_HX8357D=m +CONFIG_TINYDRM_ILI9163=m CONFIG_TINYDRM_ILI9225=m CONFIG_TINYDRM_ILI9341=m CONFIG_TINYDRM_ILI9486=m @@ -6321,9 +6656,14 @@ CONFIG_DRM_XEN=y CONFIG_DRM_XEN_FRONTEND=m CONFIG_DRM_VBOXVIDEO=m CONFIG_DRM_GUD=m +CONFIG_DRM_SSD130X=m +CONFIG_DRM_SSD130X_I2C=m +CONFIG_DRM_SSD130X_SPI=m CONFIG_DRM_HYPERV=m # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y +CONFIG_DRM_NOMODESET=y +CONFIG_DRM_PRIVACY_SCREEN=y # # Frame buffer Devices @@ -6331,19 +6671,18 @@ CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y CONFIG_FB_CMDLINE=y CONFIG_FB_NOTIFY=y CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y -CONFIG_FB_BOOT_VESA_SUPPORT=y +# CONFIG_FIRMWARE_EDID is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SYS_FILLRECT=m -CONFIG_FB_SYS_COPYAREA=m -CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_FOPS=y CONFIG_FB_DEFERRED_IO=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set # # Frame buffer hardware drivers @@ -6355,7 +6694,7 @@ CONFIG_FB_TILEBLITTING=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set -CONFIG_FB_UVESA=m +# CONFIG_FB_UVESA is not set CONFIG_FB_VESA=y CONFIG_FB_EFI=y # CONFIG_FB_N411 is not set @@ -6388,11 +6727,10 @@ CONFIG_FB_EFI=y # CONFIG_FB_UDL is not set # CONFIG_FB_IBM_GXT4500 is not set # CONFIG_FB_VIRTUAL is not set -CONFIG_XEN_FBDEV_FRONTEND=m +# CONFIG_XEN_FBDEV_FRONTEND is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set -CONFIG_FB_HYPERV=m -CONFIG_FB_SIMPLE=y +# CONFIG_FB_HYPERV is not set # CONFIG_FB_SSD1307 is not set # CONFIG_FB_SM712 is not set # end of Frame buffer Devices @@ -6420,6 +6758,7 @@ CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_DA903X=m CONFIG_BACKLIGHT_DA9052=m CONFIG_BACKLIGHT_MAX8925=m +CONFIG_BACKLIGHT_MT6370=m CONFIG_BACKLIGHT_APPLE=m CONFIG_BACKLIGHT_QCOM_WLED=m CONFIG_BACKLIGHT_RT4831=m @@ -6456,6 +6795,7 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=80 CONFIG_DUMMY_CONSOLE_ROWS=25 CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y @@ -6491,10 +6831,12 @@ CONFIG_SND_MAX_CARDS=32 CONFIG_SND_PROC_FS=y CONFIG_SND_VERBOSE_PROCFS=y CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_CTL_FAST_LOOKUP=y CONFIG_SND_DEBUG=y # CONFIG_SND_DEBUG_VERBOSE is not set # CONFIG_SND_PCM_XRUN_DEBUG is not set -# CONFIG_SND_CTL_VALIDATION is not set +CONFIG_SND_CTL_INPUT_VALIDATION=y +# CONFIG_SND_CTL_DEBUG is not set # CONFIG_SND_JACK_INJECTION_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_DMA_SGBUF=y @@ -6610,12 +6952,17 @@ CONFIG_SND_HDA_RECONFIG=y CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_INPUT_BEEP_MODE=0 CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_SCODEC_CS35L41=m +CONFIG_SND_HDA_CS_DSP_CONTROLS=m +CONFIG_SND_HDA_SCODEC_CS35L41_I2C=m +CONFIG_SND_HDA_SCODEC_CS35L41_SPI=m CONFIG_SND_HDA_CODEC_REALTEK=m CONFIG_SND_HDA_CODEC_ANALOG=m CONFIG_SND_HDA_CODEC_SIGMATEL=m CONFIG_SND_HDA_CODEC_VIA=m CONFIG_SND_HDA_CODEC_HDMI=m CONFIG_SND_HDA_CODEC_CIRRUS=m +CONFIG_SND_HDA_CODEC_CS8409=m CONFIG_SND_HDA_CODEC_CONEXANT=m CONFIG_SND_HDA_CODEC_CA0110=m CONFIG_SND_HDA_CODEC_CA0132=m @@ -6636,7 +6983,7 @@ CONFIG_SND_HDA_PREALLOC_SIZE=0 CONFIG_SND_INTEL_NHLT=y CONFIG_SND_INTEL_DSP_CONFIG=m CONFIG_SND_INTEL_SOUNDWIRE_ACPI=m -CONFIG_SND_INTEL_BYT_PREFER_SOF=y +# CONFIG_SND_INTEL_BYT_PREFER_SOF is not set CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m @@ -6680,10 +7027,29 @@ CONFIG_SND_SOC_ADI_AXI_SPDIF=m CONFIG_SND_SOC_AMD_ACP=m CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH=m CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m +CONFIG_SND_SOC_AMD_ST_ES8336_MACH=m CONFIG_SND_SOC_AMD_ACP3x=m CONFIG_SND_SOC_AMD_RV_RT5682_MACH=m CONFIG_SND_SOC_AMD_RENOIR=m CONFIG_SND_SOC_AMD_RENOIR_MACH=m +CONFIG_SND_SOC_AMD_ACP5x=m +CONFIG_SND_SOC_AMD_VANGOGH_MACH=m +CONFIG_SND_SOC_AMD_ACP6x=m +CONFIG_SND_SOC_AMD_YC_MACH=m +CONFIG_SND_AMD_ACP_CONFIG=m +CONFIG_SND_SOC_AMD_ACP_COMMON=m +CONFIG_SND_SOC_AMD_ACP_PDM=m +CONFIG_SND_SOC_AMD_ACP_I2S=m +CONFIG_SND_SOC_AMD_ACP_PCM=m +CONFIG_SND_SOC_AMD_ACP_PCI=m +CONFIG_SND_AMD_ASOC_RENOIR=m +CONFIG_SND_AMD_ASOC_REMBRANDT=m +CONFIG_SND_SOC_AMD_MACH_COMMON=m +CONFIG_SND_SOC_AMD_LEGACY_MACH=m +CONFIG_SND_SOC_AMD_SOF_MACH=m +CONFIG_SND_SOC_AMD_RPL_ACP6x=m +CONFIG_SND_SOC_AMD_PS=m +CONFIG_SND_SOC_AMD_PS_MACH=m CONFIG_SND_ATMEL_SOC=m # CONFIG_SND_BCM63XX_I2S_WHISTLER is not set CONFIG_SND_DESIGNWARE_I2S=m @@ -6736,10 +7102,35 @@ CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK=m CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC=y CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON=m CONFIG_SND_SOC_ACPI_INTEL_MATCH=m +CONFIG_SND_SOC_INTEL_AVS=m + +# +# Intel AVS Machine drivers +# + +# +# Available DSP configurations +# +CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219=m +CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC=m +CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO=m +CONFIG_SND_SOC_INTEL_AVS_MACH_I2S_TEST=m +CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A=m +CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373=m +CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT274=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT286=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT298=m +CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682=m +CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567=m +# end of Intel AVS Machine drivers + CONFIG_SND_SOC_INTEL_MACH=y CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES=y CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON=m CONFIG_SND_SOC_INTEL_SOF_MAXIM_COMMON=m +CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON=m +CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON=m CONFIG_SND_SOC_INTEL_HASWELL_MACH=m CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH=m CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH=m @@ -6774,9 +7165,12 @@ CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH=m CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH=m CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH=m CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH=m +CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH=m +CONFIG_SND_SOC_INTEL_SOF_NAU8825_MACH=m CONFIG_SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH=m CONFIG_SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH=m CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH=m +CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH=m CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH=m CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH=m CONFIG_SND_SOC_MTK_BTCVSD=m @@ -6785,9 +7179,16 @@ CONFIG_SND_SOC_SOF_PCI_DEV=m CONFIG_SND_SOC_SOF_PCI=m CONFIG_SND_SOC_SOF_ACPI=m CONFIG_SND_SOC_SOF_ACPI_DEV=m -# CONFIG_SND_SOC_SOF_DEBUG_PROBES is not set +CONFIG_SND_SOC_SOF_DEBUG_PROBES=m +CONFIG_SND_SOC_SOF_CLIENT=m CONFIG_SND_SOC_SOF=m CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE=y +CONFIG_SND_SOC_SOF_IPC3=y +CONFIG_SND_SOC_SOF_INTEL_IPC4=y +CONFIG_SND_SOC_SOF_AMD_TOPLEVEL=m +CONFIG_SND_SOC_SOF_AMD_COMMON=m +CONFIG_SND_SOC_SOF_AMD_RENOIR=m +CONFIG_SND_SOC_SOF_AMD_REMBRANDT=m CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL=y CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC=m CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP=m @@ -6795,6 +7196,8 @@ CONFIG_SND_SOC_SOF_INTEL_COMMON=m CONFIG_SND_SOC_SOF_BAYTRAIL=m # CONFIG_SND_SOC_SOF_BROADWELL is not set CONFIG_SND_SOC_SOF_MERRIFIELD=m +# CONFIG_SND_SOC_SOF_SKYLAKE is not set +# CONFIG_SND_SOC_SOF_KABYLAKE is not set CONFIG_SND_SOC_SOF_INTEL_APL=m CONFIG_SND_SOC_SOF_APOLLOLAKE=m CONFIG_SND_SOC_SOF_GEMINILAKE=m @@ -6809,12 +7212,14 @@ CONFIG_SND_SOC_SOF_INTEL_TGL=m CONFIG_SND_SOC_SOF_TIGERLAKE=m CONFIG_SND_SOC_SOF_ELKHARTLAKE=m CONFIG_SND_SOC_SOF_ALDERLAKE=m +CONFIG_SND_SOC_SOF_INTEL_MTL=m +CONFIG_SND_SOC_SOF_METEORLAKE=m CONFIG_SND_SOC_SOF_HDA_COMMON=m CONFIG_SND_SOC_SOF_HDA_LINK=y CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=y -# CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 is not set CONFIG_SND_SOC_SOF_HDA_LINK_BASELINE=m CONFIG_SND_SOC_SOF_HDA=m +CONFIG_SND_SOC_SOF_HDA_PROBES=m CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE=m CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE=m CONFIG_SND_SOC_SOF_XTENSA=m @@ -6851,6 +7256,7 @@ CONFIG_SND_SOC_ADAU7118_HW=m CONFIG_SND_SOC_ADAU7118_I2C=m CONFIG_SND_SOC_AK4104=m CONFIG_SND_SOC_AK4118=m +CONFIG_SND_SOC_AK4375=m CONFIG_SND_SOC_AK4458=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_AK4613=m @@ -6858,6 +7264,7 @@ CONFIG_SND_SOC_AK4642=m CONFIG_SND_SOC_AK5386=m CONFIG_SND_SOC_AK5558=m CONFIG_SND_SOC_ALC5623=m +CONFIG_SND_SOC_AW8738=m CONFIG_SND_SOC_BD28623=m # CONFIG_SND_SOC_BT_SCO is not set CONFIG_SND_SOC_CROS_EC_CODEC=m @@ -6866,12 +7273,22 @@ CONFIG_SND_SOC_CS35L33=m CONFIG_SND_SOC_CS35L34=m CONFIG_SND_SOC_CS35L35=m CONFIG_SND_SOC_CS35L36=m +CONFIG_SND_SOC_CS35L41_LIB=m +CONFIG_SND_SOC_CS35L41=m +CONFIG_SND_SOC_CS35L41_SPI=m +CONFIG_SND_SOC_CS35L41_I2C=m +CONFIG_SND_SOC_CS35L45_TABLES=m +CONFIG_SND_SOC_CS35L45=m +CONFIG_SND_SOC_CS35L45_SPI=m +CONFIG_SND_SOC_CS35L45_I2C=m +CONFIG_SND_SOC_CS42L42_CORE=m CONFIG_SND_SOC_CS42L42=m CONFIG_SND_SOC_CS42L51=m CONFIG_SND_SOC_CS42L51_I2C=m CONFIG_SND_SOC_CS42L52=m CONFIG_SND_SOC_CS42L56=m CONFIG_SND_SOC_CS42L73=m +CONFIG_SND_SOC_CS42L83=m CONFIG_SND_SOC_CS4234=m CONFIG_SND_SOC_CS4265=m CONFIG_SND_SOC_CS4270=m @@ -6892,12 +7309,15 @@ CONFIG_SND_SOC_HDMI_CODEC=m CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m CONFIG_SND_SOC_ES8316=m +CONFIG_SND_SOC_ES8326=m CONFIG_SND_SOC_ES8328=m CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_ES8328_SPI=m CONFIG_SND_SOC_GTM601=m CONFIG_SND_SOC_HDAC_HDMI=m CONFIG_SND_SOC_HDAC_HDA=m +CONFIG_SND_SOC_HDA=m +CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_INNO_RK3036=m CONFIG_SND_SOC_MAX98088=m CONFIG_SND_SOC_MAX98090=m @@ -6905,10 +7325,12 @@ CONFIG_SND_SOC_MAX98357A=m CONFIG_SND_SOC_MAX98504=m CONFIG_SND_SOC_MAX9867=m CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MAX98520=m CONFIG_SND_SOC_MAX98373=m CONFIG_SND_SOC_MAX98373_I2C=m CONFIG_SND_SOC_MAX98373_SDW=m CONFIG_SND_SOC_MAX98390=m +CONFIG_SND_SOC_MAX98396=m CONFIG_SND_SOC_MAX9860=m CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m CONFIG_SND_SOC_PCM1681=m @@ -6933,11 +7355,13 @@ CONFIG_SND_SOC_PCM512x_SPI=m CONFIG_SND_SOC_RK3328=m CONFIG_SND_SOC_RL6231=m CONFIG_SND_SOC_RL6347A=m +CONFIG_SND_SOC_RT274=m CONFIG_SND_SOC_RT286=m CONFIG_SND_SOC_RT298=m CONFIG_SND_SOC_RT1011=m CONFIG_SND_SOC_RT1015=m CONFIG_SND_SOC_RT1015P=m +CONFIG_SND_SOC_RT1019=m CONFIG_SND_SOC_RT1308=m CONFIG_SND_SOC_RT1308_SDW=m CONFIG_SND_SOC_RT1316_SDW=m @@ -6957,6 +7381,7 @@ CONFIG_SND_SOC_RT5677_SPI=m CONFIG_SND_SOC_RT5682=m CONFIG_SND_SOC_RT5682_I2C=m CONFIG_SND_SOC_RT5682_SDW=m +CONFIG_SND_SOC_RT5682S=m CONFIG_SND_SOC_RT700=m CONFIG_SND_SOC_RT700_SDW=m CONFIG_SND_SOC_RT711=m @@ -6965,6 +7390,8 @@ CONFIG_SND_SOC_RT711_SDCA_SDW=m CONFIG_SND_SOC_RT715=m CONFIG_SND_SOC_RT715_SDW=m CONFIG_SND_SOC_RT715_SDCA_SDW=m +CONFIG_SND_SOC_RT9120=m +# CONFIG_SND_SOC_SDW_MOCKUP is not set CONFIG_SND_SOC_SGTL5000=m CONFIG_SND_SOC_SI476X=m CONFIG_SND_SOC_SIGMADSP=m @@ -6973,6 +7400,8 @@ CONFIG_SND_SOC_SIGMADSP_REGMAP=m CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m CONFIG_SND_SOC_SIMPLE_MUX=m CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SRC4XXX_I2C=m +CONFIG_SND_SOC_SRC4XXX=m CONFIG_SND_SOC_SSM2305=m CONFIG_SND_SOC_SSM2518=m CONFIG_SND_SOC_SSM2602=m @@ -6986,13 +7415,16 @@ CONFIG_SND_SOC_TAS2552=m CONFIG_SND_SOC_TAS2562=m CONFIG_SND_SOC_TAS2764=m CONFIG_SND_SOC_TAS2770=m +CONFIG_SND_SOC_TAS2780=m CONFIG_SND_SOC_TAS5086=m CONFIG_SND_SOC_TAS571X=m CONFIG_SND_SOC_TAS5720=m +CONFIG_SND_SOC_TAS5805M=m CONFIG_SND_SOC_TAS6424=m CONFIG_SND_SOC_TDA7419=m CONFIG_SND_SOC_TFA9879=m CONFIG_SND_SOC_TFA989X=m +CONFIG_SND_SOC_TLV320ADC3XXX=m CONFIG_SND_SOC_TLV320AIC23=m CONFIG_SND_SOC_TLV320AIC23_I2C=m CONFIG_SND_SOC_TLV320AIC23_SPI=m @@ -7021,6 +7453,8 @@ CONFIG_SND_SOC_WM8580=m CONFIG_SND_SOC_WM8711=m CONFIG_SND_SOC_WM8728=m CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8731_I2C=m +CONFIG_SND_SOC_WM8731_SPI=m CONFIG_SND_SOC_WM8737=m CONFIG_SND_SOC_WM8741=m CONFIG_SND_SOC_WM8750=m @@ -7033,12 +7467,14 @@ CONFIG_SND_SOC_WM8804_I2C=m CONFIG_SND_SOC_WM8804_SPI=m CONFIG_SND_SOC_WM8903=m CONFIG_SND_SOC_WM8904=m +CONFIG_SND_SOC_WM8940=m CONFIG_SND_SOC_WM8960=m CONFIG_SND_SOC_WM8962=m CONFIG_SND_SOC_WM8974=m CONFIG_SND_SOC_WM8978=m CONFIG_SND_SOC_WM8985=m CONFIG_SND_SOC_WSA881X=m +CONFIG_SND_SOC_WSA883X=m CONFIG_SND_SOC_ZL38060=m CONFIG_SND_SOC_MAX9759=m CONFIG_SND_SOC_MT6351=m @@ -7047,10 +7483,12 @@ CONFIG_SND_SOC_MT6660=m CONFIG_SND_SOC_NAU8315=m CONFIG_SND_SOC_NAU8540=m CONFIG_SND_SOC_NAU8810=m +CONFIG_SND_SOC_NAU8821=m CONFIG_SND_SOC_NAU8822=m CONFIG_SND_SOC_NAU8824=m CONFIG_SND_SOC_NAU8825=m CONFIG_SND_SOC_TPA6130A2=m +CONFIG_SND_SOC_LPASS_MACRO_COMMON=m CONFIG_SND_SOC_LPASS_WSA_MACRO=m CONFIG_SND_SOC_LPASS_VA_MACRO=m CONFIG_SND_SOC_LPASS_RX_MACRO=m @@ -7112,6 +7550,7 @@ CONFIG_HID_GFRM=m CONFIG_HID_GLORIOUS=m CONFIG_HID_HOLTEK=m CONFIG_HOLTEK_FF=y +CONFIG_HID_VIVALDI_COMMON=m CONFIG_HID_GOOGLE_HAMMER=m CONFIG_HID_VIVALDI=m CONFIG_HID_GT683R=m @@ -7120,6 +7559,8 @@ CONFIG_HID_KYE=m CONFIG_HID_UCLOGIC=m CONFIG_HID_WALTOP=m CONFIG_HID_VIEWSONIC=m +CONFIG_HID_VRC2=m +CONFIG_HID_XIAOMI=m CONFIG_HID_GYRATION=m CONFIG_HID_ICADE=m CONFIG_HID_ITE=m @@ -7129,6 +7570,7 @@ CONFIG_HID_KENSINGTON=m CONFIG_HID_LCPOWER=m CONFIG_HID_LED=m CONFIG_HID_LENOVO=m +CONFIG_HID_LETSKETCH=m CONFIG_HID_LOGITECH=m CONFIG_HID_LOGITECH_DJ=m CONFIG_HID_LOGITECH_HIDPP=m @@ -7139,10 +7581,13 @@ CONFIG_LOGIWHEELS_FF=y CONFIG_HID_MAGICMOUSE=m CONFIG_HID_MALTRON=m CONFIG_HID_MAYFLASH=m +CONFIG_HID_MEGAWORLD_FF=m CONFIG_HID_REDRAGON=m CONFIG_HID_MICROSOFT=m CONFIG_HID_MONTEREY=m CONFIG_HID_MULTITOUCH=m +CONFIG_HID_NINTENDO=m +CONFIG_NINTENDO_FF=y CONFIG_HID_NTI=m CONFIG_HID_NTRIG=m CONFIG_HID_ORTEK=m @@ -7159,12 +7604,15 @@ CONFIG_HID_PICOLCD_CIR=y CONFIG_HID_PLANTRONICS=m CONFIG_HID_PLAYSTATION=m CONFIG_PLAYSTATION_FF=y +CONFIG_HID_PXRC=m +CONFIG_HID_RAZER=m CONFIG_HID_PRIMAX=m CONFIG_HID_RETRODE=m CONFIG_HID_ROCCAT=m CONFIG_HID_SAITEK=m CONFIG_HID_SAMSUNG=m CONFIG_HID_SEMITEK=m +CONFIG_HID_SIGMAMICRO=m CONFIG_HID_SONY=m CONFIG_SONY_FF=y CONFIG_HID_SPEEDLINK=m @@ -7179,6 +7627,7 @@ CONFIG_HID_SMARTJOYPLUS=m CONFIG_SMARTJOYPLUS_FF=y CONFIG_HID_TIVO=m CONFIG_HID_TOPSEED=m +CONFIG_HID_TOPRE=m CONFIG_HID_THINGM=m CONFIG_HID_THRUSTMASTER=m CONFIG_THRUSTMASTER_FF=y @@ -7289,6 +7738,7 @@ CONFIG_USB_R8A66597_HCD=m CONFIG_USB_HCD_BCMA=m CONFIG_USB_HCD_SSB=m # CONFIG_USB_HCD_TEST_MODE is not set +CONFIG_USB_XEN_HCD=m # # USB Device Class drivers @@ -7615,19 +8065,25 @@ CONFIG_TYPEC_TCPM=m CONFIG_TYPEC_TCPCI=m CONFIG_TYPEC_RT1711H=m CONFIG_TYPEC_MT6360=m +CONFIG_TYPEC_TCPCI_MT6370=m CONFIG_TYPEC_TCPCI_MAXIM=m CONFIG_TYPEC_FUSB302=m CONFIG_TYPEC_WCOVE=m CONFIG_TYPEC_UCSI=m CONFIG_UCSI_CCG=m CONFIG_UCSI_ACPI=m +CONFIG_UCSI_STM32G0=m CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_ANX7411=m +CONFIG_TYPEC_RT1719=m CONFIG_TYPEC_HD3SS3220=m CONFIG_TYPEC_STUSB160X=m +CONFIG_TYPEC_WUSB3801=m # # USB Type-C Multiplexer/DeMultiplexer Switch support # +CONFIG_TYPEC_MUX_FSA4480=m CONFIG_TYPEC_MUX_PI3USB30532=m CONFIG_TYPEC_MUX_INTEL_PMC=m # end of USB Type-C Multiplexer/DeMultiplexer Switch support @@ -7676,6 +8132,16 @@ CONFIG_MMC_HSQ=m CONFIG_MMC_TOSHIBA_PCI=m CONFIG_MMC_MTK=m CONFIG_MMC_SDHCI_XENON=m +CONFIG_SCSI_UFSHCD=m +CONFIG_SCSI_UFS_BSG=y +CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_SCSI_UFS_HPB=y +CONFIG_SCSI_UFS_HWMON=y +CONFIG_SCSI_UFSHCD_PCI=m +# CONFIG_SCSI_UFS_DWC_TC_PCI is not set +CONFIG_SCSI_UFSHCD_PLATFORM=m +CONFIG_SCSI_UFS_CDNS_PLATFORM=m +# CONFIG_SCSI_UFS_DWC_TC_PLATFORM is not set CONFIG_MEMSTICK=m # CONFIG_MEMSTICK_DEBUG is not set @@ -7705,12 +8171,10 @@ CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y # CONFIG_LEDS_88PM860X=m CONFIG_LEDS_APU=m -CONFIG_LEDS_AS3645A=m CONFIG_LEDS_LM3530=m CONFIG_LEDS_LM3532=m CONFIG_LEDS_LM3533=m CONFIG_LEDS_LM3642=m -CONFIG_LEDS_LM3601X=m CONFIG_LEDS_MT6323=m CONFIG_LEDS_PCA9532=m CONFIG_LEDS_PCA9532_GPIO=y @@ -7719,7 +8183,6 @@ CONFIG_LEDS_LP3944=m CONFIG_LEDS_LP3952=m CONFIG_LEDS_LP50XX=m CONFIG_LEDS_LP8788=m -CONFIG_LEDS_CLEVO_MAIL=m CONFIG_LEDS_PCA955X=m CONFIG_LEDS_PCA955X_GPIO=y CONFIG_LEDS_PCA963X=m @@ -7740,6 +8203,7 @@ CONFIG_LEDS_TLC591XX=m CONFIG_LEDS_MAX8997=m CONFIG_LEDS_LM355x=m CONFIG_LEDS_MENF21BMC=m +CONFIG_LEDS_IS31FL319X=m # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) @@ -7752,12 +8216,19 @@ CONFIG_LEDS_NIC78BX=m CONFIG_LEDS_TI_LMU_COMMON=m CONFIG_LEDS_LM36274=m CONFIG_LEDS_TPS6105X=m -CONFIG_LEDS_SGM3140=m # # Flash and Torch LED drivers # +CONFIG_LEDS_AS3645A=m +CONFIG_LEDS_LM3601X=m CONFIG_LEDS_RT8515=m +CONFIG_LEDS_SGM3140=m + +# +# RGB LED drivers +# +CONFIG_LEDS_PWM_MULTICOLOR=m # # LED Triggers @@ -7784,6 +8255,11 @@ CONFIG_LEDS_TRIGGER_NETDEV=m CONFIG_LEDS_TRIGGER_PATTERN=m CONFIG_LEDS_TRIGGER_AUDIO=m CONFIG_LEDS_TRIGGER_TTY=m + +# +# Simple LED drivers +# +CONFIG_LEDS_SIEMENS_SIMATIC_IPC=m CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y @@ -7812,23 +8288,24 @@ CONFIG_INFINIBAND_ON_DEMAND_PAGING=y CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y CONFIG_INFINIBAND_VIRT_DMA=y -CONFIG_INFINIBAND_MTHCA=m -CONFIG_INFINIBAND_MTHCA_DEBUG=y -CONFIG_INFINIBAND_QIB=m -CONFIG_INFINIBAND_QIB_DCA=y +CONFIG_INFINIBAND_BNXT_RE=m CONFIG_INFINIBAND_CXGB4=m CONFIG_INFINIBAND_EFA=m +CONFIG_INFINIBAND_ERDMA=m +CONFIG_INFINIBAND_HFI1=m +# CONFIG_HFI1_DEBUG_SDMA_ORDER is not set +# CONFIG_SDMA_VERBOSITY is not set CONFIG_INFINIBAND_IRDMA=m CONFIG_MLX4_INFINIBAND=m CONFIG_MLX5_INFINIBAND=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_OCRDMA=m -CONFIG_INFINIBAND_VMWARE_PVRDMA=m -CONFIG_INFINIBAND_USNIC=m -CONFIG_INFINIBAND_BNXT_RE=m -CONFIG_INFINIBAND_HFI1=m -# CONFIG_HFI1_DEBUG_SDMA_ORDER is not set -# CONFIG_SDMA_VERBOSITY is not set CONFIG_INFINIBAND_QEDR=m +CONFIG_INFINIBAND_QIB=m +CONFIG_INFINIBAND_QIB_DCA=y +CONFIG_INFINIBAND_USNIC=m +CONFIG_INFINIBAND_VMWARE_PVRDMA=m CONFIG_INFINIBAND_RDMAVT=m CONFIG_RDMA_RXE=m CONFIG_RDMA_SIW=m @@ -7921,7 +8398,6 @@ CONFIG_RTC_DRV_BQ32K=m CONFIG_RTC_DRV_PALMAS=m CONFIG_RTC_DRV_TPS6586X=m CONFIG_RTC_DRV_TPS65910=m -CONFIG_RTC_DRV_TPS80031=m CONFIG_RTC_DRV_RC5T583=m CONFIG_RTC_DRV_S35390A=m CONFIG_RTC_DRV_FM3130=m @@ -8019,11 +8495,14 @@ CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_ACPI=y CONFIG_ALTERA_MSGDMA=m CONFIG_INTEL_IDMA64=m +CONFIG_INTEL_IDXD_BUS=m CONFIG_INTEL_IDXD=m +# CONFIG_INTEL_IDXD_COMPAT is not set CONFIG_INTEL_IDXD_SVM=y CONFIG_INTEL_IDXD_PERFMON=y CONFIG_INTEL_IOATDMA=m CONFIG_PLX_DMA=m +CONFIG_AMD_PTDMA=m CONFIG_QCOM_HIDMA_MGMT=m CONFIG_QCOM_HIDMA=m CONFIG_DW_DMAC_CORE=y @@ -8052,30 +8531,14 @@ CONFIG_UDMABUF=y # CONFIG_DMABUF_DEBUG is not set # CONFIG_DMABUF_SELFTESTS is not set CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_SYSFS_STATS=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_DMABUF_HEAPS_CMA=y # end of DMABUF options CONFIG_DCA=m -CONFIG_AUXDISPLAY=y -CONFIG_CHARLCD=m -CONFIG_HD44780_COMMON=m -CONFIG_HD44780=m -CONFIG_KS0108=m -CONFIG_KS0108_PORT=0x378 -CONFIG_KS0108_DELAY=2 -CONFIG_CFAG12864B=m -CONFIG_CFAG12864B_RATE=20 -CONFIG_IMG_ASCII_LCD=m -CONFIG_LCD2S=m -CONFIG_PARPORT_PANEL=m -CONFIG_PANEL_PARPORT=0 -CONFIG_PANEL_PROFILE=5 -# CONFIG_PANEL_CHANGE_MESSAGE is not set -# CONFIG_CHARLCD_BL_OFF is not set -# CONFIG_CHARLCD_BL_ON is not set -CONFIG_CHARLCD_BL_FLASH=y -CONFIG_PANEL=m +# CONFIG_AUXDISPLAY is not set +# CONFIG_PANEL is not set CONFIG_UIO=m CONFIG_UIO_CIF=m CONFIG_UIO_PDRV_GENIRQ=m @@ -8088,24 +8551,30 @@ CONFIG_UIO_PRUSS=m CONFIG_UIO_MF624=m CONFIG_UIO_HV_GENERIC=m CONFIG_UIO_DFL=m +CONFIG_VFIO=m CONFIG_VFIO_IOMMU_TYPE1=m CONFIG_VFIO_VIRQFD=m -CONFIG_VFIO=m # CONFIG_VFIO_NOIOMMU is not set -CONFIG_VFIO_PCI=m -CONFIG_VFIO_PCI_VGA=y +CONFIG_VFIO_PCI_CORE=m CONFIG_VFIO_PCI_MMAP=y CONFIG_VFIO_PCI_INTX=y +CONFIG_VFIO_PCI=m +CONFIG_VFIO_PCI_VGA=y CONFIG_VFIO_PCI_IGD=y +CONFIG_MLX5_VFIO_PCI=m CONFIG_VFIO_MDEV=m CONFIG_IRQ_BYPASS_MANAGER=m CONFIG_VIRT_DRIVERS=y +CONFIG_VMGENID=y CONFIG_VBOXGUEST=m CONFIG_NITRO_ENCLAVES=m CONFIG_ACRN_HSM=m +CONFIG_EFI_SECRET=m +CONFIG_SEV_GUEST=m +CONFIG_VIRTIO_ANCHOR=y CONFIG_VIRTIO=y -CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS=y CONFIG_VIRTIO_PCI_LIB=m +CONFIG_VIRTIO_PCI_LIB_LEGACY=m CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_PCI_LEGACY=y @@ -8121,10 +8590,12 @@ CONFIG_VDPA=m CONFIG_VDPA_SIM=m CONFIG_VDPA_SIM_NET=m CONFIG_VDPA_SIM_BLOCK=m +CONFIG_VDPA_USER=m CONFIG_IFCVF=m CONFIG_MLX5_VDPA=y CONFIG_MLX5_VDPA_NET=m CONFIG_VP_VDPA=m +CONFIG_ALIBABA_ENI_VDPA=m CONFIG_VHOST_IOTLB=m CONFIG_VHOST_RING=m CONFIG_VHOST=m @@ -8162,6 +8633,7 @@ CONFIG_XEN_GNTDEV_DMABUF=y CONFIG_XEN_GRANT_DEV_ALLOC=m CONFIG_XEN_GRANT_DMA_ALLOC=y CONFIG_SWIOTLB_XEN=y +CONFIG_XEN_PCI_STUB=y CONFIG_XEN_PCIDEV_BACKEND=m CONFIG_XEN_PVCALLS_FRONTEND=m CONFIG_XEN_PVCALLS_BACKEND=y @@ -8177,6 +8649,9 @@ CONFIG_XEN_SYMS=y CONFIG_XEN_HAVE_VPMU=y CONFIG_XEN_FRONT_PGDIR_SHBUF=m CONFIG_XEN_UNPOPULATED_ALLOC=y +CONFIG_XEN_GRANT_DMA_OPS=y +CONFIG_XEN_VIRTIO=y +# CONFIG_XEN_VIRTIO_FORCE_GRANT is not set # end of Xen driver support # CONFIG_GREYBUS is not set @@ -8192,7 +8667,6 @@ CONFIG_RTL8192E=m CONFIG_RTL8723BS=m CONFIG_R8712U=m CONFIG_R8188EU=m -CONFIG_88EU_AP_MODE=y CONFIG_RTS5208=m CONFIG_VT6655=m CONFIG_VT6656=m @@ -8212,7 +8686,6 @@ CONFIG_ADIS16240=m # Analog to digital converters # CONFIG_AD7816=m -CONFIG_AD7280=m # end of Analog to digital converters # @@ -8224,12 +8697,6 @@ CONFIG_ADT7316_I2C=m # end of Analog digital bi-direction converters # -# Capacitance to digital converters -# -CONFIG_AD7746=m -# end of Capacitance to digital converters - -# # Direct Digital Synthesis # CONFIG_AD9832=m @@ -8270,28 +8737,9 @@ CONFIG_VIDEO_ATOMISP_GC0310=m CONFIG_VIDEO_ATOMISP_OV2680=m CONFIG_VIDEO_ATOMISP_OV5693=m CONFIG_VIDEO_ATOMISP_LM3554=m -# CONFIG_VIDEO_ZORAN is not set CONFIG_VIDEO_IPU3_IMGU=m -CONFIG_DVB_AV7110_IR=y -CONFIG_DVB_AV7110=m -CONFIG_DVB_AV7110_OSD=y -CONFIG_DVB_BUDGET_PATCH=m -CONFIG_DVB_SP8870=m - -# -# Android -# -# end of Android - +# CONFIG_STAGING_MEDIA_DEPRECATED is not set CONFIG_LTE_GDM724X=m -CONFIG_FIREWIRE_SERIAL=m -CONFIG_FWTTY_MAX_TOTAL_PORTS=64 -CONFIG_FWTTY_MAX_CARD_PORTS=32 -CONFIG_GS_FPGABOOT=m -CONFIG_UNISYSSPAR=y -CONFIG_UNISYS_VISORNIC=m -CONFIG_UNISYS_VISORINPUT=m -CONFIG_UNISYS_VISORHBA=m # CONFIG_FB_TFT is not set CONFIG_MOST_COMPONENTS=m CONFIG_MOST_NET=m @@ -8301,27 +8749,78 @@ CONFIG_KS7010=m CONFIG_PI433=m CONFIG_FIELDBUS_DEV=m CONFIG_QLGE=m -CONFIG_WFX=m +# CONFIG_VME_BUS is not set +CONFIG_CHROME_PLATFORMS=y +CONFIG_CHROMEOS_ACPI=m +CONFIG_CHROMEOS_LAPTOP=m +CONFIG_CHROMEOS_PSTORE=m +CONFIG_CHROMEOS_TBMC=m +CONFIG_CROS_EC=m +CONFIG_CROS_EC_I2C=m +CONFIG_CROS_EC_ISHTP=m +CONFIG_CROS_EC_SPI=m +CONFIG_CROS_EC_LPC=m +CONFIG_CROS_EC_PROTO=y +CONFIG_CROS_KBD_LED_BACKLIGHT=m +CONFIG_CROS_EC_CHARDEV=m +CONFIG_CROS_EC_LIGHTBAR=m +CONFIG_CROS_EC_DEBUGFS=m +CONFIG_CROS_EC_SENSORHUB=m +CONFIG_CROS_EC_SYSFS=m +CONFIG_CROS_EC_TYPEC=m +CONFIG_CROS_USBPD_LOGGER=m +CONFIG_CROS_USBPD_NOTIFY=m +CONFIG_CHROMEOS_PRIVACY_SCREEN=m +CONFIG_CROS_TYPEC_SWITCH=m +CONFIG_WILCO_EC=m +CONFIG_WILCO_EC_DEBUGFS=m +CONFIG_WILCO_EC_EVENTS=m +CONFIG_WILCO_EC_TELEMETRY=m +CONFIG_MELLANOX_PLATFORM=y +CONFIG_MLXREG_HOTPLUG=m +CONFIG_MLXREG_IO=m +CONFIG_MLXREG_LC=m +CONFIG_NVSW_SN2201=m +CONFIG_SURFACE_PLATFORMS=y +CONFIG_SURFACE3_WMI=m +CONFIG_SURFACE_3_POWER_OPREGION=m +CONFIG_SURFACE_ACPI_NOTIFY=m +CONFIG_SURFACE_AGGREGATOR_CDEV=m +CONFIG_SURFACE_AGGREGATOR_HUB=m +CONFIG_SURFACE_AGGREGATOR_REGISTRY=m +CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH=m +CONFIG_SURFACE_DTX=m +CONFIG_SURFACE_GPE=m +CONFIG_SURFACE_HOTPLUG=m +CONFIG_SURFACE_PLATFORM_PROFILE=m +CONFIG_SURFACE_PRO3_BUTTON=m +CONFIG_SURFACE_AGGREGATOR=m +CONFIG_SURFACE_AGGREGATOR_BUS=y +# CONFIG_SURFACE_AGGREGATOR_ERROR_INJECTION is not set CONFIG_X86_PLATFORM_DEVICES=y CONFIG_ACPI_WMI=m CONFIG_WMI_BMOF=m CONFIG_HUAWEI_WMI=m -CONFIG_INTEL_WMI_SBL_FW_UPDATE=m -CONFIG_INTEL_WMI_THUNDERBOLT=m CONFIG_MXM_WMI=m CONFIG_PEAQ_WMI=m +CONFIG_NVIDIA_WMI_EC_BACKLIGHT=m CONFIG_XIAOMI_WMI=m CONFIG_GIGABYTE_WMI=m +CONFIG_YOGABOOK_WMI=m CONFIG_ACERHDF=m CONFIG_ACER_WIRELESS=m CONFIG_ACER_WMI=m +CONFIG_AMD_PMF=m CONFIG_AMD_PMC=m +CONFIG_AMD_HSMP=m CONFIG_ADV_SWBUTTON=m CONFIG_APPLE_GMUX=m CONFIG_ASUS_LAPTOP=m CONFIG_ASUS_WIRELESS=m CONFIG_ASUS_WMI=m CONFIG_ASUS_NB_WMI=m +CONFIG_ASUS_TF103C_DOCK=m +CONFIG_MERAKI_MX100=m CONFIG_EEEPC_LAPTOP=m CONFIG_EEEPC_WMI=m CONFIG_X86_PLATFORM_DRIVERS_DELL=y @@ -8358,18 +8857,51 @@ CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y CONFIG_THINKPAD_ACPI_VIDEO=y CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y CONFIG_THINKPAD_LMI=m -CONFIG_X86_PLATFORM_DRIVERS_INTEL=y -CONFIG_INTEL_CHT_INT33FE=m -CONFIG_INTEL_SKL_INT3472=m +CONFIG_INTEL_ATOMISP2_PDX86=y CONFIG_INTEL_ATOMISP2_LED=m +CONFIG_INTEL_SAR_INT1092=m +CONFIG_INTEL_SKL_INT3472=m +CONFIG_INTEL_PMC_CORE=y +CONFIG_INTEL_PMT_CLASS=m +CONFIG_INTEL_PMT_TELEMETRY=m +CONFIG_INTEL_PMT_CRASHLOG=m + +# +# Intel Speed Select Technology interface support +# +CONFIG_INTEL_SPEED_SELECT_INTERFACE=m +# end of Intel Speed Select Technology interface support + +CONFIG_INTEL_TELEMETRY=m +CONFIG_INTEL_WMI=y +CONFIG_INTEL_WMI_SBL_FW_UPDATE=m +CONFIG_INTEL_WMI_THUNDERBOLT=m + +# +# Intel Uncore Frequency Control +# +CONFIG_INTEL_UNCORE_FREQ_CONTROL=m +# end of Intel Uncore Frequency Control + CONFIG_INTEL_HID_EVENT=m +CONFIG_INTEL_VBTN=m CONFIG_INTEL_INT0002_VGPIO=m -CONFIG_INTEL_MENLOW=m CONFIG_INTEL_OAKTRAIL=m -CONFIG_INTEL_VBTN=m +CONFIG_INTEL_BXTWC_PMIC_TMU=m +CONFIG_INTEL_CHTDC_TI_PWRBTN=m +CONFIG_INTEL_CHTWC_INT33FE=m +CONFIG_INTEL_ISHTP_ECLITE=m +CONFIG_INTEL_MRFLD_PWRBTN=m +CONFIG_INTEL_PUNIT_IPC=m +CONFIG_INTEL_RST=m +CONFIG_INTEL_SDSI=m +CONFIG_INTEL_SMARTCONNECT=m +CONFIG_INTEL_TURBO_MAX_3=y +CONFIG_INTEL_VSEC=m CONFIG_MSI_LAPTOP=m CONFIG_MSI_WMI=m CONFIG_PCENGINES_APU2=m +CONFIG_BARCO_P50_GPIO=m CONFIG_SAMSUNG_LAPTOP=m CONFIG_SAMSUNG_Q10=m CONFIG_ACPI_TOSHIBA=m @@ -8384,96 +8916,31 @@ CONFIG_SONY_LAPTOP=m CONFIG_SONYPI_COMPAT=y CONFIG_SYSTEM76_ACPI=m CONFIG_TOPSTAR_LAPTOP=m -CONFIG_I2C_MULTI_INSTANTIATE=m +CONFIG_SERIAL_MULTI_INSTANTIATE=m CONFIG_MLX_PLATFORM=m CONFIG_TOUCHSCREEN_DMI=y +CONFIG_X86_ANDROID_TABLETS=m CONFIG_FW_ATTR_CLASS=m CONFIG_INTEL_IPS=m -CONFIG_INTEL_RST=m -CONFIG_INTEL_SMARTCONNECT=m - -# -# Intel Speed Select Technology interface support -# -CONFIG_INTEL_SPEED_SELECT_INTERFACE=m -# end of Intel Speed Select Technology interface support - -CONFIG_INTEL_TURBO_MAX_3=y -CONFIG_INTEL_UNCORE_FREQ_CONTROL=m -CONFIG_INTEL_BXTWC_PMIC_TMU=m -CONFIG_INTEL_CHTDC_TI_PWRBTN=m -CONFIG_INTEL_MRFLD_PWRBTN=m -CONFIG_INTEL_PMC_CORE=y -CONFIG_INTEL_PMT_CLASS=m -CONFIG_INTEL_PMT_TELEMETRY=m -CONFIG_INTEL_PMT_CRASHLOG=m -CONFIG_INTEL_PUNIT_IPC=m CONFIG_INTEL_SCU_IPC=y CONFIG_INTEL_SCU=y CONFIG_INTEL_SCU_PCI=y CONFIG_INTEL_SCU_PLATFORM=m CONFIG_INTEL_SCU_IPC_UTIL=m -CONFIG_INTEL_TELEMETRY=m -CONFIG_PMC_ATOM=y -CONFIG_CHROME_PLATFORMS=y -CONFIG_CHROMEOS_LAPTOP=m -CONFIG_CHROMEOS_PSTORE=m -CONFIG_CHROMEOS_TBMC=m -CONFIG_CROS_EC=m -CONFIG_CROS_EC_I2C=m -CONFIG_CROS_EC_ISHTP=m -CONFIG_CROS_EC_SPI=m -CONFIG_CROS_EC_LPC=m -CONFIG_CROS_EC_PROTO=y -CONFIG_CROS_KBD_LED_BACKLIGHT=m -CONFIG_CROS_EC_CHARDEV=m -CONFIG_CROS_EC_LIGHTBAR=m -CONFIG_CROS_EC_DEBUGFS=m -CONFIG_CROS_EC_SENSORHUB=m -CONFIG_CROS_EC_SYSFS=m -CONFIG_CROS_EC_TYPEC=m -CONFIG_CROS_USBPD_LOGGER=m -CONFIG_CROS_USBPD_NOTIFY=m -CONFIG_WILCO_EC=m -CONFIG_WILCO_EC_DEBUGFS=m -CONFIG_WILCO_EC_EVENTS=m -CONFIG_WILCO_EC_TELEMETRY=m -CONFIG_MELLANOX_PLATFORM=y -CONFIG_MLXREG_HOTPLUG=m -CONFIG_MLXREG_IO=m -CONFIG_SURFACE_PLATFORMS=y -CONFIG_SURFACE3_WMI=m -CONFIG_SURFACE_3_BUTTON=m -CONFIG_SURFACE_3_POWER_OPREGION=m -CONFIG_SURFACE_ACPI_NOTIFY=m -CONFIG_SURFACE_AGGREGATOR_CDEV=m -CONFIG_SURFACE_AGGREGATOR_REGISTRY=m -CONFIG_SURFACE_DTX=m -CONFIG_SURFACE_GPE=m -CONFIG_SURFACE_HOTPLUG=m -CONFIG_SURFACE_PLATFORM_PROFILE=m -CONFIG_SURFACE_PRO3_BUTTON=m -CONFIG_SURFACE_AGGREGATOR=m -CONFIG_SURFACE_AGGREGATOR_BUS=y -# CONFIG_SURFACE_AGGREGATOR_ERROR_INJECTION is not set +CONFIG_SIEMENS_SIMATIC_IPC=m +CONFIG_WINMATE_FM07_KEYS=m +CONFIG_P2SB=y CONFIG_HAVE_CLK=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_WM831X=m - -# -# Clock driver for ARM Reference designs -# -# CONFIG_ICST is not set -# CONFIG_CLK_SP810 is not set -# end of Clock driver for ARM Reference designs - CONFIG_LMK04832=m CONFIG_COMMON_CLK_MAX9485=m CONFIG_COMMON_CLK_SI5341=m CONFIG_COMMON_CLK_SI5351=m CONFIG_COMMON_CLK_SI544=m CONFIG_COMMON_CLK_CDCE706=m +CONFIG_COMMON_CLK_TPS68470=m CONFIG_COMMON_CLK_CS2000_CP=m CONFIG_CLK_TWL6040=m CONFIG_COMMON_CLK_PALMAS=m @@ -8504,9 +8971,11 @@ CONFIG_IOMMU_IO_PGTABLE=y # end of Generic IOMMU Pagetable Support # CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set +CONFIG_IOMMU_DEFAULT_DMA_LAZY=y # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set CONFIG_IOMMU_DMA=y -CONFIG_IOMMU_SVA_LIB=y +CONFIG_IOMMU_SVA=y CONFIG_AMD_IOMMU=y CONFIG_AMD_IOMMU_V2=y CONFIG_DMAR_TABLE=y @@ -8531,6 +9000,7 @@ CONFIG_REMOTEPROC_CDEV=y # CONFIG_RPMSG=m CONFIG_RPMSG_CHAR=m +CONFIG_RPMSG_CTRL=m CONFIG_RPMSG_NS=m CONFIG_RPMSG_QCOM_GLINK=m CONFIG_RPMSG_QCOM_GLINK_RPM=m @@ -8567,6 +9037,11 @@ CONFIG_SOUNDWIRE_GENERIC_ALLOCATION=m # end of NXP/Freescale QorIQ SoC drivers # +# fujitsu SoC drivers +# +# end of fujitsu SoC drivers + +# # i.MX SoC drivers # # end of i.MX SoC drivers @@ -8651,6 +9126,15 @@ CONFIG_IIO_TRIGGERED_EVENT=m # CONFIG_ADIS16201=m CONFIG_ADIS16209=m +CONFIG_ADXL313=m +CONFIG_ADXL313_I2C=m +CONFIG_ADXL313_SPI=m +CONFIG_ADXL355=m +CONFIG_ADXL355_I2C=m +CONFIG_ADXL355_SPI=m +CONFIG_ADXL367=m +CONFIG_ADXL367_SPI=m +CONFIG_ADXL367_I2C=m CONFIG_ADXL372=m CONFIG_ADXL372_SPI=m CONFIG_ADXL372_I2C=m @@ -8665,6 +9149,7 @@ CONFIG_BMI088_ACCEL=m CONFIG_BMI088_ACCEL_SPI=m CONFIG_DA280=m CONFIG_DA311=m +CONFIG_DMARD06=m CONFIG_DMARD09=m CONFIG_DMARD10=m CONFIG_FXLS8962AF=m @@ -8688,6 +9173,7 @@ CONFIG_MMA8452=m CONFIG_MMA9551_CORE=m CONFIG_MMA9551=m CONFIG_MMA9553=m +CONFIG_MSA311=m CONFIG_MXC4005=m CONFIG_MXC6255=m CONFIG_SCA3000=m @@ -8704,6 +9190,7 @@ CONFIG_AD7091R5=m CONFIG_AD7124=m CONFIG_AD7192=m CONFIG_AD7266=m +CONFIG_AD7280=m CONFIG_AD7291=m CONFIG_AD7292=m CONFIG_AD7298=m @@ -8725,6 +9212,7 @@ CONFIG_AXP288_ADC=m CONFIG_CC10001_ADC=m CONFIG_DA9150_GPADC=m CONFIG_DLN2_ADC=m +CONFIG_ENVELOPE_DETECTOR=m CONFIG_HI8435=m CONFIG_HX711=m CONFIG_INA2XX_ADC=m @@ -8737,6 +9225,7 @@ CONFIG_LTC2497=m CONFIG_MAX1027=m CONFIG_MAX11100=m CONFIG_MAX1118=m +CONFIG_MAX11205=m CONFIG_MAX1241=m CONFIG_MAX1363=m CONFIG_MAX9611=m @@ -8748,6 +9237,8 @@ CONFIG_MEN_Z188_ADC=m CONFIG_MP2629_ADC=m CONFIG_NAU7802=m CONFIG_PALMAS_GPADC=m +CONFIG_RICHTEK_RTQ6056=m +CONFIG_SD_ADC_MODULATOR=m CONFIG_TI_ADC081C=m CONFIG_TI_ADC0832=m CONFIG_TI_ADC084S021=m @@ -8757,25 +9248,37 @@ CONFIG_TI_ADC128S052=m CONFIG_TI_ADC161S626=m CONFIG_TI_ADS1015=m CONFIG_TI_ADS7950=m +CONFIG_TI_ADS8344=m +CONFIG_TI_ADS8688=m +CONFIG_TI_ADS124S08=m CONFIG_TI_ADS131E08=m CONFIG_TI_AM335X_ADC=m CONFIG_TI_TLC4541=m CONFIG_TI_TSC2046=m CONFIG_TWL4030_MADC=m CONFIG_TWL6030_GPADC=m +CONFIG_VF610_ADC=m CONFIG_VIPERBOARD_ADC=m CONFIG_XILINX_XADC=m # end of Analog to digital converters # +# Analog to digital and digital to analog converters +# +CONFIG_AD74413R=m +# end of Analog to digital and digital to analog converters + +# # Analog Front Ends # +CONFIG_IIO_RESCALE=m # end of Analog Front Ends # # Amplifiers # CONFIG_AD8366=m +CONFIG_ADA4250=m CONFIG_HMC425=m # end of Amplifiers @@ -8783,6 +9286,7 @@ CONFIG_HMC425=m # Capacitance to digital converters # CONFIG_AD7150=m +CONFIG_AD7746=m # end of Capacitance to digital converters # @@ -8799,10 +9303,13 @@ CONFIG_PMS7003=m CONFIG_SCD30_CORE=m CONFIG_SCD30_I2C=m CONFIG_SCD30_SERIAL=m +CONFIG_SCD4X=m CONFIG_SENSIRION_SGP30=m +CONFIG_SENSIRION_SGP40=m CONFIG_SPS30=m CONFIG_SPS30_I2C=m CONFIG_SPS30_SERIAL=m +CONFIG_SENSEAIR_SUNRISE_CO2=m CONFIG_VZ89X=m # end of Chemical Sensors @@ -8838,6 +9345,7 @@ CONFIG_IIO_ST_SENSORS_CORE=m # # Digital to analog converters # +CONFIG_AD3552R=m CONFIG_AD5064=m CONFIG_AD5360=m CONFIG_AD5380=m @@ -8849,6 +9357,7 @@ CONFIG_AD5592R=m CONFIG_AD5593R=m CONFIG_AD5504=m CONFIG_AD5624R_SPI=m +CONFIG_LTC2688=m CONFIG_AD5686=m CONFIG_AD5686_SPI=m CONFIG_AD5696_I2C=m @@ -8859,19 +9368,23 @@ CONFIG_AD5764=m CONFIG_AD5766=m CONFIG_AD5770R=m CONFIG_AD5791=m +CONFIG_AD7293=m CONFIG_AD7303=m CONFIG_AD8801=m +CONFIG_DPOT_DAC=m CONFIG_DS4424=m CONFIG_LTC1660=m CONFIG_LTC2632=m CONFIG_M62332=m CONFIG_MAX517=m +CONFIG_MAX5821=m CONFIG_MCP4725=m CONFIG_MCP4922=m CONFIG_TI_DAC082S085=m CONFIG_TI_DAC5571=m CONFIG_TI_DAC7311=m CONFIG_TI_DAC7612=m +CONFIG_VF610_DAC=m # end of Digital to analog converters # @@ -8881,6 +9394,12 @@ CONFIG_TI_DAC7612=m # end of IIO dummy driver # +# Filters +# +CONFIG_ADMV8818=m +# end of Filters + +# # Frequency Synthesizers DDS/PLL # @@ -8895,6 +9414,10 @@ CONFIG_AD9523=m # CONFIG_ADF4350=m CONFIG_ADF4371=m +CONFIG_ADMV1013=m +CONFIG_ADMV1014=m +CONFIG_ADMV4420=m +CONFIG_ADRF6780=m # end of Phase-Locked Loop (PLL) frequency synthesizers # end of Frequency Synthesizers DDS/PLL @@ -8962,6 +9485,9 @@ CONFIG_ADIS16480=m CONFIG_BMI160=m CONFIG_BMI160_I2C=m CONFIG_BMI160_SPI=m +CONFIG_BOSCH_BNO055=m +CONFIG_BOSCH_BNO055_SERIAL=m +CONFIG_BOSCH_BNO055_I2C=m CONFIG_FXOS8700=m CONFIG_FXOS8700_I2C=m CONFIG_FXOS8700_SPI=m @@ -8999,6 +9525,7 @@ CONFIG_BH1780=m CONFIG_CM32181=m CONFIG_CM3232=m CONFIG_CM3323=m +CONFIG_CM3605=m CONFIG_CM36651=m CONFIG_IIO_CROS_EC_LIGHT_PROX=m CONFIG_GP2AP002=m @@ -9013,6 +9540,7 @@ CONFIG_JSA1212=m CONFIG_RPR0521=m CONFIG_SENSORS_LM3533=m CONFIG_LTR501=m +CONFIG_LTRF216A=m CONFIG_LV0104CS=m CONFIG_MAX44000=m CONFIG_MAX44009=m @@ -9044,6 +9572,7 @@ CONFIG_ZOPT2201=m # # Magnetometer sensors # +CONFIG_AK8974=m CONFIG_AK8975=m CONFIG_AK09911=m CONFIG_BMC150_MAGN=m @@ -9067,6 +9596,7 @@ CONFIG_YAMAHA_YAS530=m # # Multiplexers # +CONFIG_IIO_MUX=m # end of Multiplexers # @@ -9095,6 +9625,7 @@ CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m # # Digital potentiometers # +CONFIG_AD5110=m CONFIG_AD5272=m CONFIG_DS1803=m CONFIG_MAX5432=m @@ -9160,7 +9691,10 @@ CONFIG_MB1232=m CONFIG_PING=m CONFIG_RFD77402=m CONFIG_SRF04=m +CONFIG_SX_COMMON=m CONFIG_SX9310=m +CONFIG_SX9324=m +CONFIG_SX9360=m CONFIG_SX9500=m CONFIG_SRF08=m CONFIG_VCNL3020=m @@ -9189,6 +9723,7 @@ CONFIG_TMP117=m CONFIG_TSYS01=m CONFIG_TSYS02D=m CONFIG_MAX31856=m +CONFIG_MAX31865=m # end of Temperature sensors CONFIG_NTB=m @@ -9203,10 +9738,10 @@ CONFIG_NTB_SWITCHTEC=m # CONFIG_NTB_PERF is not set # CONFIG_NTB_MSI_TEST is not set CONFIG_NTB_TRANSPORT=m -# CONFIG_VME_BUS is not set CONFIG_PWM=y CONFIG_PWM_SYSFS=y # CONFIG_PWM_DEBUG is not set +CONFIG_PWM_CLK=m CONFIG_PWM_CRC=y CONFIG_PWM_CROS_EC=m CONFIG_PWM_DWC=m @@ -9230,6 +9765,7 @@ CONFIG_BOARD_TPCI200=m CONFIG_SERIAL_IPOCTAL=m CONFIG_RESET_CONTROLLER=y CONFIG_RESET_TI_SYSCON=m +CONFIG_RESET_TI_TPS380X=m # # PHY Subsystem @@ -9237,7 +9773,13 @@ CONFIG_RESET_TI_SYSCON=m CONFIG_GENERIC_PHY=y CONFIG_USB_LGM_PHY=m CONFIG_PHY_CAN_TRANSCEIVER=m + +# +# PHY drivers for Broadcom platforms +# CONFIG_BCM_KONA_USB2_PHY=m +# end of PHY drivers for Broadcom platforms + CONFIG_PHY_PXA_28NM_HSIC=m CONFIG_PHY_PXA_28NM_USB2=m CONFIG_PHY_CPCAP_USB=m @@ -9252,8 +9794,6 @@ CONFIG_POWERCAP=y CONFIG_INTEL_RAPL_CORE=m CONFIG_INTEL_RAPL=m CONFIG_IDLE_INJECT=y -CONFIG_DTPM=y -CONFIG_DTPM_CPU=y CONFIG_MCB=m CONFIG_MCB_PCI=m CONFIG_MCB_LPC=m @@ -9273,29 +9813,26 @@ CONFIG_USB4=m # # Android # -# CONFIG_ANDROID is not set +# CONFIG_ANDROID_BINDER_IPC is not set # end of Android CONFIG_LIBNVDIMM=y CONFIG_BLK_DEV_PMEM=m -CONFIG_ND_BLK=m CONFIG_ND_CLAIM=y CONFIG_ND_BTT=m CONFIG_BTT=y CONFIG_ND_PFN=m CONFIG_NVDIMM_PFN=y CONFIG_NVDIMM_DAX=y -CONFIG_DAX_DRIVER=y CONFIG_DAX=y CONFIG_DEV_DAX=m CONFIG_DEV_DAX_PMEM=m CONFIG_DEV_DAX_HMEM=m CONFIG_DEV_DAX_HMEM_DEVICES=y CONFIG_DEV_DAX_KMEM=m -CONFIG_DEV_DAX_PMEM_COMPAT=m CONFIG_NVMEM=y CONFIG_NVMEM_SYSFS=y -CONFIG_RAVE_SP_EEPROM=m +CONFIG_NVMEM_RAVE_SP_EEPROM=m CONFIG_NVMEM_RMEM=m # @@ -9336,14 +9873,10 @@ CONFIG_FPGA_DFL_FME_REGION=m CONFIG_FPGA_DFL_AFU=m CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000=m CONFIG_FPGA_DFL_PCI=m +CONFIG_FPGA_M10_BMC_SEC_UPDATE=m +CONFIG_FPGA_MGR_MICROCHIP_SPI=m CONFIG_TEE=m - -# -# TEE drivers -# CONFIG_AMDTEE=m -# end of TEE drivers - CONFIG_MULTIPLEXER=m # @@ -9355,7 +9888,6 @@ CONFIG_MUX_GPIO=m # end of Multiplexer drivers CONFIG_PM_OPP=y -CONFIG_UNISYS_VISORBUS=m CONFIG_SIOX=m CONFIG_SIOX_BUS_GPIO=m CONFIG_SLIMBUS=m @@ -9368,6 +9900,8 @@ CONFIG_MOST=m CONFIG_MOST_USB_HDM=m CONFIG_MOST_CDEV=m CONFIG_MOST_SND=m +# CONFIG_PECI is not set +CONFIG_HTE=y # end of Device Drivers # @@ -9431,10 +9965,12 @@ CONFIG_F2FS_CHECK_FS=y # CONFIG_F2FS_FAULT_INJECTION is not set CONFIG_F2FS_FS_COMPRESSION=y CONFIG_F2FS_FS_LZO=y +CONFIG_F2FS_FS_LZORLE=y CONFIG_F2FS_FS_LZ4=y CONFIG_F2FS_FS_LZ4HC=y CONFIG_F2FS_FS_ZSTD=y -CONFIG_F2FS_FS_LZORLE=y +CONFIG_F2FS_IOSTAT=y +CONFIG_F2FS_UNFAIR_RWSEM=y CONFIG_ZONEFS_FS=m CONFIG_FS_DAX=y CONFIG_FS_DAX_PMD=y @@ -9442,7 +9978,6 @@ CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FILE_LOCKING=y -# CONFIG_MANDATORY_FILE_LOCKING is not set CONFIG_FS_ENCRYPTION=y CONFIG_FS_ENCRYPTION_ALGS=m CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y @@ -9482,12 +10017,11 @@ CONFIG_NETFS_SUPPORT=m CONFIG_NETFS_STATS=y CONFIG_FSCACHE=m CONFIG_FSCACHE_STATS=y -# CONFIG_FSCACHE_HISTOGRAM is not set # CONFIG_FSCACHE_DEBUG is not set -CONFIG_FSCACHE_OBJECT_LIST=y CONFIG_CACHEFILES=m # CONFIG_CACHEFILES_DEBUG is not set -# CONFIG_CACHEFILES_HISTOGRAM is not set +# CONFIG_CACHEFILES_ERROR_INJECTION is not set +CONFIG_CACHEFILES_ONDEMAND=y # end of Caches # @@ -9511,6 +10045,10 @@ CONFIG_FAT_DEFAULT_UTF8=y CONFIG_EXFAT_FS=m CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" # CONFIG_NTFS_FS is not set +CONFIG_NTFS3_FS=m +# CONFIG_NTFS3_64BIT_CLUSTER is not set +CONFIG_NTFS3_LZX_XPRESS=y +CONFIG_NTFS3_FS_POSIX_ACL=y # end of DOS/FAT/EXFAT/NT Filesystems # @@ -9533,8 +10071,9 @@ CONFIG_TMPFS_XATTR=y CONFIG_TMPFS_INODE64=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y -CONFIG_HUGETLB_PAGE_FREE_VMEMMAP=y -CONFIG_HUGETLB_PAGE_FREE_VMEMMAP_DEFAULT_ON=y +CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y +CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y +# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set CONFIG_MEMFD_CREATE=y CONFIG_ARCH_HAS_GIGANTIC_PAGE=y CONFIG_CONFIGFS_FS=y @@ -9621,6 +10160,11 @@ CONFIG_PSTORE_COMPRESS_DEFAULT="zstd" # CONFIG_PSTORE_PMSG is not set # CONFIG_PSTORE_FTRACE is not set CONFIG_PSTORE_RAM=m +CONFIG_PSTORE_ZONE=m +CONFIG_PSTORE_BLK=m +CONFIG_PSTORE_BLK_BLKDEV="" +CONFIG_PSTORE_BLK_KMSG_SIZE=64 +CONFIG_PSTORE_BLK_MAX_REASON=2 # CONFIG_SYSV_FS is not set CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set @@ -9631,6 +10175,8 @@ CONFIG_EROFS_FS_XATTR=y CONFIG_EROFS_FS_POSIX_ACL=y CONFIG_EROFS_FS_SECURITY=y CONFIG_EROFS_FS_ZIP=y +CONFIG_EROFS_FS_ZIP_LZMA=y +CONFIG_EROFS_FS_ONDEMAND=y CONFIG_VBOXSF_FS=m CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m @@ -9655,7 +10201,6 @@ CONFIG_NFS_DEBUG=y # CONFIG_NFS_V4_2_READ_PLUS is not set CONFIG_NFSD=m CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_PNFS=y @@ -9685,7 +10230,6 @@ CONFIG_CEPH_FS_SECURITY_LABEL=y CONFIG_CIFS=m # CONFIG_CIFS_STATS2 is not set CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_WEAK_PW_HASH is not set CONFIG_CIFS_UPCALL=y CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y @@ -9696,6 +10240,11 @@ CONFIG_CIFS_DFS_UPCALL=y CONFIG_CIFS_SWN_UPCALL=y # CONFIG_CIFS_SMB_DIRECT is not set CONFIG_CIFS_FSCACHE=y +CONFIG_SMB_SERVER=m +CONFIG_SMB_SERVER_SMBDIRECT=y +CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y +CONFIG_SMB_SERVER_KERBEROS5=y +CONFIG_SMBFS_COMMON=m CONFIG_CODA_FS=m CONFIG_AFS_FS=m # CONFIG_AFS_DEBUG is not set @@ -9757,6 +10306,7 @@ CONFIG_NLS_MAC_ROMANIAN=m CONFIG_NLS_MAC_TURKISH=m CONFIG_NLS_UTF8=m CONFIG_DLM=m +# CONFIG_DLM_DEPRECATED_API is not set CONFIG_DLM_DEBUG=y CONFIG_UNICODE=y # CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set @@ -9770,14 +10320,16 @@ CONFIG_KEYS=y CONFIG_KEYS_REQUEST_CACHE=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_TRUSTED_KEYS=m +CONFIG_TRUSTED_KEYS_TPM=y +CONFIG_TRUSTED_KEYS_TEE=y CONFIG_ENCRYPTED_KEYS=m +# CONFIG_USER_DECRYPTED_DATA is not set CONFIG_KEY_DH_OPERATIONS=y CONFIG_KEY_NOTIFICATIONS=y CONFIG_SECURITY_DMESG_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SECURITY_NETWORK=y -CONFIG_PAGE_TABLE_ISOLATION=y CONFIG_SECURITY_INFINIBAND=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_PATH=y @@ -9785,7 +10337,6 @@ CONFIG_SECURITY_PATH=y CONFIG_LSM_MMAP_MIN_ADDR=65536 CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y CONFIG_HARDENED_USERCOPY=y -CONFIG_HARDENED_USERCOPY_FALLBACK=y CONFIG_FORTIFY_SOURCE=y # CONFIG_STATIC_USERMODEHELPER is not set CONFIG_SECURITY_SELINUX=y @@ -9808,9 +10359,12 @@ CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/usr/bin/tomoyo-init" CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/usr/lib/systemd/systemd" # CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING is not set CONFIG_SECURITY_APPARMOR=y +# CONFIG_SECURITY_APPARMOR_DEBUG is not set +CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y CONFIG_SECURITY_APPARMOR_HASH=y CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y -# CONFIG_SECURITY_APPARMOR_DEBUG is not set +CONFIG_SECURITY_APPARMOR_EXPORT_BINARY=y +CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y CONFIG_SECURITY_LOADPIN=y CONFIG_SECURITY_LOADPIN_ENFORCE=y CONFIG_SECURITY_YAMA=y @@ -9821,32 +10375,48 @@ CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y # CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set # CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set CONFIG_SECURITY_LANDLOCK=y -# CONFIG_INTEGRITY is not set +CONFIG_INTEGRITY=y +CONFIG_INTEGRITY_SIGNATURE=y +CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y +CONFIG_INTEGRITY_TRUSTED_KEYRING=y +CONFIG_INTEGRITY_PLATFORM_KEYRING=y +CONFIG_INTEGRITY_MACHINE_KEYRING=y +CONFIG_LOAD_UEFI_KEYS=y +CONFIG_INTEGRITY_AUDIT=y +# CONFIG_IMA is not set +# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set # CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set +# CONFIG_EVM is not set # CONFIG_DEFAULT_SECURITY_SELINUX is not set # CONFIG_DEFAULT_SECURITY_SMACK is not set # CONFIG_DEFAULT_SECURITY_TOMOYO is not set # CONFIG_DEFAULT_SECURITY_APPARMOR is not set CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_LSM="landlock,lockdown,yama,bpf" +CONFIG_LSM="landlock,lockdown,yama,integrity,bpf" # # Kernel hardening options # -CONFIG_GCC_PLUGIN_STRUCTLEAK=y # # Memory initialization # +CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y # CONFIG_INIT_STACK_NONE is not set -# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set -# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set -CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL=y -# CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE is not set +# CONFIG_INIT_STACK_ALL_PATTERN is not set +CONFIG_INIT_STACK_ALL_ZERO=y # CONFIG_GCC_PLUGIN_STACKLEAK is not set CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y +# CONFIG_ZERO_CALL_USED_REGS is not set # end of Memory initialization + +CONFIG_RANDSTRUCT_NONE=y +# CONFIG_RANDSTRUCT_FULL is not set +# CONFIG_RANDSTRUCT_PERFORMANCE is not set # end of Kernel hardening options # end of Security options @@ -9871,7 +10441,7 @@ CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RNG_DEFAULT=m +CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AKCIPHER=y CONFIG_CRYPTO_KPP2=y @@ -9890,123 +10460,109 @@ CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_SIMD=m CONFIG_CRYPTO_ENGINE=m +# end of Crypto core or helper # # Public-key cryptography # CONFIG_CRYPTO_RSA=y CONFIG_CRYPTO_DH=y -CONFIG_CRYPTO_ECC=m +CONFIG_CRYPTO_DH_RFC7919_GROUPS=y +CONFIG_CRYPTO_ECC=y CONFIG_CRYPTO_ECDH=m -CONFIG_CRYPTO_ECDSA=m +CONFIG_CRYPTO_ECDSA=y CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_SM2=m CONFIG_CRYPTO_CURVE25519=m -CONFIG_CRYPTO_CURVE25519_X86=m +# end of Public-key cryptography # -# Authenticated Encryption with Associated Data +# Block ciphers # -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_AEGIS128=m -CONFIG_CRYPTO_AEGIS128_AESNI_SSE2=m -CONFIG_CRYPTO_SEQIV=m -CONFIG_CRYPTO_ECHAINIV=m +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_ARIA=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SM4=m +CONFIG_CRYPTO_SM4_GENERIC=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +# end of Block ciphers # -# Block modes +# Length-preserving ciphers and modes # +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_CHACHA20=m CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_CFB=m CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_HCTR2=m +CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_OFB=m CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XCTR=m CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_NHPOLY1305=m -CONFIG_CRYPTO_NHPOLY1305_SSE2=m -CONFIG_CRYPTO_NHPOLY1305_AVX2=m -CONFIG_CRYPTO_ADIANTUM=m -CONFIG_CRYPTO_ESSIV=m +# end of Length-preserving ciphers and modes # -# Hash modes +# AEAD (authenticated encryption with associated data) ciphers # -CONFIG_CRYPTO_CMAC=m -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_ECHAINIV=m +CONFIG_CRYPTO_ESSIV=m +# end of AEAD (authenticated encryption with associated data) ciphers # -# Digest +# Hashes, digests, and MACs # -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CRC32C_INTEL=m -CONFIG_CRYPTO_CRC32=m -CONFIG_CRYPTO_CRC32_PCLMUL=m -CONFIG_CRYPTO_XXHASH=m CONFIG_CRYPTO_BLAKE2B=m -CONFIG_CRYPTO_BLAKE2S=m -CONFIG_CRYPTO_BLAKE2S_X86=m -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_CRCT10DIF_PCLMUL=m +CONFIG_CRYPTO_CMAC=m CONFIG_CRYPTO_GHASH=m -CONFIG_CRYPTO_POLY1305=m -CONFIG_CRYPTO_POLY1305_X86_64=m +CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_POLYVAL=m +CONFIG_CRYPTO_POLY1305=m CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA1_SSSE3=m -CONFIG_CRYPTO_SHA256_SSSE3=m -CONFIG_CRYPTO_SHA512_SSSE3=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_SHA3=m CONFIG_CRYPTO_SM3=m +CONFIG_CRYPTO_SM3_GENERIC=m CONFIG_CRYPTO_STREEBOG=m +CONFIG_CRYPTO_VMAC=m CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XXHASH=m +# end of Hashes, digests, and MACs # -# Ciphers +# CRCs (cyclic redundancy checks) # -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m -CONFIG_CRYPTO_AES_NI_INTEL=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_BLOWFISH_COMMON=m -CONFIG_CRYPTO_BLOWFISH_X86_64=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAMELLIA_X86_64=m -CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m -CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m -CONFIG_CRYPTO_CAST_COMMON=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST5_AVX_X86_64=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_CAST6_AVX_X86_64=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_DES3_EDE_X86_64=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_CHACHA20=m -CONFIG_CRYPTO_CHACHA20_X86_64=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m -CONFIG_CRYPTO_SERPENT_AVX_X86_64=m -CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m -CONFIG_CRYPTO_SM4=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_TWOFISH_X86_64=m -CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m -CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRC64_ROCKSOFT=y +# end of CRCs (cyclic redundancy checks) # # Compression @@ -10017,17 +10573,24 @@ CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=y CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_ZSTD=y +# end of Compression # -# Random Number Generation +# Random number generation # CONFIG_CRYPTO_ANSI_CPRNG=m -CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y CONFIG_CRYPTO_DRBG_HASH=y CONFIG_CRYPTO_DRBG_CTR=y -CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_KDF800108_CTR=y +# end of Random number generation + +# +# Userspace interface +# CONFIG_CRYPTO_USER_API=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m @@ -10036,29 +10599,48 @@ CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m # CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set CONFIG_CRYPTO_STATS=y +# end of Userspace interface + CONFIG_CRYPTO_HASH_INFO=y # -# Crypto library routines +# Accelerated Cryptographic Algorithms for CPU (x86) # -CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=m -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m -CONFIG_CRYPTO_LIB_BLAKE2S=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m -CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m -CONFIG_CRYPTO_LIB_CHACHA=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m -CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m -CONFIG_CRYPTO_LIB_CURVE25519=m -CONFIG_CRYPTO_LIB_DES=m -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 -CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m -CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m -CONFIG_CRYPTO_LIB_POLY1305=m -CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m -CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_CURVE25519_X86=m +CONFIG_CRYPTO_AES_NI_INTEL=m +CONFIG_CRYPTO_BLOWFISH_X86_64=m +CONFIG_CRYPTO_CAMELLIA_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m +CONFIG_CRYPTO_CAST5_AVX_X86_64=m +CONFIG_CRYPTO_CAST6_AVX_X86_64=m +CONFIG_CRYPTO_DES3_EDE_X86_64=m +CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m +CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64=m +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m +CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m +CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_CHACHA20_X86_64=m +CONFIG_CRYPTO_AEGIS128_AESNI_SSE2=m +CONFIG_CRYPTO_NHPOLY1305_SSE2=m +CONFIG_CRYPTO_NHPOLY1305_AVX2=m +CONFIG_CRYPTO_BLAKE2S_X86=y +CONFIG_CRYPTO_POLYVAL_CLMUL_NI=m +CONFIG_CRYPTO_POLY1305_X86_64=m +CONFIG_CRYPTO_SHA1_SSSE3=m +CONFIG_CRYPTO_SHA256_SSSE3=m +CONFIG_CRYPTO_SHA512_SSSE3=m +CONFIG_CRYPTO_SM3_AVX_X86_64=m +CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRC32_PCLMUL=m +CONFIG_CRYPTO_CRCT10DIF_PCLMUL=m +# end of Accelerated Cryptographic Algorithms for CPU (x86) + CONFIG_CRYPTO_HW=y CONFIG_CRYPTO_DEV_PADLOCK=m CONFIG_CRYPTO_DEV_PADLOCK_AES=m @@ -10089,18 +10671,19 @@ CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG=y CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y -CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE=m CONFIG_X509_CERTIFICATE_PARSER=y CONFIG_PKCS8_PRIVATE_KEY_PARSER=m -CONFIG_TPM_KEY_PARSER=m CONFIG_PKCS7_MESSAGE_PARSER=y # CONFIG_PKCS7_TEST_KEY is not set CONFIG_SIGNED_PE_FILE_VERIFICATION=y +# CONFIG_FIPS_SIGNATURE_SELFTEST is not set # # Certificates for signature checking # CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" +# CONFIG_MODULE_SIG_KEY_TYPE_RSA is not set +CONFIG_MODULE_SIG_KEY_TYPE_ECDSA=y CONFIG_SYSTEM_TRUSTED_KEYRING=y CONFIG_SYSTEM_TRUSTED_KEYS="" # CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set @@ -10109,6 +10692,7 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y CONFIG_SYSTEM_BLACKLIST_HASH_LIST="" CONFIG_SYSTEM_REVOCATION_LIST=y CONFIG_SYSTEM_REVOCATION_KEYS="" +CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE=y # end of Certificates for signature checking CONFIG_BINARY_PRINTF=y @@ -10124,7 +10708,6 @@ CONFIG_BITREVERSE=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y -CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_CORDIC=m # CONFIG_PRIME_NUMBERS is not set CONFIG_RATIONAL=y @@ -10133,9 +10716,35 @@ CONFIG_GENERIC_IOMAP=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_ARCH_HAS_FAST_MULTIPLIER=y CONFIG_ARCH_USE_SYM_ANNOTATIONS=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + CONFIG_CRC_CCITT=y CONFIG_CRC16=m CONFIG_CRC_T10DIF=y +CONFIG_CRC64_ROCKSOFT=y CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC32_SELFTEST is not set @@ -10143,7 +10752,7 @@ CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set -CONFIG_CRC64=m +CONFIG_CRC64=y CONFIG_CRC4=m CONFIG_CRC7=m CONFIG_LIBCRC32C=m @@ -10159,6 +10768,7 @@ CONFIG_LZO_DECOMPRESS=y CONFIG_LZ4_COMPRESS=y CONFIG_LZ4HC_COMPRESS=m CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_COMMON=y CONFIG_ZSTD_COMPRESS=y CONFIG_ZSTD_DECOMPRESS=y CONFIG_XZ_DEC=y @@ -10168,6 +10778,7 @@ CONFIG_XZ_DEC_IA64=y CONFIG_XZ_DEC_ARM=y CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_MICROLZMA=y CONFIG_XZ_DEC_BCJ=y # CONFIG_XZ_DEC_TEST is not set CONFIG_DECOMPRESS_GZIP=y @@ -10216,6 +10827,7 @@ CONFIG_CMA_ALIGNMENT=8 # CONFIG_DMA_MAP_BENCHMARK is not set CONFIG_SGL_ALLOC=y CONFIG_CHECK_SIGNATURE=y +# CONFIG_FORCE_NR_CPUS is not set CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y @@ -10225,6 +10837,7 @@ CONFIG_LRU_CACHE=m CONFIG_CLZ_TAB=y CONFIG_IRQ_POLL=y CONFIG_MPILIB=y +CONFIG_SIGNATURE=y CONFIG_DIMLIB=y CONFIG_OID_REGISTRY=y CONFIG_UCS2_STRING=y @@ -10252,6 +10865,7 @@ CONFIG_MEMREGION=y CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y CONFIG_ARCH_HAS_COPY_MC=y CONFIG_ARCH_STACKWALK=y +CONFIG_STACKDEPOT=y CONFIG_SBITMAP=y CONFIG_PARMAN=m CONFIG_OBJAGG=m @@ -10259,6 +10873,7 @@ CONFIG_OBJAGG=m CONFIG_PLDMFW=y CONFIG_ASN1_ENCODER=m +CONFIG_POLYNOMIAL=m # # Kernel hacking @@ -10280,18 +10895,25 @@ CONFIG_SYMBOLIC_ERRNAME=y CONFIG_DEBUG_BUGVERBOSE=y # end of printk and dmesg options +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_MISC is not set + # # Compile-time checks and compiler options # CONFIG_DEBUG_INFO=y +CONFIG_AS_HAS_NON_CONST_LEB128=y +# CONFIG_DEBUG_INFO_NONE is not set +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +CONFIG_DEBUG_INFO_DWARF5=y # CONFIG_DEBUG_INFO_REDUCED is not set # CONFIG_DEBUG_INFO_COMPRESSED is not set # CONFIG_DEBUG_INFO_SPLIT is not set -# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set -CONFIG_DEBUG_INFO_DWARF4=y CONFIG_DEBUG_INFO_BTF=y CONFIG_PAHOLE_HAS_SPLIT_BTF=y CONFIG_DEBUG_INFO_BTF_MODULES=y +# CONFIG_MODULE_ALLOW_BTF_MISMATCH is not set # CONFIG_GDB_SCRIPTS is not set CONFIG_FRAME_WARN=2048 CONFIG_STRIP_ASM_SYMS=y @@ -10299,7 +10921,7 @@ CONFIG_STRIP_ASM_SYMS=y # CONFIG_HEADERS_INSTALL is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y -CONFIG_STACK_VALIDATION=y +CONFIG_OBJTOOL=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # end of Compile-time checks and compiler options @@ -10323,15 +10945,23 @@ CONFIG_HAVE_KCSAN_COMPILER=y # CONFIG_KCSAN is not set # end of Generic Kernel Debugging Instruments -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_MISC is not set +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging # # Memory Debugging # # CONFIG_PAGE_EXTENSION is not set # CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set # CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_TABLE_CHECK is not set CONFIG_PAGE_POISONING=y # CONFIG_DEBUG_PAGE_REF is not set CONFIG_DEBUG_RODATA_TEST=y @@ -10341,8 +10971,7 @@ CONFIG_GENERIC_PTDUMP=y CONFIG_PTDUMP_CORE=y # CONFIG_PTDUMP_DEBUGFS is not set # CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set +CONFIG_SHRINKER_DEBUG=y CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_STACK_USAGE is not set @@ -10363,10 +10992,11 @@ CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y # CONFIG_KASAN is not set CONFIG_HAVE_ARCH_KFENCE=y CONFIG_KFENCE=y -CONFIG_KFENCE_STATIC_KEYS=y CONFIG_KFENCE_SAMPLE_INTERVAL=100 CONFIG_KFENCE_NUM_OBJECTS=255 +CONFIG_KFENCE_DEFERRABLE=y CONFIG_KFENCE_STRESS_TEST_FAULTS=0 +CONFIG_HAVE_ARCH_KMSAN=y # end of Memory Debugging CONFIG_DEBUG_SHIRQ=y @@ -10380,16 +11010,13 @@ CONFIG_PANIC_TIMEOUT=0 CONFIG_LOCKUP_DETECTOR=y CONFIG_SOFTLOCKUP_DETECTOR=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 CONFIG_HARDLOCKUP_DETECTOR_PERF=y CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y CONFIG_HARDLOCKUP_DETECTOR=y # CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 CONFIG_DETECT_HUNG_TASK=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 # CONFIG_WQ_WATCHDOG is not set # CONFIG_TEST_LOCKUP is not set # end of Debug Oops, Lockups and Hangs @@ -10438,6 +11065,7 @@ CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_DEBUG_MAPLE_TREE is not set # end of Debug kernel data structures # CONFIG_DEBUG_CREDENTIALS is not set @@ -10449,27 +11077,32 @@ CONFIG_DEBUG_LIST=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_REF_SCALE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 # CONFIG_RCU_TRACE is not set # CONFIG_RCU_EQS_DEBUG is not set # end of RCU Debugging # CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set CONFIG_LATENCYTOP=y CONFIG_USER_STACKTRACE_SUPPORT=y CONFIG_NOP_TRACER=y +CONFIG_HAVE_RETHOOK=y +CONFIG_RETHOOK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_FENTRY=y CONFIG_HAVE_OBJTOOL_MCOUNT=y CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y +CONFIG_BUILDTIME_MCOUNT_SORT=y CONFIG_TRACER_MAX_TRACE=y CONFIG_TRACE_CLOCK=y CONFIG_RING_BUFFER=y @@ -10486,6 +11119,7 @@ CONFIG_DYNAMIC_FTRACE=y CONFIG_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_FPROBE=y CONFIG_FUNCTION_PROFILER=y CONFIG_STACK_TRACER=y # CONFIG_IRQSOFF_TRACER is not set @@ -10519,6 +11153,7 @@ CONFIG_HIST_TRIGGERS=y # CONFIG_TRACE_EVAL_MAP_FILE is not set # CONFIG_FTRACE_RECORD_RECURSION is not set # CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_FTRACE_SORT_STARTUP_TEST is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set # CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set # CONFIG_MMIOTRACE_TEST is not set @@ -10526,8 +11161,11 @@ CONFIG_HIST_TRIGGERS=y # CONFIG_SYNTH_EVENT_GEN_TEST is not set # CONFIG_KPROBE_EVENT_GEN_TEST is not set # CONFIG_HIST_TRIGGERS_DEBUG is not set +# CONFIG_RV is not set # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set # CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y CONFIG_STRICT_DEVMEM=y CONFIG_IO_STRICT_DEVMEM=y @@ -10535,8 +11173,6 @@ CONFIG_IO_STRICT_DEVMEM=y # # x86 Debugging # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y CONFIG_EARLY_PRINTK_USB=y # CONFIG_X86_VERBOSE_BOOTUP is not set CONFIG_EARLY_PRINTK=y @@ -10573,10 +11209,9 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_LKDTM is not set # CONFIG_TEST_MIN_HEAP is not set -# CONFIG_TEST_SORT is not set # CONFIG_TEST_DIV64 is not set -# CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_TEST_REF_TRACKER is not set # CONFIG_RBTREE_TEST is not set # CONFIG_REED_SOLOMON_TEST is not set # CONFIG_INTERVAL_TREE_TEST is not set @@ -10593,9 +11228,9 @@ CONFIG_ASYNC_RAID6_TEST=m # CONFIG_TEST_BITMAP is not set # CONFIG_TEST_UUID is not set # CONFIG_TEST_XARRAY is not set -# CONFIG_TEST_OVERFLOW is not set +# CONFIG_TEST_MAPLE_TREE is not set # CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_HASH is not set +# CONFIG_TEST_SIPHASH is not set # CONFIG_TEST_IDA is not set # CONFIG_TEST_PARMAN is not set # CONFIG_TEST_LKM is not set @@ -10609,17 +11244,22 @@ CONFIG_ASYNC_RAID6_TEST=m # CONFIG_TEST_SYSCTL is not set # CONFIG_TEST_UDELAY is not set # CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_TEST_DYNAMIC_DEBUG is not set # CONFIG_TEST_KMOD is not set # CONFIG_TEST_MEMCAT_P is not set # CONFIG_TEST_OBJAGG is not set -# CONFIG_TEST_STACKINIT is not set # CONFIG_TEST_MEMINIT is not set # CONFIG_TEST_HMM is not set # CONFIG_TEST_FREE_PAGES is not set # CONFIG_TEST_FPU is not set # CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set CONFIG_ARCH_USE_MEMTEST=y -# CONFIG_MEMTEST is not set +CONFIG_MEMTEST=y # CONFIG_HYPERV_TESTING is not set # end of Kernel Testing and Coverage + +# +# Rust hacking +# +# end of Rust hacking # end of Kernel hacking diff --git a/sys-kernel_arch-sources-g14_files-0004-5.8+--more-uarches-for-kernel.patch b/sys-kernel_arch-sources-g14_files-0004-5.17+--more-uarches-for-kernel.patch index c45d13bf417a..b9c03cb605f3 100644 --- a/sys-kernel_arch-sources-g14_files-0004-5.8+--more-uarches-for-kernel.patch +++ b/sys-kernel_arch-sources-g14_files-0004-5.17+--more-uarches-for-kernel.patch @@ -1,7 +1,7 @@ -From 4af44fbc97bc51eb742f0d6555bde23cf580d4e3 Mon Sep 17 00:00:00 2001 +From b5892719c43f739343c628e3d357471a3bdaa368 Mon Sep 17 00:00:00 2001 From: graysky <graysky@archlinux.us> -Date: Sun, 6 Jun 2021 09:41:36 -0400 -Subject: [PATCH] more uarches for kernel 5.8+ +Date: Tue, 15 Mar 2022 05:58:43 -0400 +Subject: [PATCH] more uarches for kernel 5.17+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -86,7 +86,7 @@ See the following experimental evidence supporting this statement: https://github.com/graysky2/kernel_gcc_patch REQUIREMENTS -linux version >=5.8 +linux version 5.17+ gcc version >=9.0 or clang version >=9.0 ACKNOWLEDGMENTS @@ -102,12 +102,12 @@ REFERENCES Signed-off-by: graysky <graysky@archlinux.us> --- arch/x86/Kconfig.cpu | 332 ++++++++++++++++++++++++++++++-- - arch/x86/Makefile | 47 ++++- + arch/x86/Makefile | 40 +++- arch/x86/include/asm/vermagic.h | 66 +++++++ - 3 files changed, 428 insertions(+), 17 deletions(-) + 3 files changed, 424 insertions(+), 14 deletions(-) diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu -index 814fe0d349b0..8acf6519d279 100644 +index 542377cd419d..22b919cdb6d1 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -157,7 +157,7 @@ config MPENTIUM4 @@ -219,7 +219,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config MZEN3 + bool "AMD Zen 3" -+ depends on ( CC_IS_GCC && GCC_VERSION >= 100300 ) || ( CC_IS_CLANG && CLANG_VERSION >= 120000 ) ++ depends on (CC_IS_GCC && GCC_VERSION >= 100300) || (CC_IS_CLANG && CLANG_VERSION >= 120000) + help + Select this for AMD Family 19h Zen 3 processors. + @@ -378,7 +378,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config MCOOPERLAKE + bool "Intel Cooper Lake" -+ depends on ( CC_IS_GCC && GCC_VERSION > 100100 ) || ( CC_IS_CLANG && CLANG_VERSION >= 100000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 100100) || (CC_IS_CLANG && CLANG_VERSION >= 100000) + select X86_P6_NOP + help + @@ -388,7 +388,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config MTIGERLAKE + bool "Intel Tiger Lake" -+ depends on ( CC_IS_GCC && GCC_VERSION > 100100 ) || ( CC_IS_CLANG && CLANG_VERSION >= 100000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 100100) || (CC_IS_CLANG && CLANG_VERSION >= 100000) + select X86_P6_NOP + help + @@ -398,7 +398,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config MSAPPHIRERAPIDS + bool "Intel Sapphire Rapids" -+ depends on ( CC_IS_GCC && GCC_VERSION > 110000 ) || ( CC_IS_CLANG && CLANG_VERSION >= 120000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000) + select X86_P6_NOP + help + @@ -408,7 +408,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config MROCKETLAKE + bool "Intel Rocket Lake" -+ depends on ( CC_IS_GCC && GCC_VERSION > 110000 ) || ( CC_IS_CLANG && CLANG_VERSION >= 120000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000) + select X86_P6_NOP + help + @@ -418,7 +418,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config MALDERLAKE + bool "Intel Alder Lake" -+ depends on ( CC_IS_GCC && GCC_VERSION > 110000 ) || ( CC_IS_CLANG && CLANG_VERSION >= 120000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000) + select X86_P6_NOP + help + @@ -435,7 +435,7 @@ index 814fe0d349b0..8acf6519d279 100644 +config GENERIC_CPU2 + bool "Generic-x86-64-v2" -+ depends on ( CC_IS_GCC && GCC_VERSION > 110000 ) || ( CC_IS_CLANG && LANG_VERSION >= 120000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000) + depends on X86_64 + help + Generic x86-64 CPU. @@ -443,7 +443,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config GENERIC_CPU3 + bool "Generic-x86-64-v3" -+ depends on ( CC_IS_GCC && GCC_VERSION > 110000 ) || ( CC_IS_CLANG && LANG_VERSION >= 120000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000) + depends on X86_64 + help + Generic x86-64-v3 CPU with v3 instructions. @@ -451,7 +451,7 @@ index 814fe0d349b0..8acf6519d279 100644 + +config GENERIC_CPU4 + bool "Generic-x86-64-v4" -+ depends on ( CC_IS_GCC && GCC_VERSION > 110000 ) || ( CC_IS_CLANG && LANG_VERSION >= 120000 ) ++ depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000) + depends on X86_64 + help + Generic x86-64 CPU with v4 instructions. @@ -501,9 +501,9 @@ index 814fe0d349b0..8acf6519d279 100644 - 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 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD - config X86_USE_3DNOW - def_bool y -@@ -360,26 +668,26 @@ config X86_USE_3DNOW + # + # P6_NOPs are a relatively minor optimization that require a family >= +@@ -356,26 +664,26 @@ config X86_USE_PPRO_CHECKSUM config X86_P6_NOP def_bool y depends on X86_64 @@ -536,61 +536,54 @@ index 814fe0d349b0..8acf6519d279 100644 default "4" diff --git a/arch/x86/Makefile b/arch/x86/Makefile -index 78faf9c7e3ae..ee0cd507af8b 100644 +index e84cdd409b64..7d3bbf060079 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile -@@ -114,11 +114,48 @@ else +@@ -131,8 +131,44 @@ else # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) - cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) - cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) -- -- cflags-$(CONFIG_MCORE2) += \ -- $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) -- cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \ -- $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) -+ cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3) -+ cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10) -+ cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona) -+ cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1) -+ cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2) -+ cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1) -+ cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2) -+ cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-mno-tbm) -+ cflags-$(CONFIG_MSTEAMROLLER) += $(call cc-option,-march=bdver3) -+ cflags-$(CONFIG_MSTEAMROLLER) += $(call cc-option,-mno-tbm) -+ cflags-$(CONFIG_MEXCAVATOR) += $(call cc-option,-march=bdver4) -+ cflags-$(CONFIG_MEXCAVATOR) += $(call cc-option,-mno-tbm) -+ cflags-$(CONFIG_MZEN) += $(call cc-option,-march=znver1) -+ cflags-$(CONFIG_MZEN2) += $(call cc-option,-march=znver2) -+ cflags-$(CONFIG_MZEN3) += $(call cc-option,-march=znver3) -+ -+ cflags-$(CONFIG_MNATIVE_INTEL) += $(call cc-option,-march=native) -+ cflags-$(CONFIG_MNATIVE_AMD) += $(call cc-option,-march=native) -+ cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell) -+ cflags-$(CONFIG_MCORE2) += $(call cc-option,-march=core2) -+ cflags-$(CONFIG_MNEHALEM) += $(call cc-option,-march=nehalem) -+ cflags-$(CONFIG_MWESTMERE) += $(call cc-option,-march=westmere) -+ cflags-$(CONFIG_MSILVERMONT) += $(call cc-option,-march=silvermont) -+ cflags-$(CONFIG_MGOLDMONT) += $(call cc-option,-march=goldmont) -+ cflags-$(CONFIG_MGOLDMONTPLUS) += $(call cc-option,-march=goldmont-plus) -+ cflags-$(CONFIG_MSANDYBRIDGE) += $(call cc-option,-march=sandybridge) -+ cflags-$(CONFIG_MIVYBRIDGE) += $(call cc-option,-march=ivybridge) -+ cflags-$(CONFIG_MHASWELL) += $(call cc-option,-march=haswell) -+ cflags-$(CONFIG_MBROADWELL) += $(call cc-option,-march=broadwell) -+ cflags-$(CONFIG_MSKYLAKE) += $(call cc-option,-march=skylake) -+ cflags-$(CONFIG_MSKYLAKEX) += $(call cc-option,-march=skylake-avx512) -+ cflags-$(CONFIG_MCANNONLAKE) += $(call cc-option,-march=cannonlake) -+ cflags-$(CONFIG_MICELAKE) += $(call cc-option,-march=icelake-client) -+ cflags-$(CONFIG_MCASCADELAKE) += $(call cc-option,-march=cascadelake) -+ cflags-$(CONFIG_MCOOPERLAKE) += $(call cc-option,-march=cooperlake) -+ cflags-$(CONFIG_MTIGERLAKE) += $(call cc-option,-march=tigerlake) -+ cflags-$(CONFIG_MSAPPHIRERAPIDS) += $(call cc-option,-march=sapphirerapids) -+ cflags-$(CONFIG_MROCKETLAKE) += $(call cc-option,-march=rocketlake) -+ cflags-$(CONFIG_MALDERLAKE) += $(call cc-option,-march=alderlake) -+ cflags-$(CONFIG_GENERIC_CPU2) += $(call cc-option,-march=x86-64-v2) -+ cflags-$(CONFIG_GENERIC_CPU3) += $(call cc-option,-march=x86-64-v3) -+ cflags-$(CONFIG_GENERIC_CPU4) += $(call cc-option,-march=x86-64-v4) - cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) + cflags-$(CONFIG_MK8) += -march=k8 + cflags-$(CONFIG_MPSC) += -march=nocona +- cflags-$(CONFIG_MCORE2) += -march=core2 +- cflags-$(CONFIG_MATOM) += -march=atom ++ cflags-$(CONFIG_MK8SSE3) += -march=k8-sse3 ++ cflags-$(CONFIG_MK10) += -march=amdfam10 ++ cflags-$(CONFIG_MBARCELONA) += -march=barcelona ++ cflags-$(CONFIG_MBOBCAT) += -march=btver1 ++ cflags-$(CONFIG_MJAGUAR) += -march=btver2 ++ cflags-$(CONFIG_MBULLDOZER) += -march=bdver1 ++ cflags-$(CONFIG_MPILEDRIVER) += -march=bdver2 -mno-tbm ++ cflags-$(CONFIG_MSTEAMROLLER) += -march=bdver3 -mno-tbm ++ cflags-$(CONFIG_MEXCAVATOR) += -march=bdver4 -mno-tbm ++ cflags-$(CONFIG_MZEN) += -march=znver1 ++ cflags-$(CONFIG_MZEN2) += -march=znver2 ++ cflags-$(CONFIG_MZEN3) += -march=znver3 ++ cflags-$(CONFIG_MNATIVE_INTEL) += -march=native ++ cflags-$(CONFIG_MNATIVE_AMD) += -march=native ++ cflags-$(CONFIG_MATOM) += -march=bonnell ++ cflags-$(CONFIG_MCORE2) += -march=core2 ++ cflags-$(CONFIG_MNEHALEM) += -march=nehalem ++ cflags-$(CONFIG_MWESTMERE) += -march=westmere ++ cflags-$(CONFIG_MSILVERMONT) += -march=silvermont ++ cflags-$(CONFIG_MGOLDMONT) += -march=goldmont ++ cflags-$(CONFIG_MGOLDMONTPLUS) += -march=goldmont-plus ++ cflags-$(CONFIG_MSANDYBRIDGE) += -march=sandybridge ++ cflags-$(CONFIG_MIVYBRIDGE) += -march=ivybridge ++ cflags-$(CONFIG_MHASWELL) += -march=haswell ++ cflags-$(CONFIG_MBROADWELL) += -march=broadwell ++ cflags-$(CONFIG_MSKYLAKE) += -march=skylake ++ cflags-$(CONFIG_MSKYLAKEX) += -march=skylake-avx512 ++ cflags-$(CONFIG_MCANNONLAKE) += -march=cannonlake ++ cflags-$(CONFIG_MICELAKE) += -march=icelake-client ++ cflags-$(CONFIG_MCASCADELAKE) += -march=cascadelake ++ cflags-$(CONFIG_MCOOPERLAKE) += -march=cooperlake ++ cflags-$(CONFIG_MTIGERLAKE) += -march=tigerlake ++ cflags-$(CONFIG_MSAPPHIRERAPIDS) += -march=sapphirerapids ++ cflags-$(CONFIG_MROCKETLAKE) += -march=rocketlake ++ cflags-$(CONFIG_MALDERLAKE) += -march=alderlake ++ cflags-$(CONFIG_GENERIC_CPU2) += -march=x86-64-v2 ++ cflags-$(CONFIG_GENERIC_CPU3) += -march=x86-64-v3 ++ cflags-$(CONFIG_GENERIC_CPU4) += -march=x86-64-v4 + cflags-$(CONFIG_GENERIC_CPU) += -mtune=generic KBUILD_CFLAGS += $(cflags-y) diff --git a/arch/x86/include/asm/vermagic.h b/arch/x86/include/asm/vermagic.h @@ -678,5 +671,5 @@ index 75884d2cdec3..4e6a08d4c7e5 100644 #define MODULE_PROC_FAMILY "ELAN " #elif defined CONFIG_MCRUSOE -- -2.31.1 +2.35.1 diff --git a/sys-kernel_arch-sources-g14_files-0005-lru-multi-generational.patch b/sys-kernel_arch-sources-g14_files-0005-lru-multi-generational.patch deleted file mode 100644 index c764e595c7cf..000000000000 --- a/sys-kernel_arch-sources-g14_files-0005-lru-multi-generational.patch +++ /dev/null @@ -1,5006 +0,0 @@ -From 57f053bd03e8f7f071afa1f37df96f202776206f Mon Sep 17 00:00:00 2001 -From: Scott B <arglebargle@arglebargle.dev> -Date: Sat, 4 Sep 2021 11:32:55 -0700 -Subject: [PATCH] mm: multigenerational lru: v4 for 5.14.y - -Squashed commit of the following: - -commit 3dc3dbb33be3f97bac25ad0f3c46d78baf34d402 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:07 2021 -0600 - - mm: multigenerational lru: documentation - - Add Documentation/vm/multigen_lru.rst. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 96271be92ae9f9d03a83087c49b5524dd50499e9 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:06 2021 -0600 - - mm: multigenerational lru: Kconfig - - Add configuration options for the multigenerational lru. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit f5bd50edc2363203a368dbfd313f966357d18879 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:05 2021 -0600 - - mm: multigenerational lru: user interface - - Add /sys/kernel/mm/lru_gen/enabled to enable and disable the - multigenerational lru at runtime. - - Add /sys/kernel/mm/lru_gen/min_ttl_ms to protect the working set of a - given number of milliseconds. The OOM killer is invoked if this - working set cannot be kept in memory. - - Add /sys/kernel/debug/lru_gen to monitor the multigenerational lru and - invoke the aging and the eviction. This file has the following output: - memcg memcg_id memcg_path - node node_id - min_gen birth_time anon_size file_size - ... - max_gen birth_time anon_size file_size - - min_gen is the oldest generation number and max_gen is the youngest - generation number. birth_time is in milliseconds. anon_size and - file_size are in pages. - - This file takes the following input: - + memcg_id node_id max_gen [swappiness] - - memcg_id node_id min_gen [swappiness] [nr_to_reclaim] - - The first command line invokes the aging, which scans PTEs for - accessed pages and then creates the next generation max_gen+1. A swap - file and a non-zero swappiness, which overrides vm.swappiness, are - required to scan PTEs mapping anon pages. The second command line - invokes the eviction, which evicts generations less than or equal to - min_gen. min_gen should be less than max_gen-1 as max_gen and - max_gen-1 are not fully aged and therefore cannot be evicted. - nr_to_reclaim can be used to limit the number of pages to evict. - Multiple command lines are supported, as is concatenation with - delimiters "," and ";". - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 9e86a22600d8821d1627a6207ff5ffb35d23bfe8 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:04 2021 -0600 - - mm: multigenerational lru: eviction - - The eviction consumes old generations. Given an lruvec, the eviction - scans pages on lrugen->lists indexed by anon and file min_seq[2] - (modulo MAX_NR_GENS). It first tries to select a type based on the - values of min_seq[2]. If they are equal, it selects the type that has - a lower refault rate. The eviction sorts a page according to its - updated generation number if the aging has found this page accessed. - It also moves a page to the next generation if this page is from an - upper tier that has a higher refault rate than the base tier. The - eviction increments min_seq[2] of a selected type when it finds - lrugen->lists indexed by min_seq[2] of this selected type are empty. - - With the aging and the eviction in place, implementing page reclaim - becomes quite straightforward: - 1) To reduce the latency, direct reclaim skips the aging unless both - min_seq[2] are equal to max_seq-1. Then it invokes the eviction. - 2) To avoid the aging in the direct reclaim path, kswapd invokes the - aging if either of min_seq[2] is equal to max_seq-1. Then it invokes - the eviction. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 2543d9375988fcc4319de01eadf201c6653ffdf3 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:03 2021 -0600 - - mm: multigenerational lru: aging - - The aging produces young generations. Given an lruvec, the aging - traverses lruvec_memcg()->mm_list and calls walk_page_range() to scan - PTEs for accessed pages. Upon finding one, the aging updates its - generation number to max_seq (modulo MAX_NR_GENS). After each round of - traversal, the aging increments max_seq. The aging is due when both - min_seq[2] have caught up with max_seq-1. - - The aging uses the following optimizations when walking page tables: - 1) It skips page tables of processes that have been sleeping since - the last walk. - 2) It skips non-leaf PMD entries that have the accessed bit cleared - when CONFIG_HAVE_ARCH_PARENT_PMD_YOUNG=y. - 3) It does not zigzag between a PGD table and the same PMD or PTE - table spanning multiple VMAs. In other words, it finishes all the - VMAs within the range of the same PMD or PTE table before it returns - to this PGD table. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 468ccfd7e0987448ef57d368f74b2d98d21cdc03 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:02 2021 -0600 - - mm: multigenerational lru: mm_struct list - - To scan PTEs for accessed pages, a mm_struct list is maintained for - each memcg. When multiple threads traverse the same memcg->mm_list, - each of them gets a unique mm_struct and therefore they can run - walk_page_range() concurrently to reach page tables of all processes - of this memcg. - - And to skip page tables of processes that have been sleeping since the - last walk, the usage of mm_struct is also tracked between context - switches. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 1faa209bc96a6da1612c453b0ac41d10595959f1 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:01 2021 -0600 - - mm: multigenerational lru: protection - - The protection is based on page access types and patterns. There are - two access types: one via page tables and the other via file - descriptors. The protection of the former type is by design stronger - because: - 1) The uncertainty in determining the access patterns of the former - type is higher due to the coalesced nature of the accessed bit. - 2) The cost of evicting the former type is higher due to the TLB - flushes required and the likelihood of involving I/O. - 3) The penalty of under-protecting the former type is higher because - applications usually do not prepare themselves for major faults like - they do for blocked I/O. For example, client applications commonly - dedicate blocked I/O to separate threads to avoid UI janks that - negatively affect user experience. - - There are also two access patterns: one with temporal locality and the - other without. The latter pattern, e.g., random and sequential, needs - to be explicitly excluded to avoid weakening the protection of the - former pattern. Generally the former type follows the former pattern - unless MADV_SEQUENTIAL is specified and the latter type follows the - latter pattern unless outlying refaults have been observed. - - Upon faulting, a page is added to the youngest generation, which - provides the strongest protection as the eviction will not consider - this page before the aging has scanned it at least twice. The first - scan clears the accessed bit set during the initial fault. And the - second scan makes sure this page has not been used since the first - scan. A page from any other generations is brought back to the - youngest generation whenever the aging finds the accessed bit set on - any of the PTEs mapping this page. - - Unmapped pages are initially added to the oldest generation and then - conditionally protected by tiers. Pages accessed N times via file - descriptors belong to tier order_base_2(N). Each tier keeps track of - how many pages from it have refaulted. Tier 0 is the base tier and - pages from it are evicted unconditionally because there are no better - candidates. Pages from an upper tier are either evicted or moved to - the next generation, depending on whether this upper tier has a higher - refault rate than the base tier. This model has the following - advantages: - 1) It removes the cost in the buffered access path and reduces the - overall cost of protection because pages are conditionally protected - in the reclaim path. - 2) It takes mapped pages into account and avoids overprotecting - pages accessed multiple times via file descriptors. - 3 Additional tiers improve the protection of pages accessed more - than twice. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 80b0b1cbfaaedf3c4f2ab10c1c9e405173a5b200 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:31:00 2021 -0600 - - mm: multigenerational lru: groundwork - - For each lruvec, evictable pages are divided into multiple - generations. The youngest generation number is stored in - lrugen->max_seq for both anon and file types as they are aged on an - equal footing. The oldest generation numbers are stored in - lrugen->min_seq[2] separately for anon and file types as clean file - pages can be evicted regardless of swap and writeback constraints. - These three variables are monotonically increasing. Generation numbers - are truncated into order_base_2(MAX_NR_GENS+1) bits in order to fit - into page->flags. The sliding window technique is used to prevent - truncated generation numbers from overlapping. Each truncated - generation number is an index to - lrugen->lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]. - - Each generation is then divided into multiple tiers. Tiers represent - levels of usage from file descriptors only. Pages accessed N times via - file descriptors belong to tier order_base_2(N). Each generation - contains at most MAX_NR_TIERS tiers, and they require additional - MAX_NR_TIERS-2 bits in page->flags. In contrast to moving across - generations which requires list operations, moving across tiers only - involves operations on page->flags and therefore has a negligible - cost. A feedback loop modeled after the PID controller monitors - refault rates of all tiers and decides when to protect pages from - which tiers. - - The framework comprises two conceptually independent components: the - aging and the eviction, which can be invoked separately from user - space for the purpose of working set estimation and proactive reclaim. - - The aging produces young generations. Given an lruvec, the aging - traverses lruvec_memcg()->mm_list and calls walk_page_range() to scan - PTEs for accessed pages (a mm_struct list is maintained for each - memcg). Upon finding one, the aging updates its generation number to - max_seq (modulo MAX_NR_GENS). After each round of traversal, the aging - increments max_seq. The aging is due when both min_seq[2] have caught - up with max_seq-1. - - The eviction consumes old generations. Given an lruvec, the eviction - scans pages on lrugen->lists indexed by anon and file min_seq[2] - (modulo MAX_NR_GENS). It first tries to select a type based on the - values of min_seq[2]. If they are equal, it selects the type that has - a lower refault rate. The eviction sorts a page according to its - updated generation number if the aging has found this page accessed. - It also moves a page to the next generation if this page is from an - upper tier that has a higher refault rate than the base tier. The - eviction increments min_seq[2] of a selected type when it finds - lrugen->lists indexed by min_seq[2] of this selected type are empty. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 7ca2c4587a3a64417bcbecc415c25a685b8ec2d9 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:30:59 2021 -0600 - - mm/vmscan.c: refactor shrink_node() - - This patch refactors shrink_node(). This will make the upcoming - changes to mm/vmscan.c more readable. - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit d56b7b3475793aaa5bfb40856d620a40edfbb4c0 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:30:58 2021 -0600 - - mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG - - Some architectures support the accessed bit on non-leaf PMD entries, - e.g., x86_64 sets the accessed bit on a non-leaf PMD entry when using - it as part of linear address translation [1]. As an optimization, page - table walkers who are interested in the accessed bit can skip the PTEs - under a non-leaf PMD entry if the accessed bit is cleared on this - non-leaf PMD entry. - - Although an inline function may be preferable, this capability is - added as a configuration option to look consistent when used with the - existing macros. - - [1]: Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 3 (October 2019), section 4.8 - - Signed-off-by: Yu Zhao <yuzhao@google.com> - Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> - -commit 8bf795e4c3243e2b4539c3e4e4de2b8d7efd04b9 -Author: Yu Zhao <yuzhao@google.com> -Date: Wed Aug 18 00:30:57 2021 -0600 - - mm: x86, arm64: add arch_has_hw_pte_young() - - Some architectures set the accessed bit in PTEs automatically, e.g., - x86, and arm64 v8.2 and later. On architectures that do not have this - capability, clearing the accessed bit in a PTE triggers a page fault - following the TLB miss. - - Being aware of this capability can help make better decisions, i.e., - whether to limit the size of each batch of PTEs and the burst of - batches when clearing the accessed bit. - - Signed-off-by: Yu Zhao <yuzhao@google.com> ---- - Documentation/vm/index.rst | 1 + - Documentation/vm/multigen_lru.rst | 134 ++ - arch/Kconfig | 9 + - arch/arm64/include/asm/cpufeature.h | 19 +- - arch/arm64/include/asm/pgtable.h | 10 +- - arch/arm64/kernel/cpufeature.c | 19 + - arch/arm64/mm/proc.S | 12 - - arch/arm64/tools/cpucaps | 1 + - arch/x86/Kconfig | 1 + - arch/x86/include/asm/pgtable.h | 9 +- - arch/x86/mm/pgtable.c | 5 +- - fs/exec.c | 2 + - fs/fuse/dev.c | 3 +- - include/linux/cgroup.h | 15 +- - include/linux/memcontrol.h | 9 + - include/linux/mm.h | 34 + - include/linux/mm_inline.h | 201 ++ - include/linux/mm_types.h | 107 ++ - include/linux/mmzone.h | 103 ++ - include/linux/nodemask.h | 1 + - include/linux/oom.h | 16 + - include/linux/page-flags-layout.h | 19 +- - include/linux/page-flags.h | 4 +- - include/linux/pgtable.h | 16 +- - include/linux/sched.h | 3 + - include/linux/swap.h | 1 + - kernel/bounds.c | 3 + - kernel/cgroup/cgroup-internal.h | 1 - - kernel/exit.c | 1 + - kernel/fork.c | 10 + - kernel/kthread.c | 1 + - kernel/sched/core.c | 2 + - mm/Kconfig | 59 + - mm/huge_memory.c | 3 +- - mm/memcontrol.c | 28 + - mm/memory.c | 21 +- - mm/mm_init.c | 6 +- - mm/mmzone.c | 2 + - mm/oom_kill.c | 4 +- - mm/rmap.c | 7 + - mm/swap.c | 55 +- - mm/swapfile.c | 2 + - mm/vmscan.c | 2674 ++++++++++++++++++++++++++- - mm/workingset.c | 119 +- - 44 files changed, 3591 insertions(+), 161 deletions(-) - create mode 100644 Documentation/vm/multigen_lru.rst - -diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst -index eff5fbd492d0..c353b3f55924 100644 ---- a/Documentation/vm/index.rst -+++ b/Documentation/vm/index.rst -@@ -17,6 +17,7 @@ various features of the Linux memory management - - swap_numa - zswap -+ multigen_lru - - Kernel developers MM documentation - ================================== -diff --git a/Documentation/vm/multigen_lru.rst b/Documentation/vm/multigen_lru.rst -new file mode 100644 -index 000000000000..adedff5319d9 ---- /dev/null -+++ b/Documentation/vm/multigen_lru.rst -@@ -0,0 +1,134 @@ -+.. SPDX-License-Identifier: GPL-2.0 -+ -+===================== -+Multigenerational LRU -+===================== -+ -+Quick Start -+=========== -+Build Configurations -+-------------------- -+:Required: Set ``CONFIG_LRU_GEN=y``. -+ -+:Optional: Set ``CONFIG_LRU_GEN_ENABLED=y`` to turn the feature on by -+ default. -+ -+Runtime Configurations -+---------------------- -+:Required: Write ``1`` to ``/sys/kernel/mm/lru_gen/enable`` if the -+ feature was not turned on by default. -+ -+:Optional: Write ``N`` to ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to -+ protect the working set of ``N`` milliseconds. The OOM killer is -+ invoked if this working set cannot be kept in memory. -+ -+:Optional: Read ``/sys/kernel/debug/lru_gen`` to confirm the feature -+ is turned on. This file has the following output: -+ -+:: -+ -+ memcg memcg_id memcg_path -+ node node_id -+ min_gen birth_time anon_size file_size -+ ... -+ max_gen birth_time anon_size file_size -+ -+``min_gen`` is the oldest generation number and ``max_gen`` is the -+youngest generation number. ``birth_time`` is in milliseconds. -+``anon_size`` and ``file_size`` are in pages. -+ -+Phones/Laptops/Workstations -+--------------------------- -+No additional configurations required. -+ -+Servers/Data Centers -+-------------------- -+:To support more generations: Change ``CONFIG_NR_LRU_GENS`` to a -+ larger number. -+ -+:To support more tiers: Change ``CONFIG_TIERS_PER_GEN`` to a larger -+ number. -+ -+:To support full stats: Set ``CONFIG_LRU_GEN_STATS=y``. -+ -+:Working set estimation: Write ``+ memcg_id node_id max_gen -+ [swappiness]`` to ``/sys/kernel/debug/lru_gen`` to invoke the aging, -+ which scans PTEs for accessed pages and then creates the next -+ generation ``max_gen+1``. A swap file and a non-zero ``swappiness``, -+ which overrides ``vm.swappiness``, are required to scan PTEs mapping -+ anon pages. -+ -+:Proactive reclaim: Write ``- memcg_id node_id min_gen [swappiness] -+ [nr_to_reclaim]`` to ``/sys/kernel/debug/lru_gen`` to invoke the -+ eviction, which evicts generations less than or equal to ``min_gen``. -+ ``min_gen`` should be less than ``max_gen-1`` as ``max_gen`` and -+ ``max_gen-1`` are not fully aged and therefore cannot be evicted. -+ ``nr_to_reclaim`` can be used to limit the number of pages to evict. -+ Multiple command lines are supported, so does concatenation with -+ delimiters ``,`` and ``;``. -+ -+Framework -+========= -+For each ``lruvec``, evictable pages are divided into multiple -+generations. The youngest generation number is stored in -+``lrugen->max_seq`` for both anon and file types as they are aged on -+an equal footing. The oldest generation numbers are stored in -+``lrugen->min_seq[2]`` separately for anon and file types as clean -+file pages can be evicted regardless of swap and writeback -+constraints. These three variables are monotonically increasing. -+Generation numbers are truncated into -+``order_base_2(CONFIG_NR_LRU_GENS+1)`` bits in order to fit into -+``page->flags``. The sliding window technique is used to prevent -+truncated generation numbers from overlapping. Each truncated -+generation number is an index to an array of per-type and per-zone -+lists ``lrugen->lists``. -+ -+Each generation is then divided into multiple tiers. Tiers represent -+levels of usage from file descriptors only. Pages accessed ``N`` times -+via file descriptors belong to tier ``order_base_2(N)``. Each -+generation contains at most ``CONFIG_TIERS_PER_GEN`` tiers, and they -+require additional ``CONFIG_TIERS_PER_GEN-2`` bits in ``page->flags``. -+In contrast to moving across generations which requires list -+operations, moving across tiers only involves operations on -+``page->flags`` and therefore has a negligible cost. A feedback loop -+modeled after the PID controller monitors refault rates of all tiers -+and decides when to protect pages from which tiers. -+ -+The framework comprises two conceptually independent components: the -+aging and the eviction, which can be invoked separately from user -+space for the purpose of working set estimation and proactive reclaim. -+ -+Aging -+----- -+The aging produces young generations. Given an ``lruvec``, the aging -+traverses ``lruvec_memcg()->mm_list`` and calls ``walk_page_range()`` -+to scan PTEs for accessed pages (a ``mm_struct`` list is maintained -+for each ``memcg``). Upon finding one, the aging updates its -+generation number to ``max_seq`` (modulo ``CONFIG_NR_LRU_GENS``). -+After each round of traversal, the aging increments ``max_seq``. The -+aging is due when both ``min_seq[2]`` have caught up with -+``max_seq-1``. -+ -+Eviction -+-------- -+The eviction consumes old generations. Given an ``lruvec``, the -+eviction scans pages on the per-zone lists indexed by anon and file -+``min_seq[2]`` (modulo ``CONFIG_NR_LRU_GENS``). It first tries to -+select a type based on the values of ``min_seq[2]``. If they are -+equal, it selects the type that has a lower refault rate. The eviction -+sorts a page according to its updated generation number if the aging -+has found this page accessed. It also moves a page to the next -+generation if this page is from an upper tier that has a higher -+refault rate than the base tier. The eviction increments -+``min_seq[2]`` of a selected type when it finds all the per-zone lists -+indexed by ``min_seq[2]`` of this selected type are empty. -+ -+To-do List -+========== -+KVM Optimization -+---------------- -+Support shadow page table walk. -+ -+NUMA Optimization -+----------------- -+Optimize page table walk for NUMA. -diff --git a/arch/Kconfig b/arch/Kconfig -index 129df498a8e1..5b6b4f95372f 100644 ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -1282,6 +1282,15 @@ config ARCH_SPLIT_ARG64 - config ARCH_HAS_ELFCORE_COMPAT - bool - -+config ARCH_HAS_NONLEAF_PMD_YOUNG -+ bool -+ depends on PGTABLE_LEVELS > 2 -+ help -+ Architectures that select this are able to set the accessed bit on -+ non-leaf PMD entries in addition to leaf PTE entries where pages are -+ mapped. For them, page table walkers that clear the accessed bit may -+ stop at non-leaf PMD entries if they do not see the accessed bit. -+ - source "kernel/gcov/Kconfig" - - source "scripts/gcc-plugins/Kconfig" -diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h -index 9bb9d11750d7..2020b9e818c8 100644 ---- a/arch/arm64/include/asm/cpufeature.h -+++ b/arch/arm64/include/asm/cpufeature.h -@@ -776,6 +776,12 @@ static inline bool system_supports_tlb_range(void) - cpus_have_const_cap(ARM64_HAS_TLB_RANGE); - } - -+/* Check whether hardware update of the Access flag is supported. */ -+static inline bool system_has_hw_af(void) -+{ -+ return IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && cpus_have_const_cap(ARM64_HW_AF); -+} -+ - extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt); - - static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange) -@@ -799,19 +805,6 @@ static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange) - } - } - --/* Check whether hardware update of the Access flag is supported */ --static inline bool cpu_has_hw_af(void) --{ -- u64 mmfr1; -- -- if (!IS_ENABLED(CONFIG_ARM64_HW_AFDBM)) -- return false; -- -- mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); -- return cpuid_feature_extract_unsigned_field(mmfr1, -- ID_AA64MMFR1_HADBS_SHIFT); --} -- - static inline bool cpu_has_pan(void) - { - u64 mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); -diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h -index f09bf5c02891..b63a6a7b62ee 100644 ---- a/arch/arm64/include/asm/pgtable.h -+++ b/arch/arm64/include/asm/pgtable.h -@@ -993,13 +993,11 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, - * page after fork() + CoW for pfn mappings. We don't always have a - * hardware-managed access flag on arm64. - */ --static inline bool arch_faults_on_old_pte(void) -+static inline bool arch_has_hw_pte_young(void) - { -- WARN_ON(preemptible()); -- -- return !cpu_has_hw_af(); -+ return system_has_hw_af(); - } --#define arch_faults_on_old_pte arch_faults_on_old_pte -+#define arch_has_hw_pte_young arch_has_hw_pte_young - - /* - * Experimentally, it's cheap to set the access flag in hardware and we -@@ -1007,7 +1005,7 @@ static inline bool arch_faults_on_old_pte(void) - */ - static inline bool arch_wants_old_prefaulted_pte(void) - { -- return !arch_faults_on_old_pte(); -+ return arch_has_hw_pte_young(); - } - #define arch_wants_old_prefaulted_pte arch_wants_old_prefaulted_pte - -diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index 0ead8bfedf20..d05de77626f5 100644 ---- a/arch/arm64/kernel/cpufeature.c -+++ b/arch/arm64/kernel/cpufeature.c -@@ -1650,6 +1650,14 @@ static bool has_hw_dbm(const struct arm64_cpu_capabilities *cap, - return true; - } - -+static void cpu_enable_hw_af(struct arm64_cpu_capabilities const *cap) -+{ -+ u64 val = read_sysreg(tcr_el1); -+ -+ write_sysreg(val | TCR_HA, tcr_el1); -+ isb(); -+ local_flush_tlb_all(); -+} - #endif - - #ifdef CONFIG_ARM64_AMU_EXTN -@@ -2126,6 +2134,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = { - .matches = has_hw_dbm, - .cpu_enable = cpu_enable_hw_dbm, - }, -+ { -+ .desc = "Hardware update of the Access flag", -+ .type = ARM64_CPUCAP_SYSTEM_FEATURE, -+ .capability = ARM64_HW_AF, -+ .sys_reg = SYS_ID_AA64MMFR1_EL1, -+ .sign = FTR_UNSIGNED, -+ .field_pos = ID_AA64MMFR1_HADBS_SHIFT, -+ .min_field_value = 1, -+ .matches = has_cpuid_feature, -+ .cpu_enable = cpu_enable_hw_af, -+ }, - #endif - { - .desc = "CRC32 instructions", -diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S -index 35936c5ae1ce..b066d5712e3d 100644 ---- a/arch/arm64/mm/proc.S -+++ b/arch/arm64/mm/proc.S -@@ -478,18 +478,6 @@ SYM_FUNC_START(__cpu_setup) - * Set the IPS bits in TCR_EL1. - */ - tcr_compute_pa_size tcr, #TCR_IPS_SHIFT, x5, x6 --#ifdef CONFIG_ARM64_HW_AFDBM -- /* -- * Enable hardware update of the Access Flags bit. -- * Hardware dirty bit management is enabled later, -- * via capabilities. -- */ -- mrs x9, ID_AA64MMFR1_EL1 -- and x9, x9, #0xf -- cbz x9, 1f -- orr tcr, tcr, #TCR_HA // hardware Access flag update --1: --#endif /* CONFIG_ARM64_HW_AFDBM */ - msr mair_el1, mair - msr tcr_el1, tcr - /* -diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps -index 49305c2e6dfd..d52f50671e60 100644 ---- a/arch/arm64/tools/cpucaps -+++ b/arch/arm64/tools/cpucaps -@@ -35,6 +35,7 @@ HAS_STAGE2_FWB - HAS_SYSREG_GIC_CPUIF - HAS_TLB_RANGE - HAS_VIRT_HOST_EXTN -+HW_AF - HW_DBM - KVM_PROTECTED_MODE - MISMATCHED_CACHE_TYPE -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 88fb922c23a0..36a81d31f711 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -84,6 +84,7 @@ config X86 - select ARCH_HAS_PMEM_API if X86_64 - select ARCH_HAS_PTE_DEVMAP if X86_64 - select ARCH_HAS_PTE_SPECIAL -+ select ARCH_HAS_NONLEAF_PMD_YOUNG if X86_64 - select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 - select ARCH_HAS_COPY_MC if X86_64 - select ARCH_HAS_SET_MEMORY -diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h -index 448cd01eb3ec..01a1763123ff 100644 ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -817,7 +817,8 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) - - static inline int pmd_bad(pmd_t pmd) - { -- return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE; -+ return (pmd_flags(pmd) & ~(_PAGE_USER | _PAGE_ACCESSED)) != -+ (_KERNPG_TABLE & ~_PAGE_ACCESSED); - } - - static inline unsigned long pages_to_mb(unsigned long npg) -@@ -1397,10 +1398,10 @@ static inline bool arch_has_pfn_modify_check(void) - return boot_cpu_has_bug(X86_BUG_L1TF); - } - --#define arch_faults_on_old_pte arch_faults_on_old_pte --static inline bool arch_faults_on_old_pte(void) -+#define arch_has_hw_pte_young arch_has_hw_pte_young -+static inline bool arch_has_hw_pte_young(void) - { -- return false; -+ return true; - } - - #endif /* __ASSEMBLY__ */ -diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c -index 3481b35cb4ec..a224193d84bf 100644 ---- a/arch/x86/mm/pgtable.c -+++ b/arch/x86/mm/pgtable.c -@@ -550,7 +550,7 @@ int ptep_test_and_clear_young(struct vm_area_struct *vma, - return ret; - } - --#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) - int pmdp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pmd_t *pmdp) - { -@@ -562,6 +562,9 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma, - - return ret; - } -+#endif -+ -+#ifdef CONFIG_TRANSPARENT_HUGEPAGE - int pudp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pud_t *pudp) - { -diff --git a/fs/exec.c b/fs/exec.c -index 38f63451b928..7ead083bcb39 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1005,6 +1005,7 @@ static int exec_mmap(struct mm_struct *mm) - active_mm = tsk->active_mm; - tsk->active_mm = mm; - tsk->mm = mm; -+ lru_gen_add_mm(mm); - /* - * This prevents preemption while active_mm is being loaded and - * it and mm are being updated, which could cause problems for -@@ -1015,6 +1016,7 @@ static int exec_mmap(struct mm_struct *mm) - if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) - local_irq_enable(); - activate_mm(active_mm, mm); -+ lru_gen_switch_mm(active_mm, mm); - if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) - local_irq_enable(); - tsk->mm->vmacache_seqnum = 0; -diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c -index 1c8f79b3dd06..673d987652ee 100644 ---- a/fs/fuse/dev.c -+++ b/fs/fuse/dev.c -@@ -785,7 +785,8 @@ static int fuse_check_page(struct page *page) - 1 << PG_active | - 1 << PG_workingset | - 1 << PG_reclaim | -- 1 << PG_waiters))) { -+ 1 << PG_waiters | -+ LRU_GEN_MASK | LRU_USAGE_MASK))) { - dump_page(page, "fuse: trying to steal weird page"); - return 1; - } -diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h -index 7bf60454a313..1ebc27c8fee7 100644 ---- a/include/linux/cgroup.h -+++ b/include/linux/cgroup.h -@@ -432,6 +432,18 @@ static inline void cgroup_put(struct cgroup *cgrp) - css_put(&cgrp->self); - } - -+extern struct mutex cgroup_mutex; -+ -+static inline void cgroup_lock(void) -+{ -+ mutex_lock(&cgroup_mutex); -+} -+ -+static inline void cgroup_unlock(void) -+{ -+ mutex_unlock(&cgroup_mutex); -+} -+ - /** - * task_css_set_check - obtain a task's css_set with extra access conditions - * @task: the task to obtain css_set for -@@ -446,7 +458,6 @@ static inline void cgroup_put(struct cgroup *cgrp) - * as locks used during the cgroup_subsys::attach() methods. - */ - #ifdef CONFIG_PROVE_RCU --extern struct mutex cgroup_mutex; - extern spinlock_t css_set_lock; - #define task_css_set_check(task, __c) \ - rcu_dereference_check((task)->cgroups, \ -@@ -707,6 +718,8 @@ struct cgroup; - static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; } - static inline void css_get(struct cgroup_subsys_state *css) {} - static inline void css_put(struct cgroup_subsys_state *css) {} -+static inline void cgroup_lock(void) {} -+static inline void cgroup_unlock(void) {} - static inline int cgroup_attach_task_all(struct task_struct *from, - struct task_struct *t) { return 0; } - static inline int cgroupstats_build(struct cgroupstats *stats, -diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h -index 24797929d8a1..6ba29522286b 100644 ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -230,6 +230,8 @@ struct obj_cgroup { - }; - }; - -+struct lru_gen_mm_list; -+ - /* - * The memory controller data structure. The memory controller controls both - * page cache and RSS per cgroup. We would eventually like to provide -@@ -349,6 +351,10 @@ struct mem_cgroup { - struct deferred_split deferred_split_queue; - #endif - -+#ifdef CONFIG_LRU_GEN -+ struct lru_gen_mm_list *mm_list; -+#endif -+ - struct mem_cgroup_per_node *nodeinfo[]; - }; - -@@ -1341,10 +1347,13 @@ mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) - - static inline void lock_page_memcg(struct page *page) - { -+ /* to match page_memcg_rcu() */ -+ rcu_read_lock(); - } - - static inline void unlock_page_memcg(struct page *page) - { -+ rcu_read_unlock(); - } - - static inline void mem_cgroup_handle_over_high(void) -diff --git a/include/linux/mm.h b/include/linux/mm.h -index 7ca22e6e694a..7a91518792ba 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1092,6 +1092,8 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf); - #define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) - #define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH) - #define KASAN_TAG_PGOFF (LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH) -+#define LRU_GEN_PGOFF (KASAN_TAG_PGOFF - LRU_GEN_WIDTH) -+#define LRU_USAGE_PGOFF (LRU_GEN_PGOFF - LRU_USAGE_WIDTH) - - /* - * Define the bit shifts to access each section. For non-existent -@@ -1776,6 +1778,25 @@ void unmap_mapping_pages(struct address_space *mapping, - pgoff_t start, pgoff_t nr, bool even_cows); - void unmap_mapping_range(struct address_space *mapping, - loff_t const holebegin, loff_t const holelen, int even_cows); -+ -+static inline void task_enter_nonseq_fault(void) -+{ -+ WARN_ON(current->in_nonseq_fault); -+ -+ current->in_nonseq_fault = 1; -+} -+ -+static inline void task_exit_nonseq_fault(void) -+{ -+ WARN_ON(!current->in_nonseq_fault); -+ -+ current->in_nonseq_fault = 0; -+} -+ -+static inline bool task_in_nonseq_fault(void) -+{ -+ return current->in_nonseq_fault; -+} - #else - static inline vm_fault_t handle_mm_fault(struct vm_area_struct *vma, - unsigned long address, unsigned int flags, -@@ -1797,6 +1818,19 @@ static inline void unmap_mapping_pages(struct address_space *mapping, - pgoff_t start, pgoff_t nr, bool even_cows) { } - static inline void unmap_mapping_range(struct address_space *mapping, - loff_t const holebegin, loff_t const holelen, int even_cows) { } -+ -+static inline void task_enter_nonseq_fault(void) -+{ -+} -+ -+static inline void task_exit_nonseq_fault(void) -+{ -+} -+ -+static inline bool task_in_nonseq_fault(void) -+{ -+ return false; -+} - #endif - - static inline void unmap_shared_mapping_range(struct address_space *mapping, -diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h -index 355ea1ee32bd..19e722ec7cf3 100644 ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -79,11 +79,206 @@ static __always_inline enum lru_list page_lru(struct page *page) - return lru; - } - -+#ifdef CONFIG_LRU_GEN -+ -+#ifdef CONFIG_LRU_GEN_ENABLED -+DECLARE_STATIC_KEY_TRUE(lru_gen_static_key); -+ -+static inline bool lru_gen_enabled(void) -+{ -+ return static_branch_likely(&lru_gen_static_key); -+} -+#else -+DECLARE_STATIC_KEY_FALSE(lru_gen_static_key); -+ -+static inline bool lru_gen_enabled(void) -+{ -+ return static_branch_unlikely(&lru_gen_static_key); -+} -+#endif -+ -+/* Return an index within the sliding window that tracks MAX_NR_GENS generations. */ -+static inline int lru_gen_from_seq(unsigned long seq) -+{ -+ return seq % MAX_NR_GENS; -+} -+ -+/* Return a proper index regardless whether we keep a full history of stats. */ -+static inline int lru_hist_from_seq(int seq) -+{ -+ return seq % NR_STAT_GENS; -+} -+ -+/* Convert the level of usage to a tier. See the comment on MAX_NR_TIERS. */ -+static inline int lru_tier_from_usage(int usage) -+{ -+ VM_BUG_ON(usage > BIT(LRU_USAGE_WIDTH)); -+ -+ return order_base_2(usage + 1); -+} -+ -+/* The youngest and the second youngest generations are counted as active. */ -+static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen) -+{ -+ unsigned long max_seq = READ_ONCE(lruvec->evictable.max_seq); -+ -+ VM_BUG_ON(!max_seq); -+ VM_BUG_ON(gen >= MAX_NR_GENS); -+ -+ return gen == lru_gen_from_seq(max_seq) || gen == lru_gen_from_seq(max_seq - 1); -+} -+ -+/* Update the sizes of the multigenerational lru lists. */ -+static inline void lru_gen_update_size(struct page *page, struct lruvec *lruvec, -+ int old_gen, int new_gen) -+{ -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ int delta = thp_nr_pages(page); -+ enum lru_list lru = type * LRU_FILE; -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ lockdep_assert_held(&lruvec->lru_lock); -+ VM_BUG_ON(old_gen != -1 && old_gen >= MAX_NR_GENS); -+ VM_BUG_ON(new_gen != -1 && new_gen >= MAX_NR_GENS); -+ VM_BUG_ON(old_gen == -1 && new_gen == -1); -+ -+ if (old_gen >= 0) -+ WRITE_ONCE(lrugen->sizes[old_gen][type][zone], -+ lrugen->sizes[old_gen][type][zone] - delta); -+ if (new_gen >= 0) -+ WRITE_ONCE(lrugen->sizes[new_gen][type][zone], -+ lrugen->sizes[new_gen][type][zone] + delta); -+ -+ if (old_gen < 0) { -+ if (lru_gen_is_active(lruvec, new_gen)) -+ lru += LRU_ACTIVE; -+ update_lru_size(lruvec, lru, zone, delta); -+ return; -+ } -+ -+ if (new_gen < 0) { -+ if (lru_gen_is_active(lruvec, old_gen)) -+ lru += LRU_ACTIVE; -+ update_lru_size(lruvec, lru, zone, -delta); -+ return; -+ } -+ -+ if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) { -+ update_lru_size(lruvec, lru, zone, -delta); -+ update_lru_size(lruvec, lru + LRU_ACTIVE, zone, delta); -+ } -+ -+ VM_BUG_ON(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_active(lruvec, new_gen)); -+} -+ -+/* Add a page to one of the multigenerational lru lists. Return true on success. */ -+static inline bool lru_gen_add_page(struct page *page, struct lruvec *lruvec, bool reclaiming) -+{ -+ int gen; -+ unsigned long old_flags, new_flags; -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ if (PageUnevictable(page) || !lrugen->enabled[type]) -+ return false; -+ /* -+ * If a page shouldn't be considered for eviction, i.e., a page mapped -+ * upon fault during which the accessed bit is set, add it to the -+ * youngest generation. -+ * -+ * If a page can't be evicted immediately, i.e., an anon page not in -+ * swap cache or a dirty page pending writeback, add it to the second -+ * oldest generation. -+ * -+ * If a page could be evicted immediately, e.g., a clean page, add it to -+ * the oldest generation. -+ */ -+ if (PageActive(page)) -+ gen = lru_gen_from_seq(lrugen->max_seq); -+ else if ((!type && !PageSwapCache(page)) || -+ (PageReclaim(page) && (PageDirty(page) || PageWriteback(page)))) -+ gen = lru_gen_from_seq(lrugen->min_seq[type] + 1); -+ else -+ gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ do { -+ new_flags = old_flags = READ_ONCE(page->flags); -+ VM_BUG_ON_PAGE(new_flags & LRU_GEN_MASK, page); -+ -+ new_flags &= ~(LRU_GEN_MASK | BIT(PG_active)); -+ new_flags |= (gen + 1UL) << LRU_GEN_PGOFF; -+ } while (cmpxchg(&page->flags, old_flags, new_flags) != old_flags); -+ -+ lru_gen_update_size(page, lruvec, -1, gen); -+ if (reclaiming) -+ list_add_tail(&page->lru, &lrugen->lists[gen][type][zone]); -+ else -+ list_add(&page->lru, &lrugen->lists[gen][type][zone]); -+ -+ return true; -+} -+ -+/* Delete a page from one of the multigenerational lru lists. Return true on success. */ -+static inline bool lru_gen_del_page(struct page *page, struct lruvec *lruvec, bool reclaiming) -+{ -+ int gen; -+ unsigned long old_flags, new_flags; -+ -+ do { -+ new_flags = old_flags = READ_ONCE(page->flags); -+ if (!(new_flags & LRU_GEN_MASK)) -+ return false; -+ -+ VM_BUG_ON_PAGE(PageActive(page), page); -+ VM_BUG_ON_PAGE(PageUnevictable(page), page); -+ -+ gen = ((new_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+ -+ new_flags &= ~LRU_GEN_MASK; -+ if ((new_flags & LRU_TIER_FLAGS) != LRU_TIER_FLAGS) -+ new_flags &= ~(LRU_USAGE_MASK | LRU_TIER_FLAGS); -+ /* see the comment on PageReferenced()/PageReclaim() in shrink_page_list() */ -+ if (reclaiming) -+ new_flags &= ~(BIT(PG_referenced) | BIT(PG_reclaim)); -+ else if (lru_gen_is_active(lruvec, gen)) -+ new_flags |= BIT(PG_active); -+ } while (cmpxchg(&page->flags, old_flags, new_flags) != old_flags); -+ -+ lru_gen_update_size(page, lruvec, gen, -1); -+ list_del(&page->lru); -+ -+ return true; -+} -+ -+#else /* CONFIG_LRU_GEN */ -+ -+static inline bool lru_gen_enabled(void) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_add_page(struct page *page, struct lruvec *lruvec, bool reclaiming) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_del_page(struct page *page, struct lruvec *lruvec, bool reclaiming) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - static __always_inline void add_page_to_lru_list(struct page *page, - struct lruvec *lruvec) - { - enum lru_list lru = page_lru(page); - -+ if (lru_gen_add_page(page, lruvec, false)) -+ return; -+ - update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page)); - list_add(&page->lru, &lruvec->lists[lru]); - } -@@ -93,6 +288,9 @@ static __always_inline void add_page_to_lru_list_tail(struct page *page, - { - enum lru_list lru = page_lru(page); - -+ if (lru_gen_add_page(page, lruvec, true)) -+ return; -+ - update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page)); - list_add_tail(&page->lru, &lruvec->lists[lru]); - } -@@ -100,6 +298,9 @@ static __always_inline void add_page_to_lru_list_tail(struct page *page, - static __always_inline void del_page_from_lru_list(struct page *page, - struct lruvec *lruvec) - { -+ if (lru_gen_del_page(page, lruvec, false)) -+ return; -+ - list_del(&page->lru); - update_lru_size(lruvec, page_lru(page), page_zonenum(page), - -thp_nr_pages(page)); -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index 52bbd2b7cb46..d9a2ba150ce8 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -15,6 +15,8 @@ - #include <linux/page-flags-layout.h> - #include <linux/workqueue.h> - #include <linux/seqlock.h> -+#include <linux/nodemask.h> -+#include <linux/mmdebug.h> - - #include <asm/mmu.h> - -@@ -571,6 +573,22 @@ struct mm_struct { - - #ifdef CONFIG_IOMMU_SUPPORT - u32 pasid; -+#endif -+#ifdef CONFIG_LRU_GEN -+ struct { -+ /* the node of a global or per-memcg mm_struct list */ -+ struct list_head list; -+#ifdef CONFIG_MEMCG -+ /* points to the memcg of the owner task above */ -+ struct mem_cgroup *memcg; -+#endif -+ /* whether this mm_struct has been used since the last walk */ -+ nodemask_t nodes; -+#ifndef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH -+ /* the number of CPUs using this mm_struct */ -+ atomic_t nr_cpus; -+#endif -+ } lrugen; - #endif - } __randomize_layout; - -@@ -598,6 +616,95 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm) - return (struct cpumask *)&mm->cpu_bitmap; - } - -+#ifdef CONFIG_LRU_GEN -+ -+void lru_gen_init_mm(struct mm_struct *mm); -+void lru_gen_add_mm(struct mm_struct *mm); -+void lru_gen_del_mm(struct mm_struct *mm); -+#ifdef CONFIG_MEMCG -+int lru_gen_alloc_mm_list(struct mem_cgroup *memcg); -+void lru_gen_free_mm_list(struct mem_cgroup *memcg); -+void lru_gen_migrate_mm(struct mm_struct *mm); -+#endif -+ -+/* Track the usage of each mm_struct so that we can skip inactive ones. */ -+static inline void lru_gen_switch_mm(struct mm_struct *old, struct mm_struct *new) -+{ -+ /* exclude init_mm, efi_mm, etc. */ -+ if (!core_kernel_data((unsigned long)old)) { -+ VM_BUG_ON(old == &init_mm); -+ -+ nodes_setall(old->lrugen.nodes); -+#ifndef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH -+ atomic_dec(&old->lrugen.nr_cpus); -+ VM_BUG_ON_MM(atomic_read(&old->lrugen.nr_cpus) < 0, old); -+#endif -+ } else -+ VM_BUG_ON_MM(READ_ONCE(old->lrugen.list.prev) || -+ READ_ONCE(old->lrugen.list.next), old); -+ -+ if (!core_kernel_data((unsigned long)new)) { -+ VM_BUG_ON(new == &init_mm); -+ -+#ifndef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH -+ atomic_inc(&new->lrugen.nr_cpus); -+ VM_BUG_ON_MM(atomic_read(&new->lrugen.nr_cpus) < 0, new); -+#endif -+ } else -+ VM_BUG_ON_MM(READ_ONCE(new->lrugen.list.prev) || -+ READ_ONCE(new->lrugen.list.next), new); -+} -+ -+/* Return whether this mm_struct is being used on any CPUs. */ -+static inline bool lru_gen_mm_is_active(struct mm_struct *mm) -+{ -+#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH -+ return !cpumask_empty(mm_cpumask(mm)); -+#else -+ return atomic_read(&mm->lrugen.nr_cpus); -+#endif -+} -+ -+#else /* CONFIG_LRU_GEN */ -+ -+static inline void lru_gen_init_mm(struct mm_struct *mm) -+{ -+} -+ -+static inline void lru_gen_add_mm(struct mm_struct *mm) -+{ -+} -+ -+static inline void lru_gen_del_mm(struct mm_struct *mm) -+{ -+} -+ -+#ifdef CONFIG_MEMCG -+static inline int lru_gen_alloc_mm_list(struct mem_cgroup *memcg) -+{ -+ return 0; -+} -+ -+static inline void lru_gen_free_mm_list(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_migrate_mm(struct mm_struct *mm) -+{ -+} -+#endif -+ -+static inline void lru_gen_switch_mm(struct mm_struct *old, struct mm_struct *new) -+{ -+} -+ -+static inline bool lru_gen_mm_is_active(struct mm_struct *mm) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - struct mmu_gather; - extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm); - extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm); -diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h -index fcb535560028..b6005e881862 100644 ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -294,6 +294,100 @@ enum lruvec_flags { - */ - }; - -+struct lruvec; -+struct page_vma_mapped_walk; -+ -+#define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) -+#define LRU_USAGE_MASK ((BIT(LRU_USAGE_WIDTH) - 1) << LRU_USAGE_PGOFF) -+ -+#ifdef CONFIG_LRU_GEN -+ -+/* -+ * For each lruvec, evictable pages are divided into multiple generations. The -+ * youngest and the oldest generation numbers, AKA max_seq and min_seq, are -+ * monotonically increasing. The sliding window technique is used to track at -+ * most MAX_NR_GENS and at least MIN_NR_GENS generations. An offset within the -+ * window, AKA gen, indexes an array of per-type and per-zone lists for the -+ * corresponding generation. The counter in page->flags stores gen+1 while a -+ * page is on one of the multigenerational lru lists. Otherwise, it stores 0. -+ */ -+#define MAX_NR_GENS ((unsigned int)CONFIG_NR_LRU_GENS) -+ -+/* -+ * Each generation is then divided into multiple tiers. Tiers represent levels -+ * of usage from file descriptors, i.e., mark_page_accessed(). In contrast to -+ * moving across generations which requires the lru lock, moving across tiers -+ * only involves an atomic operation on page->flags and therefore has a -+ * negligible cost. -+ * -+ * The purposes of tiers are to: -+ * 1) estimate whether pages accessed multiple times via file descriptors are -+ * more active than pages accessed only via page tables by separating the two -+ * access types into upper tiers and the base tier and comparing refault rates -+ * across tiers. -+ * 2) improve buffered io performance by deferring the protection of pages -+ * accessed multiple times until the eviction. That is the protection happens -+ * in the reclaim path, not the access path. -+ * -+ * Pages accessed N times via file descriptors belong to tier order_base_2(N). -+ * The base tier may be marked by PageReferenced(). All upper tiers are marked -+ * by PageReferenced() && PageWorkingset(). Additional bits from page->flags are -+ * used to support more than one upper tier. -+ */ -+#define MAX_NR_TIERS ((unsigned int)CONFIG_TIERS_PER_GEN) -+#define LRU_TIER_FLAGS (BIT(PG_referenced) | BIT(PG_workingset)) -+ -+/* Whether to keep historical stats for each generation. */ -+#ifdef CONFIG_LRU_GEN_STATS -+#define NR_STAT_GENS ((unsigned int)CONFIG_NR_LRU_GENS) -+#else -+#define NR_STAT_GENS 1U -+#endif -+ -+struct lrugen { -+ /* the aging increments the max generation number */ -+ unsigned long max_seq; -+ /* the eviction increments the min generation numbers */ -+ unsigned long min_seq[ANON_AND_FILE]; -+ /* the birth time of each generation in jiffies */ -+ unsigned long timestamps[MAX_NR_GENS]; -+ /* the multigenerational lru lists */ -+ struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* the sizes of the multigenerational lru lists in pages */ -+ unsigned long sizes[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* to determine which type and its tiers to evict */ -+ atomic_long_t refaulted[NR_STAT_GENS][ANON_AND_FILE][MAX_NR_TIERS]; -+ atomic_long_t evicted[NR_STAT_GENS][ANON_AND_FILE][MAX_NR_TIERS]; -+ /* the base tier isn't protected, hence the minus one */ -+ unsigned long protected[NR_STAT_GENS][ANON_AND_FILE][MAX_NR_TIERS - 1]; -+ /* the exponential moving average of refaulted */ -+ unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS]; -+ /* the exponential moving average of evicted+protected */ -+ unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS]; -+ /* whether the multigenerational lru is enabled */ -+ bool enabled[ANON_AND_FILE]; -+}; -+ -+void lru_gen_init_lrugen(struct lruvec *lruvec); -+void lru_gen_set_state(bool enable, bool main, bool swap); -+void lru_gen_scan_around(struct page_vma_mapped_walk *pvmw); -+ -+#else /* CONFIG_LRU_GEN */ -+ -+static inline void lru_gen_init_lrugen(struct lruvec *lruvec) -+{ -+} -+ -+static inline void lru_gen_set_state(bool enable, bool main, bool swap) -+{ -+} -+ -+static inline void lru_gen_scan_around(struct page_vma_mapped_walk *pvmw) -+{ -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - struct lruvec { - struct list_head lists[NR_LRU_LISTS]; - /* per lruvec lru_lock for memcg */ -@@ -311,6 +405,10 @@ struct lruvec { - unsigned long refaults[ANON_AND_FILE]; - /* Various lruvec state flags (enum lruvec_flags) */ - unsigned long flags; -+#ifdef CONFIG_LRU_GEN -+ /* unevictable pages are on LRU_UNEVICTABLE */ -+ struct lrugen evictable; -+#endif - #ifdef CONFIG_MEMCG - struct pglist_data *pgdat; - #endif -@@ -782,6 +880,8 @@ struct deferred_split { - }; - #endif - -+struct mm_walk_args; -+ - /* - * On NUMA machines, each NUMA node would have a pg_data_t to describe - * it's memory layout. On UMA machines there is a single pglist_data which -@@ -887,6 +987,9 @@ typedef struct pglist_data { - - unsigned long flags; - -+#ifdef CONFIG_LRU_GEN -+ struct mm_walk_args *mm_walk_args; -+#endif - ZONE_PADDING(_pad2_) - - /* Per-node vmstats */ -diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h -index 567c3ddba2c4..90840c459abc 100644 ---- a/include/linux/nodemask.h -+++ b/include/linux/nodemask.h -@@ -486,6 +486,7 @@ static inline int num_node_state(enum node_states state) - #define first_online_node 0 - #define first_memory_node 0 - #define next_online_node(nid) (MAX_NUMNODES) -+#define next_memory_node(nid) (MAX_NUMNODES) - #define nr_node_ids 1U - #define nr_online_nodes 1U - -diff --git a/include/linux/oom.h b/include/linux/oom.h -index 2db9a1432511..c4c8c7e71099 100644 ---- a/include/linux/oom.h -+++ b/include/linux/oom.h -@@ -57,6 +57,22 @@ struct oom_control { - extern struct mutex oom_lock; - extern struct mutex oom_adj_mutex; - -+#ifdef CONFIG_MMU -+extern struct task_struct *oom_reaper_list; -+extern struct wait_queue_head oom_reaper_wait; -+ -+static inline bool oom_reaping_in_progress(void) -+{ -+ /* racy check to see if oom reaping could be in progress */ -+ return READ_ONCE(oom_reaper_list) || !waitqueue_active(&oom_reaper_wait); -+} -+#else -+static inline bool oom_reaping_in_progress(void) -+{ -+ return false; -+} -+#endif -+ - static inline void set_current_oom_origin(void) - { - current->signal->oom_flag_origin = true; -diff --git a/include/linux/page-flags-layout.h b/include/linux/page-flags-layout.h -index ef1e3e736e14..ce8d5732a3aa 100644 ---- a/include/linux/page-flags-layout.h -+++ b/include/linux/page-flags-layout.h -@@ -26,6 +26,14 @@ - - #define ZONES_WIDTH ZONES_SHIFT - -+#ifdef CONFIG_LRU_GEN -+/* LRU_GEN_WIDTH is generated from order_base_2(CONFIG_NR_LRU_GENS + 1). */ -+#define LRU_USAGE_WIDTH (CONFIG_TIERS_PER_GEN - 2) -+#else -+#define LRU_GEN_WIDTH 0 -+#define LRU_USAGE_WIDTH 0 -+#endif -+ - #ifdef CONFIG_SPARSEMEM - #include <asm/sparsemem.h> - #define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS) -@@ -55,7 +63,8 @@ - #define SECTIONS_WIDTH 0 - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + LRU_USAGE_WIDTH + SECTIONS_WIDTH + NODES_SHIFT \ -+ <= BITS_PER_LONG - NR_PAGEFLAGS - #define NODES_WIDTH NODES_SHIFT - #elif defined(CONFIG_SPARSEMEM_VMEMMAP) - #error "Vmemmap: No space for nodes field in page flags" -@@ -89,8 +98,8 @@ - #define LAST_CPUPID_SHIFT 0 - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT \ -- <= BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + LRU_USAGE_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \ -+ KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS - #define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT - #else - #define LAST_CPUPID_WIDTH 0 -@@ -100,8 +109,8 @@ - #define LAST_CPUPID_NOT_IN_PAGE_FLAGS - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH \ -- > BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + LRU_USAGE_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \ -+ KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS - #error "Not enough bits in page flags" - #endif - -diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h -index 5922031ffab6..0156ac5f08f0 100644 ---- a/include/linux/page-flags.h -+++ b/include/linux/page-flags.h -@@ -848,7 +848,7 @@ static inline void ClearPageSlabPfmemalloc(struct page *page) - 1UL << PG_private | 1UL << PG_private_2 | \ - 1UL << PG_writeback | 1UL << PG_reserved | \ - 1UL << PG_slab | 1UL << PG_active | \ -- 1UL << PG_unevictable | __PG_MLOCKED) -+ 1UL << PG_unevictable | __PG_MLOCKED | LRU_GEN_MASK) - - /* - * Flags checked when a page is prepped for return by the page allocator. -@@ -859,7 +859,7 @@ static inline void ClearPageSlabPfmemalloc(struct page *page) - * alloc-free cycle to prevent from reusing the page. - */ - #define PAGE_FLAGS_CHECK_AT_PREP \ -- (((1UL << NR_PAGEFLAGS) - 1) & ~__PG_HWPOISON) -+ ((((1UL << NR_PAGEFLAGS) - 1) & ~__PG_HWPOISON) | LRU_GEN_MASK | LRU_USAGE_MASK) - - #define PAGE_FLAGS_PRIVATE \ - (1UL << PG_private | 1UL << PG_private_2) -diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h -index e24d2c992b11..483d5ff7a33e 100644 ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -211,7 +211,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, - #endif - - #ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG --#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) - static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long address, - pmd_t *pmdp) -@@ -232,7 +232,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, - BUILD_BUG(); - return 0; - } --#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -+#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG */ - #endif - - #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH -@@ -258,6 +258,18 @@ static inline int pmdp_clear_flush_young(struct vm_area_struct *vma, - #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ - #endif - -+#ifndef arch_has_hw_pte_young -+static inline bool arch_has_hw_pte_young(void) -+{ -+ /* -+ * Those arches which have hw access flag feature need to implement -+ * their own helper. By default, "false" means pagefault will be hit -+ * on old pte. -+ */ -+ return false; -+} -+#endif -+ - #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR - static inline pte_t ptep_get_and_clear(struct mm_struct *mm, - unsigned long address, -diff --git a/include/linux/sched.h b/include/linux/sched.h -index ec8d07d88641..fd41c9c86cd1 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -843,6 +843,9 @@ struct task_struct { - #ifdef CONFIG_MEMCG - unsigned in_user_fault:1; - #endif -+#ifdef CONFIG_MMU -+ unsigned in_nonseq_fault:1; -+#endif - #ifdef CONFIG_COMPAT_BRK - unsigned brk_randomized:1; - #endif -diff --git a/include/linux/swap.h b/include/linux/swap.h -index 6f5a43251593..c838e67dfa3a 100644 ---- a/include/linux/swap.h -+++ b/include/linux/swap.h -@@ -368,6 +368,7 @@ extern void lru_add_drain_all(void); - extern void rotate_reclaimable_page(struct page *page); - extern void deactivate_file_page(struct page *page); - extern void deactivate_page(struct page *page); -+extern void activate_page(struct page *page); - extern void mark_page_lazyfree(struct page *page); - extern void swap_setup(void); - -diff --git a/kernel/bounds.c b/kernel/bounds.c -index 9795d75b09b2..aba13aa7336c 100644 ---- a/kernel/bounds.c -+++ b/kernel/bounds.c -@@ -22,6 +22,9 @@ int main(void) - DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS)); - #endif - DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t)); -+#ifdef CONFIG_LRU_GEN -+ DEFINE(LRU_GEN_WIDTH, order_base_2(CONFIG_NR_LRU_GENS + 1)); -+#endif - /* End of constants */ - - return 0; -diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h -index bfbeabc17a9d..bec59189e206 100644 ---- a/kernel/cgroup/cgroup-internal.h -+++ b/kernel/cgroup/cgroup-internal.h -@@ -146,7 +146,6 @@ struct cgroup_mgctx { - #define DEFINE_CGROUP_MGCTX(name) \ - struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name) - --extern struct mutex cgroup_mutex; - extern spinlock_t css_set_lock; - extern struct cgroup_subsys *cgroup_subsys[]; - extern struct list_head cgroup_roots; -diff --git a/kernel/exit.c b/kernel/exit.c -index 9a89e7f36acb..c24d5ffae792 100644 ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -422,6 +422,7 @@ void mm_update_next_owner(struct mm_struct *mm) - goto retry; - } - WRITE_ONCE(mm->owner, c); -+ lru_gen_migrate_mm(mm); - task_unlock(c); - put_task_struct(c); - } -diff --git a/kernel/fork.c b/kernel/fork.c -index 44f4c2d83763..a7d305b3339c 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -669,6 +669,7 @@ static void check_mm(struct mm_struct *mm) - #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS - VM_BUG_ON_MM(mm->pmd_huge_pte, mm); - #endif -+ VM_BUG_ON_MM(lru_gen_mm_is_active(mm), mm); - } - - #define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) -@@ -1066,6 +1067,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, - goto fail_nocontext; - - mm->user_ns = get_user_ns(user_ns); -+ lru_gen_init_mm(mm); - return mm; - - fail_nocontext: -@@ -1108,6 +1110,7 @@ static inline void __mmput(struct mm_struct *mm) - } - if (mm->binfmt) - module_put(mm->binfmt->module); -+ lru_gen_del_mm(mm); - mmdrop(mm); - } - -@@ -2530,6 +2533,13 @@ pid_t kernel_clone(struct kernel_clone_args *args) - get_task_struct(p); - } - -+ if (IS_ENABLED(CONFIG_LRU_GEN) && !(clone_flags & CLONE_VM)) { -+ /* lock the task to synchronize with memcg migration */ -+ task_lock(p); -+ lru_gen_add_mm(p->mm); -+ task_unlock(p); -+ } -+ - wake_up_new_task(p); - - /* forking complete and child started to run, tell ptracer */ -diff --git a/kernel/kthread.c b/kernel/kthread.c -index 5b37a8567168..fd827fdad26b 100644 ---- a/kernel/kthread.c -+++ b/kernel/kthread.c -@@ -1361,6 +1361,7 @@ void kthread_use_mm(struct mm_struct *mm) - tsk->mm = mm; - membarrier_update_current_mm(mm); - switch_mm_irqs_off(active_mm, mm, tsk); -+ lru_gen_switch_mm(active_mm, mm); - local_irq_enable(); - task_unlock(tsk); - #ifdef finish_arch_post_lock_switch -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index f3b27c6c5153..aae1e0c0f461 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -4679,6 +4679,7 @@ context_switch(struct rq *rq, struct task_struct *prev, - * finish_task_switch()'s mmdrop(). - */ - switch_mm_irqs_off(prev->active_mm, next->mm, next); -+ lru_gen_switch_mm(prev->active_mm, next->mm); - - if (!prev->mm) { // from kernel - /* will mmdrop() in finish_task_switch(). */ -@@ -8479,6 +8480,7 @@ void idle_task_exit(void) - - if (mm != &init_mm) { - switch_mm(mm, &init_mm, current); -+ lru_gen_switch_mm(mm, &init_mm); - finish_arch_post_lock_switch(); - } - -diff --git a/mm/Kconfig b/mm/Kconfig -index 40a9bfcd5062..4cd257cfdf84 100644 ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -889,4 +889,63 @@ config IO_MAPPING - config SECRETMEM - def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED - -+# the multigenerational lru { -+config LRU_GEN -+ bool "Multigenerational LRU" -+ depends on MMU -+ # the following options may leave not enough spare bits in page->flags -+ depends on !MAXSMP && (64BIT || !SPARSEMEM || SPARSEMEM_VMEMMAP) -+ help -+ A high performance LRU implementation to heavily overcommit workloads -+ that are not IO bound. See Documentation/vm/multigen_lru.rst for -+ details. -+ -+ Warning: do not enable this option unless you plan to use it because -+ it introduces a small per-process and per-memcg and per-node memory -+ overhead. -+ -+config LRU_GEN_ENABLED -+ bool "Turn on by default" -+ depends on LRU_GEN -+ help -+ The default value of /sys/kernel/mm/lru_gen/enabled is 0. This option -+ changes it to 1. -+ -+ Warning: the default value is the fast path. See -+ Documentation/static-keys.txt for details. -+ -+config LRU_GEN_STATS -+ bool "Full stats for debugging" -+ depends on LRU_GEN -+ help -+ This option keeps full stats for each generation, which can be read -+ from /sys/kernel/debug/lru_gen_full. -+ -+ Warning: do not enable this option unless you plan to use it because -+ it introduces an additional small per-process and per-memcg and -+ per-node memory overhead. -+ -+config NR_LRU_GENS -+ int "Max number of generations" -+ depends on LRU_GEN -+ range 4 31 -+ default 7 -+ help -+ This will use order_base_2(N+1) spare bits from page flags. -+ -+ Warning: do not use numbers larger than necessary because each -+ generation introduces a small per-node and per-memcg memory overhead. -+ -+config TIERS_PER_GEN -+ int "Number of tiers per generation" -+ depends on LRU_GEN -+ range 2 5 -+ default 4 -+ help -+ This will use N-2 spare bits from page flags. -+ -+ Larger values generally offer better protection to active pages under -+ heavy buffered I/O workloads. -+# } -+ - endmenu -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index afff3ac87067..d5ccbfb50352 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -2390,7 +2390,8 @@ static void __split_huge_page_tail(struct page *head, int tail, - #ifdef CONFIG_64BIT - (1L << PG_arch_2) | - #endif -- (1L << PG_dirty))); -+ (1L << PG_dirty) | -+ LRU_GEN_MASK | LRU_USAGE_MASK)); - - /* ->mapping in first tail page is compound_mapcount */ - VM_BUG_ON_PAGE(tail > 2 && page_tail->mapping != TAIL_MAPPING, -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 702a81dfe72d..8597992797d0 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -5172,6 +5172,7 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg) - for_each_node(node) - free_mem_cgroup_per_node_info(memcg, node); - free_percpu(memcg->vmstats_percpu); -+ lru_gen_free_mm_list(memcg); - kfree(memcg); - } - -@@ -5221,6 +5222,9 @@ static struct mem_cgroup *mem_cgroup_alloc(void) - if (alloc_mem_cgroup_per_node_info(memcg, node)) - goto fail; - -+ if (lru_gen_alloc_mm_list(memcg)) -+ goto fail; -+ - if (memcg_wb_domain_init(memcg, GFP_KERNEL)) - goto fail; - -@@ -6182,6 +6186,29 @@ static void mem_cgroup_move_task(void) - } - #endif - -+#ifdef CONFIG_LRU_GEN -+static void mem_cgroup_attach(struct cgroup_taskset *tset) -+{ -+ struct cgroup_subsys_state *css; -+ struct task_struct *task = NULL; -+ -+ cgroup_taskset_for_each_leader(task, css, tset) -+ break; -+ -+ if (!task) -+ return; -+ -+ task_lock(task); -+ if (task->mm && task->mm->owner == task) -+ lru_gen_migrate_mm(task->mm); -+ task_unlock(task); -+} -+#else -+static void mem_cgroup_attach(struct cgroup_taskset *tset) -+{ -+} -+#endif -+ - static int seq_puts_memcg_tunable(struct seq_file *m, unsigned long value) - { - if (value == PAGE_COUNTER_MAX) -@@ -6523,6 +6550,7 @@ struct cgroup_subsys memory_cgrp_subsys = { - .css_reset = mem_cgroup_css_reset, - .css_rstat_flush = mem_cgroup_css_rstat_flush, - .can_attach = mem_cgroup_can_attach, -+ .attach = mem_cgroup_attach, - .cancel_attach = mem_cgroup_cancel_attach, - .post_attach = mem_cgroup_move_task, - .dfl_cftypes = memory_files, -diff --git a/mm/memory.c b/mm/memory.c -index 25fc46e87214..fa40a5b7a7a7 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -121,18 +121,6 @@ int randomize_va_space __read_mostly = - 2; - #endif - --#ifndef arch_faults_on_old_pte --static inline bool arch_faults_on_old_pte(void) --{ -- /* -- * Those arches which don't have hw access flag feature need to -- * implement their own helper. By default, "true" means pagefault -- * will be hit on old pte. -- */ -- return true; --} --#endif -- - #ifndef arch_wants_old_prefaulted_pte - static inline bool arch_wants_old_prefaulted_pte(void) - { -@@ -2769,7 +2757,7 @@ static inline bool cow_user_page(struct page *dst, struct page *src, - * On architectures with software "accessed" bits, we would - * take a double page fault, so mark it accessed here. - */ -- if (arch_faults_on_old_pte() && !pte_young(vmf->orig_pte)) { -+ if (!arch_has_hw_pte_young() && !pte_young(vmf->orig_pte)) { - pte_t entry; - - vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl); -@@ -4764,6 +4752,7 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address, - unsigned int flags, struct pt_regs *regs) - { - vm_fault_t ret; -+ bool nonseq_fault = !(vma->vm_flags & VM_SEQ_READ); - - __set_current_state(TASK_RUNNING); - -@@ -4785,11 +4774,17 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address, - if (flags & FAULT_FLAG_USER) - mem_cgroup_enter_user_fault(); - -+ if (nonseq_fault) -+ task_enter_nonseq_fault(); -+ - if (unlikely(is_vm_hugetlb_page(vma))) - ret = hugetlb_fault(vma->vm_mm, vma, address, flags); - else - ret = __handle_mm_fault(vma, address, flags); - -+ if (nonseq_fault) -+ task_exit_nonseq_fault(); -+ - if (flags & FAULT_FLAG_USER) { - mem_cgroup_exit_user_fault(); - /* -diff --git a/mm/mm_init.c b/mm/mm_init.c -index 9ddaf0e1b0ab..ef0deadb90a7 100644 ---- a/mm/mm_init.c -+++ b/mm/mm_init.c -@@ -65,14 +65,16 @@ void __init mminit_verify_pageflags_layout(void) - - shift = 8 * sizeof(unsigned long); - width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH -- - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH; -+ - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH - LRU_GEN_WIDTH - LRU_USAGE_WIDTH; - mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths", -- "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Flags %d\n", -+ "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Gen %d Tier %d Flags %d\n", - SECTIONS_WIDTH, - NODES_WIDTH, - ZONES_WIDTH, - LAST_CPUPID_WIDTH, - KASAN_TAG_WIDTH, -+ LRU_GEN_WIDTH, -+ LRU_USAGE_WIDTH, - NR_PAGEFLAGS); - mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts", - "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d\n", -diff --git a/mm/mmzone.c b/mm/mmzone.c -index eb89d6e018e2..2055d66a7f22 100644 ---- a/mm/mmzone.c -+++ b/mm/mmzone.c -@@ -81,6 +81,8 @@ void lruvec_init(struct lruvec *lruvec) - - for_each_lru(lru) - INIT_LIST_HEAD(&lruvec->lists[lru]); -+ -+ lru_gen_init_lrugen(lruvec); - } - - #if defined(CONFIG_NUMA_BALANCING) && !defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS) -diff --git a/mm/oom_kill.c b/mm/oom_kill.c -index c729a4c4a1ac..eca484ee3a3d 100644 ---- a/mm/oom_kill.c -+++ b/mm/oom_kill.c -@@ -507,8 +507,8 @@ bool process_shares_mm(struct task_struct *p, struct mm_struct *mm) - * victim (if that is possible) to help the OOM killer to move on. - */ - static struct task_struct *oom_reaper_th; --static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait); --static struct task_struct *oom_reaper_list; -+DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait); -+struct task_struct *oom_reaper_list; - static DEFINE_SPINLOCK(oom_reaper_lock); - - bool __oom_reap_task_mm(struct mm_struct *mm) -diff --git a/mm/rmap.c b/mm/rmap.c -index b9eb5c12f3fe..f4963d60ff68 100644 ---- a/mm/rmap.c -+++ b/mm/rmap.c -@@ -72,6 +72,7 @@ - #include <linux/page_idle.h> - #include <linux/memremap.h> - #include <linux/userfaultfd_k.h> -+#include <linux/mm_inline.h> - - #include <asm/tlbflush.h> - -@@ -789,6 +790,12 @@ static bool page_referenced_one(struct page *page, struct vm_area_struct *vma, - } - - if (pvmw.pte) { -+ /* the multigenerational lru exploits the spatial locality */ -+ if (lru_gen_enabled() && pte_young(*pvmw.pte) && -+ !(vma->vm_flags & VM_SEQ_READ)) { -+ lru_gen_scan_around(&pvmw); -+ referenced++; -+ } - if (ptep_clear_flush_young_notify(vma, address, - pvmw.pte)) { - /* -diff --git a/mm/swap.c b/mm/swap.c -index 19600430e536..0315cfa9fa41 100644 ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -347,7 +347,7 @@ static bool need_activate_page_drain(int cpu) - return pagevec_count(&per_cpu(lru_pvecs.activate_page, cpu)) != 0; - } - --static void activate_page(struct page *page) -+void activate_page(struct page *page) - { - page = compound_head(page); - if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) { -@@ -367,7 +367,7 @@ static inline void activate_page_drain(int cpu) - { - } - --static void activate_page(struct page *page) -+void activate_page(struct page *page) - { - struct lruvec *lruvec; - -@@ -411,6 +411,43 @@ static void __lru_cache_activate_page(struct page *page) - local_unlock(&lru_pvecs.lock); - } - -+#ifdef CONFIG_LRU_GEN -+static void page_inc_usage(struct page *page) -+{ -+ unsigned long usage; -+ unsigned long old_flags, new_flags; -+ -+ if (PageUnevictable(page)) -+ return; -+ -+ /* see the comment on MAX_NR_TIERS */ -+ do { -+ new_flags = old_flags = READ_ONCE(page->flags); -+ -+ if (!(new_flags & BIT(PG_referenced))) { -+ new_flags |= BIT(PG_referenced); -+ continue; -+ } -+ -+ if (!(new_flags & BIT(PG_workingset))) { -+ new_flags |= BIT(PG_workingset); -+ continue; -+ } -+ -+ usage = new_flags & LRU_USAGE_MASK; -+ usage = min(usage + BIT(LRU_USAGE_PGOFF), LRU_USAGE_MASK); -+ -+ new_flags &= ~LRU_USAGE_MASK; -+ new_flags |= usage; -+ } while (new_flags != old_flags && -+ cmpxchg(&page->flags, old_flags, new_flags) != old_flags); -+} -+#else -+static void page_inc_usage(struct page *page) -+{ -+} -+#endif /* CONFIG_LRU_GEN */ -+ - /* - * Mark a page as having seen activity. - * -@@ -425,6 +462,11 @@ void mark_page_accessed(struct page *page) - { - page = compound_head(page); - -+ if (lru_gen_enabled()) { -+ page_inc_usage(page); -+ return; -+ } -+ - if (!PageReferenced(page)) { - SetPageReferenced(page); - } else if (PageUnevictable(page)) { -@@ -468,6 +510,11 @@ void lru_cache_add(struct page *page) - VM_BUG_ON_PAGE(PageActive(page) && PageUnevictable(page), page); - VM_BUG_ON_PAGE(PageLRU(page), page); - -+ /* see the comment in lru_gen_add_page() */ -+ if (lru_gen_enabled() && !PageUnevictable(page) && -+ task_in_nonseq_fault() && !(current->flags & PF_MEMALLOC)) -+ SetPageActive(page); -+ - get_page(page); - local_lock(&lru_pvecs.lock); - pvec = this_cpu_ptr(&lru_pvecs.lru_add); -@@ -569,7 +616,7 @@ static void lru_deactivate_file_fn(struct page *page, struct lruvec *lruvec) - - static void lru_deactivate_fn(struct page *page, struct lruvec *lruvec) - { -- if (PageActive(page) && !PageUnevictable(page)) { -+ if (!PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) { - int nr_pages = thp_nr_pages(page); - - del_page_from_lru_list(page, lruvec); -@@ -684,7 +731,7 @@ void deactivate_file_page(struct page *page) - */ - void deactivate_page(struct page *page) - { -- if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) { -+ if (PageLRU(page) && !PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) { - struct pagevec *pvec; - - local_lock(&lru_pvecs.lock); -diff --git a/mm/swapfile.c b/mm/swapfile.c -index 1e07d1c776f2..19dacc4ae35e 100644 ---- a/mm/swapfile.c -+++ b/mm/swapfile.c -@@ -2688,6 +2688,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) - err = 0; - atomic_inc(&proc_poll_event); - wake_up_interruptible(&proc_poll_wait); -+ lru_gen_set_state(false, false, true); - - out_dput: - filp_close(victim, NULL); -@@ -3343,6 +3344,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) - mutex_unlock(&swapon_mutex); - atomic_inc(&proc_poll_event); - wake_up_interruptible(&proc_poll_wait); -+ lru_gen_set_state(true, false, true); - - error = 0; - goto out; -diff --git a/mm/vmscan.c b/mm/vmscan.c -index eeae2f6bc532..6f7c69924dc5 100644 ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -49,6 +49,11 @@ - #include <linux/printk.h> - #include <linux/dax.h> - #include <linux/psi.h> -+#include <linux/memory.h> -+#include <linux/pagewalk.h> -+#include <linux/shmem_fs.h> -+#include <linux/ctype.h> -+#include <linux/debugfs.h> - - #include <asm/tlbflush.h> - #include <asm/div64.h> -@@ -1096,9 +1101,11 @@ static int __remove_mapping(struct address_space *mapping, struct page *page, - - if (PageSwapCache(page)) { - swp_entry_t swap = { .val = page_private(page) }; -- mem_cgroup_swapout(page, swap); -+ -+ /* get a shadow entry before page_memcg() is cleared */ - if (reclaimed && !mapping_exiting(mapping)) - shadow = workingset_eviction(page, target_memcg); -+ mem_cgroup_swapout(page, swap); - __delete_from_swap_cache(page, swap, shadow); - xa_unlock_irqrestore(&mapping->i_pages, flags); - put_swap_page(page, swap); -@@ -1309,6 +1316,11 @@ static unsigned int shrink_page_list(struct list_head *page_list, - if (!sc->may_unmap && page_mapped(page)) - goto keep_locked; - -+ /* lru_gen_scan_around() has updated this page? */ -+ if (lru_gen_enabled() && !ignore_references && -+ page_mapped(page) && PageReferenced(page)) -+ goto keep_locked; -+ - may_enter_fs = (sc->gfp_mask & __GFP_FS) || - (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO)); - -@@ -2440,6 +2452,106 @@ enum scan_balance { - SCAN_FILE, - }; - -+static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc) -+{ -+ unsigned long file; -+ struct lruvec *target_lruvec; -+ -+ if (lru_gen_enabled()) -+ return; -+ -+ target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); -+ -+ /* -+ * Determine the scan balance between anon and file LRUs. -+ */ -+ spin_lock_irq(&target_lruvec->lru_lock); -+ sc->anon_cost = target_lruvec->anon_cost; -+ sc->file_cost = target_lruvec->file_cost; -+ spin_unlock_irq(&target_lruvec->lru_lock); -+ -+ /* -+ * Target desirable inactive:active list ratios for the anon -+ * and file LRU lists. -+ */ -+ if (!sc->force_deactivate) { -+ unsigned long refaults; -+ -+ refaults = lruvec_page_state(target_lruvec, -+ WORKINGSET_ACTIVATE_ANON); -+ if (refaults != target_lruvec->refaults[0] || -+ inactive_is_low(target_lruvec, LRU_INACTIVE_ANON)) -+ sc->may_deactivate |= DEACTIVATE_ANON; -+ else -+ sc->may_deactivate &= ~DEACTIVATE_ANON; -+ -+ /* -+ * When refaults are being observed, it means a new -+ * workingset is being established. Deactivate to get -+ * rid of any stale active pages quickly. -+ */ -+ refaults = lruvec_page_state(target_lruvec, -+ WORKINGSET_ACTIVATE_FILE); -+ if (refaults != target_lruvec->refaults[1] || -+ inactive_is_low(target_lruvec, LRU_INACTIVE_FILE)) -+ sc->may_deactivate |= DEACTIVATE_FILE; -+ else -+ sc->may_deactivate &= ~DEACTIVATE_FILE; -+ } else -+ sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE; -+ -+ /* -+ * If we have plenty of inactive file pages that aren't -+ * thrashing, try to reclaim those first before touching -+ * anonymous pages. -+ */ -+ file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE); -+ if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE)) -+ sc->cache_trim_mode = 1; -+ else -+ sc->cache_trim_mode = 0; -+ -+ /* -+ * Prevent the reclaimer from falling into the cache trap: as -+ * cache pages start out inactive, every cache fault will tip -+ * the scan balance towards the file LRU. And as the file LRU -+ * shrinks, so does the window for rotation from references. -+ * This means we have a runaway feedback loop where a tiny -+ * thrashing file LRU becomes infinitely more attractive than -+ * anon pages. Try to detect this based on file LRU size. -+ */ -+ if (!cgroup_reclaim(sc)) { -+ unsigned long total_high_wmark = 0; -+ unsigned long free, anon; -+ int z; -+ -+ free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES); -+ file = node_page_state(pgdat, NR_ACTIVE_FILE) + -+ node_page_state(pgdat, NR_INACTIVE_FILE); -+ -+ for (z = 0; z < MAX_NR_ZONES; z++) { -+ struct zone *zone = &pgdat->node_zones[z]; -+ -+ if (!managed_zone(zone)) -+ continue; -+ -+ total_high_wmark += high_wmark_pages(zone); -+ } -+ -+ /* -+ * Consider anon: if that's low too, this isn't a -+ * runaway file reclaim problem, but rather just -+ * extreme pressure. Reclaim as per usual then. -+ */ -+ anon = node_page_state(pgdat, NR_INACTIVE_ANON); -+ -+ sc->file_is_tiny = -+ file + free <= total_high_wmark && -+ !(sc->may_deactivate & DEACTIVATE_ANON) && -+ anon >> sc->priority; -+ } -+} -+ - /* - * Determine how aggressively the anon and file LRU lists should be - * scanned. The relative value of each set of LRU lists is determined -@@ -2645,6 +2757,2464 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, - } - } - -+#ifdef CONFIG_LRU_GEN -+ -+/* -+ * After a page is faulted in, the aging must scan it twice before the eviction -+ * can consider it. The first scan clears the accessed bit set during the -+ * initial fault. And the second scan makes sure it hasn't been used since the -+ * first scan. -+ */ -+#define MIN_NR_GENS 2 -+ -+#define MAX_BATCH_SIZE 8192 -+ -+/****************************************************************************** -+ * shorthand helpers -+ ******************************************************************************/ -+ -+#define DEFINE_MAX_SEQ(lruvec) \ -+ unsigned long max_seq = READ_ONCE((lruvec)->evictable.max_seq) -+ -+#define DEFINE_MIN_SEQ(lruvec) \ -+ unsigned long min_seq[ANON_AND_FILE] = { \ -+ READ_ONCE((lruvec)->evictable.min_seq[0]), \ -+ READ_ONCE((lruvec)->evictable.min_seq[1]), \ -+ } -+ -+#define for_each_type_zone(type, zone) \ -+ for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ -+ for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) -+ -+#define for_each_gen_type_zone(gen, type, zone) \ -+ for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++) \ -+ for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ -+ for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) -+ -+static int page_lru_gen(struct page *page) -+{ -+ unsigned long flags = READ_ONCE(page->flags); -+ -+ return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+} -+ -+static int page_lru_tier(struct page *page) -+{ -+ int usage; -+ unsigned long flags = READ_ONCE(page->flags); -+ -+ usage = (flags & LRU_TIER_FLAGS) == LRU_TIER_FLAGS ? -+ ((flags & LRU_USAGE_MASK) >> LRU_USAGE_PGOFF) + 1 : 0; -+ -+ return lru_tier_from_usage(usage); -+} -+ -+static int get_lo_wmark(unsigned long max_seq, unsigned long *min_seq, int swappiness) -+{ -+ return max_seq - max(min_seq[!swappiness], min_seq[1]) + 1; -+} -+ -+static int get_hi_wmark(unsigned long max_seq, unsigned long *min_seq, int swappiness) -+{ -+ return max_seq - min(min_seq[!swappiness], min_seq[1]) + 1; -+} -+ -+static int get_nr_gens(struct lruvec *lruvec, int type) -+{ -+ return lruvec->evictable.max_seq - lruvec->evictable.min_seq[type] + 1; -+} -+ -+static int get_swappiness(struct mem_cgroup *memcg) -+{ -+ return mem_cgroup_get_nr_swap_pages(memcg) >= (long)SWAP_CLUSTER_MAX ? -+ mem_cgroup_swappiness(memcg) : 0; -+} -+ -+static bool __maybe_unused seq_is_valid(struct lruvec *lruvec) -+{ -+ return get_nr_gens(lruvec, 0) >= MIN_NR_GENS && -+ get_nr_gens(lruvec, 0) <= MAX_NR_GENS && -+ get_nr_gens(lruvec, 1) >= MIN_NR_GENS && -+ get_nr_gens(lruvec, 1) <= MAX_NR_GENS; -+} -+ -+/****************************************************************************** -+ * refault feedback loop -+ ******************************************************************************/ -+ -+/* -+ * A feedback loop modeled after the PID controller. Currently supports the -+ * proportional (P) and the integral (I) terms; the derivative (D) term can be -+ * added if necessary. The setpoint (SP) is the desired position; the process -+ * variable (PV) is the measured position. The error is the difference between -+ * the SP and the PV. A positive error results in a positive control output -+ * correction, which, in our case, is to allow eviction. -+ * -+ * The P term is the refault rate of the current generation being evicted. The I -+ * term is the exponential moving average of the refault rates of the previous -+ * generations, using the smoothing factor 1/2. -+ * -+ * Our goal is to make sure upper tiers have similar refault rates as the base -+ * tier. That is we try to be fair to all tiers by maintaining similar refault -+ * rates across them. -+ */ -+struct controller_pos { -+ unsigned long refaulted; -+ unsigned long total; -+ int gain; -+}; -+ -+static void read_controller_pos(struct controller_pos *pos, struct lruvec *lruvec, -+ int type, int tier, int gain) -+{ -+ struct lrugen *lrugen = &lruvec->evictable; -+ int hist = lru_hist_from_seq(lrugen->min_seq[type]); -+ -+ pos->refaulted = lrugen->avg_refaulted[type][tier] + -+ atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ pos->total = lrugen->avg_total[type][tier] + -+ atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ pos->total += lrugen->protected[hist][type][tier - 1]; -+ pos->gain = gain; -+} -+ -+static void reset_controller_pos(struct lruvec *lruvec, int gen, int type) -+{ -+ int tier; -+ int hist = lru_hist_from_seq(gen); -+ struct lrugen *lrugen = &lruvec->evictable; -+ bool carryover = gen == lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ if (!carryover && NR_STAT_GENS == 1) -+ return; -+ -+ for (tier = 0; tier < MAX_NR_TIERS; tier++) { -+ if (carryover) { -+ unsigned long sum; -+ -+ sum = lrugen->avg_refaulted[type][tier] + -+ atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ WRITE_ONCE(lrugen->avg_refaulted[type][tier], sum / 2); -+ -+ sum = lrugen->avg_total[type][tier] + -+ atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ sum += lrugen->protected[hist][type][tier - 1]; -+ WRITE_ONCE(lrugen->avg_total[type][tier], sum / 2); -+ -+ if (NR_STAT_GENS > 1) -+ continue; -+ } -+ -+ atomic_long_set(&lrugen->refaulted[hist][type][tier], 0); -+ atomic_long_set(&lrugen->evicted[hist][type][tier], 0); -+ if (tier) -+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1], 0); -+ } -+} -+ -+static bool positive_ctrl_err(struct controller_pos *sp, struct controller_pos *pv) -+{ -+ /* -+ * Allow eviction if the PV has a limited number of refaulted pages or a -+ * lower refault rate than the SP. -+ */ -+ return pv->refaulted < SWAP_CLUSTER_MAX || -+ pv->refaulted * max(sp->total, 1UL) * sp->gain <= -+ sp->refaulted * max(pv->total, 1UL) * pv->gain; -+} -+ -+/****************************************************************************** -+ * mm_struct list -+ ******************************************************************************/ -+ -+enum { -+ MM_SCHED_ACTIVE, /* running processes */ -+ MM_SCHED_INACTIVE, /* sleeping processes */ -+ MM_LOCK_CONTENTION, /* lock contentions */ -+ MM_VMA_INTERVAL, /* VMAs within the range of each PUD/PMD/PTE */ -+ MM_LEAF_OTHER_NODE, /* entries not from the node under reclaim */ -+ MM_LEAF_OTHER_MEMCG, /* entries not from the memcg under reclaim */ -+ MM_LEAF_OLD, /* old entries */ -+ MM_LEAF_YOUNG, /* young entries */ -+ MM_LEAF_DIRTY, /* dirty entries */ -+ MM_LEAF_HOLE, /* non-present entries */ -+ MM_NONLEAF_OLD, /* old non-leaf PMD entries */ -+ MM_NONLEAF_YOUNG, /* young non-leaf PMD entries */ -+ NR_MM_STATS -+}; -+ -+/* mnemonic codes for the stats above */ -+#define MM_STAT_CODES "aicvnmoydhlu" -+ -+struct lru_gen_mm_list { -+ /* the head of a global or per-memcg mm_struct list */ -+ struct list_head head; -+ /* protects the list */ -+ spinlock_t lock; -+ struct { -+ /* set to max_seq after each round of walk */ -+ unsigned long cur_seq; -+ /* the next mm_struct on the list to walk */ -+ struct list_head *iter; -+ /* to wait for the last walker to finish */ -+ struct wait_queue_head wait; -+ /* the number of concurrent walkers */ -+ int nr_walkers; -+ /* stats for debugging */ -+ unsigned long stats[NR_STAT_GENS][NR_MM_STATS]; -+ } nodes[0]; -+}; -+ -+static struct lru_gen_mm_list *global_mm_list; -+ -+static struct lru_gen_mm_list *alloc_mm_list(void) -+{ -+ int nid; -+ struct lru_gen_mm_list *mm_list; -+ -+ mm_list = kvzalloc(struct_size(mm_list, nodes, nr_node_ids), GFP_KERNEL); -+ if (!mm_list) -+ return NULL; -+ -+ INIT_LIST_HEAD(&mm_list->head); -+ spin_lock_init(&mm_list->lock); -+ -+ for_each_node(nid) { -+ mm_list->nodes[nid].cur_seq = MIN_NR_GENS; -+ mm_list->nodes[nid].iter = &mm_list->head; -+ init_waitqueue_head(&mm_list->nodes[nid].wait); -+ } -+ -+ return mm_list; -+} -+ -+static struct lru_gen_mm_list *get_mm_list(struct mem_cgroup *memcg) -+{ -+#ifdef CONFIG_MEMCG -+ if (!mem_cgroup_disabled()) -+ return memcg ? memcg->mm_list : root_mem_cgroup->mm_list; -+#endif -+ VM_BUG_ON(memcg); -+ -+ return global_mm_list; -+} -+ -+void lru_gen_init_mm(struct mm_struct *mm) -+{ -+ INIT_LIST_HEAD(&mm->lrugen.list); -+#ifdef CONFIG_MEMCG -+ mm->lrugen.memcg = NULL; -+#endif -+#ifndef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH -+ atomic_set(&mm->lrugen.nr_cpus, 0); -+#endif -+ nodes_clear(mm->lrugen.nodes); -+} -+ -+void lru_gen_add_mm(struct mm_struct *mm) -+{ -+ struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ -+ VM_BUG_ON_MM(!list_empty(&mm->lrugen.list), mm); -+#ifdef CONFIG_MEMCG -+ VM_BUG_ON_MM(mm->lrugen.memcg, mm); -+ WRITE_ONCE(mm->lrugen.memcg, memcg); -+#endif -+ spin_lock(&mm_list->lock); -+ list_add_tail(&mm->lrugen.list, &mm_list->head); -+ spin_unlock(&mm_list->lock); -+} -+ -+void lru_gen_del_mm(struct mm_struct *mm) -+{ -+ int nid; -+#ifdef CONFIG_MEMCG -+ struct lru_gen_mm_list *mm_list = get_mm_list(mm->lrugen.memcg); -+#else -+ struct lru_gen_mm_list *mm_list = get_mm_list(NULL); -+#endif -+ -+ spin_lock(&mm_list->lock); -+ -+ for_each_node(nid) { -+ if (mm_list->nodes[nid].iter != &mm->lrugen.list) -+ continue; -+ -+ mm_list->nodes[nid].iter = mm_list->nodes[nid].iter->next; -+ if (mm_list->nodes[nid].iter == &mm_list->head) -+ WRITE_ONCE(mm_list->nodes[nid].cur_seq, -+ mm_list->nodes[nid].cur_seq + 1); -+ } -+ -+ list_del_init(&mm->lrugen.list); -+ -+ spin_unlock(&mm_list->lock); -+ -+#ifdef CONFIG_MEMCG -+ mem_cgroup_put(mm->lrugen.memcg); -+ WRITE_ONCE(mm->lrugen.memcg, NULL); -+#endif -+} -+ -+#ifdef CONFIG_MEMCG -+int lru_gen_alloc_mm_list(struct mem_cgroup *memcg) -+{ -+ if (mem_cgroup_disabled()) -+ return 0; -+ -+ memcg->mm_list = alloc_mm_list(); -+ -+ return memcg->mm_list ? 0 : -ENOMEM; -+} -+ -+void lru_gen_free_mm_list(struct mem_cgroup *memcg) -+{ -+ kvfree(memcg->mm_list); -+ memcg->mm_list = NULL; -+} -+ -+void lru_gen_migrate_mm(struct mm_struct *mm) -+{ -+ struct mem_cgroup *memcg; -+ -+ lockdep_assert_held(&mm->owner->alloc_lock); -+ -+ if (mem_cgroup_disabled()) -+ return; -+ -+ rcu_read_lock(); -+ memcg = mem_cgroup_from_task(mm->owner); -+ rcu_read_unlock(); -+ if (memcg == mm->lrugen.memcg) -+ return; -+ -+ VM_BUG_ON_MM(!mm->lrugen.memcg, mm); -+ VM_BUG_ON_MM(list_empty(&mm->lrugen.list), mm); -+ -+ lru_gen_del_mm(mm); -+ lru_gen_add_mm(mm); -+} -+ -+static bool mm_is_migrated(struct mm_struct *mm, struct mem_cgroup *memcg) -+{ -+ return READ_ONCE(mm->lrugen.memcg) != memcg; -+} -+#else -+static bool mm_is_migrated(struct mm_struct *mm, struct mem_cgroup *memcg) -+{ -+ return false; -+} -+#endif -+ -+struct mm_walk_args { -+ struct mem_cgroup *memcg; -+ unsigned long max_seq; -+ unsigned long start_pfn; -+ unsigned long end_pfn; -+ unsigned long next_addr; -+ int node_id; -+ int swappiness; -+ int batch_size; -+ int nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ int mm_stats[NR_MM_STATS]; -+ unsigned long bitmap[0]; -+}; -+ -+static void reset_mm_stats(struct lru_gen_mm_list *mm_list, bool last, -+ struct mm_walk_args *args) -+{ -+ int i; -+ int nid = args->node_id; -+ int hist = lru_hist_from_seq(args->max_seq); -+ -+ lockdep_assert_held(&mm_list->lock); -+ -+ for (i = 0; i < NR_MM_STATS; i++) { -+ WRITE_ONCE(mm_list->nodes[nid].stats[hist][i], -+ mm_list->nodes[nid].stats[hist][i] + args->mm_stats[i]); -+ args->mm_stats[i] = 0; -+ } -+ -+ if (!last || NR_STAT_GENS == 1) -+ return; -+ -+ hist = lru_hist_from_seq(args->max_seq + 1); -+ for (i = 0; i < NR_MM_STATS; i++) -+ WRITE_ONCE(mm_list->nodes[nid].stats[hist][i], 0); -+} -+ -+static bool should_skip_mm(struct mm_struct *mm, struct mm_walk_args *args) -+{ -+ int type; -+ unsigned long size = 0; -+ -+ if (!lru_gen_mm_is_active(mm) && !node_isset(args->node_id, mm->lrugen.nodes)) -+ return true; -+ -+ if (mm_is_oom_victim(mm)) -+ return true; -+ -+ for (type = !args->swappiness; type < ANON_AND_FILE; type++) { -+ size += type ? get_mm_counter(mm, MM_FILEPAGES) : -+ get_mm_counter(mm, MM_ANONPAGES) + -+ get_mm_counter(mm, MM_SHMEMPAGES); -+ } -+ -+ /* leave the legwork to the rmap if the mappings are too sparse */ -+ if (size < max(SWAP_CLUSTER_MAX, mm_pgtables_bytes(mm) / PAGE_SIZE)) -+ return true; -+ -+ return !mmget_not_zero(mm); -+} -+ -+/* To support multiple walkers that concurrently walk an mm_struct list. */ -+static bool get_next_mm(struct mm_walk_args *args, struct mm_struct **iter) -+{ -+ bool last = true; -+ struct mm_struct *mm = NULL; -+ int nid = args->node_id; -+ struct lru_gen_mm_list *mm_list = get_mm_list(args->memcg); -+ -+ if (*iter) -+ mmput_async(*iter); -+ else if (args->max_seq <= READ_ONCE(mm_list->nodes[nid].cur_seq)) -+ return false; -+ -+ spin_lock(&mm_list->lock); -+ -+ VM_BUG_ON(args->max_seq > mm_list->nodes[nid].cur_seq + 1); -+ VM_BUG_ON(*iter && args->max_seq < mm_list->nodes[nid].cur_seq); -+ VM_BUG_ON(*iter && !mm_list->nodes[nid].nr_walkers); -+ -+ if (args->max_seq <= mm_list->nodes[nid].cur_seq) { -+ last = *iter; -+ goto done; -+ } -+ -+ if (mm_list->nodes[nid].iter == &mm_list->head) { -+ VM_BUG_ON(*iter || mm_list->nodes[nid].nr_walkers); -+ mm_list->nodes[nid].iter = mm_list->nodes[nid].iter->next; -+ } -+ -+ while (!mm && mm_list->nodes[nid].iter != &mm_list->head) { -+ mm = list_entry(mm_list->nodes[nid].iter, struct mm_struct, lrugen.list); -+ mm_list->nodes[nid].iter = mm_list->nodes[nid].iter->next; -+ if (should_skip_mm(mm, args)) -+ mm = NULL; -+ -+ args->mm_stats[mm ? MM_SCHED_ACTIVE : MM_SCHED_INACTIVE]++; -+ } -+ -+ if (mm_list->nodes[nid].iter == &mm_list->head) -+ WRITE_ONCE(mm_list->nodes[nid].cur_seq, -+ mm_list->nodes[nid].cur_seq + 1); -+done: -+ if (*iter && !mm) -+ mm_list->nodes[nid].nr_walkers--; -+ if (!*iter && mm) -+ mm_list->nodes[nid].nr_walkers++; -+ -+ last = last && !mm_list->nodes[nid].nr_walkers && -+ mm_list->nodes[nid].iter == &mm_list->head; -+ -+ reset_mm_stats(mm_list, last, args); -+ -+ spin_unlock(&mm_list->lock); -+ -+ *iter = mm; -+ if (mm) -+ node_clear(nid, mm->lrugen.nodes); -+ -+ return last; -+} -+ -+/****************************************************************************** -+ * the aging -+ ******************************************************************************/ -+ -+static int page_update_gen(struct page *page, int gen) -+{ -+ unsigned long old_flags, new_flags; -+ -+ VM_BUG_ON(gen >= MAX_NR_GENS); -+ -+ do { -+ new_flags = old_flags = READ_ONCE(page->flags); -+ -+ if (!(new_flags & LRU_GEN_MASK)) { -+ new_flags |= BIT(PG_referenced); -+ continue; -+ } -+ -+ new_flags &= ~(LRU_GEN_MASK | LRU_USAGE_MASK | LRU_TIER_FLAGS); -+ new_flags |= (gen + 1UL) << LRU_GEN_PGOFF; -+ } while (new_flags != old_flags && -+ cmpxchg(&page->flags, old_flags, new_flags) != old_flags); -+ -+ return ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+} -+ -+static void page_inc_gen(struct page *page, struct lruvec *lruvec, bool reclaiming) -+{ -+ int old_gen, new_gen; -+ unsigned long old_flags, new_flags; -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ old_gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ do { -+ new_flags = old_flags = READ_ONCE(page->flags); -+ VM_BUG_ON_PAGE(!(new_flags & LRU_GEN_MASK), page); -+ -+ new_gen = ((new_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+ /* page_update_gen() has updated this page? */ -+ if (new_gen >= 0 && new_gen != old_gen) { -+ list_move(&page->lru, &lrugen->lists[new_gen][type][zone]); -+ return; -+ } -+ -+ new_gen = (old_gen + 1) % MAX_NR_GENS; -+ -+ new_flags &= ~(LRU_GEN_MASK | LRU_USAGE_MASK | LRU_TIER_FLAGS); -+ new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF; -+ /* for rotate_reclaimable_page() */ -+ if (reclaiming) -+ new_flags |= BIT(PG_reclaim); -+ } while (cmpxchg(&page->flags, old_flags, new_flags) != old_flags); -+ -+ lru_gen_update_size(page, lruvec, old_gen, new_gen); -+ if (reclaiming) -+ list_move(&page->lru, &lrugen->lists[new_gen][type][zone]); -+ else -+ list_move_tail(&page->lru, &lrugen->lists[new_gen][type][zone]); -+} -+ -+static void update_batch_size(struct page *page, int old_gen, int new_gen, -+ struct mm_walk_args *args) -+{ -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ int delta = thp_nr_pages(page); -+ -+ VM_BUG_ON(old_gen >= MAX_NR_GENS); -+ VM_BUG_ON(new_gen >= MAX_NR_GENS); -+ -+ args->batch_size++; -+ -+ args->nr_pages[old_gen][type][zone] -= delta; -+ args->nr_pages[new_gen][type][zone] += delta; -+} -+ -+static void reset_batch_size(struct lruvec *lruvec, struct mm_walk_args *args) -+{ -+ int gen, type, zone; -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ if (!args->batch_size) -+ return; -+ -+ args->batch_size = 0; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ enum lru_list lru = type * LRU_FILE; -+ int total = args->nr_pages[gen][type][zone]; -+ -+ if (!total) -+ continue; -+ -+ args->nr_pages[gen][type][zone] = 0; -+ WRITE_ONCE(lrugen->sizes[gen][type][zone], -+ lrugen->sizes[gen][type][zone] + total); -+ -+ if (lru_gen_is_active(lruvec, gen)) -+ lru += LRU_ACTIVE; -+ update_lru_size(lruvec, lru, zone, total); -+ } -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+} -+ -+static int should_skip_vma(unsigned long start, unsigned long end, struct mm_walk *walk) -+{ -+ struct address_space *mapping; -+ struct vm_area_struct *vma = walk->vma; -+ struct mm_walk_args *args = walk->private; -+ -+ if (!vma_is_accessible(vma) || is_vm_hugetlb_page(vma) || -+ (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ))) -+ return true; -+ -+ if (vma_is_anonymous(vma)) -+ return !args->swappiness; -+ -+ if (WARN_ON_ONCE(!vma->vm_file || !vma->vm_file->f_mapping)) -+ return true; -+ -+ mapping = vma->vm_file->f_mapping; -+ if (!mapping->a_ops->writepage) -+ return true; -+ -+ return (shmem_mapping(mapping) && !args->swappiness) || mapping_unevictable(mapping); -+} -+ -+/* -+ * Some userspace memory allocators create many single-page VMAs. So instead of -+ * returning back to the PGD table for each of such VMAs, we finish at least an -+ * entire PMD table and therefore avoid many zigzags. -+ */ -+static bool get_next_vma(struct mm_walk *walk, unsigned long mask, unsigned long size, -+ unsigned long *start, unsigned long *end) -+{ -+ unsigned long next = round_up(*end, size); -+ struct mm_walk_args *args = walk->private; -+ -+ VM_BUG_ON(mask & size); -+ VM_BUG_ON(*start >= *end); -+ VM_BUG_ON((next & mask) != (*start & mask)); -+ -+ while (walk->vma) { -+ if (next >= walk->vma->vm_end) { -+ walk->vma = walk->vma->vm_next; -+ continue; -+ } -+ -+ if ((next & mask) != (walk->vma->vm_start & mask)) -+ return false; -+ -+ if (should_skip_vma(walk->vma->vm_start, walk->vma->vm_end, walk)) { -+ walk->vma = walk->vma->vm_next; -+ continue; -+ } -+ -+ *start = max(next, walk->vma->vm_start); -+ next = (next | ~mask) + 1; -+ /* rounded-up boundaries can wrap to 0 */ -+ *end = next && next < walk->vma->vm_end ? next : walk->vma->vm_end; -+ -+ args->mm_stats[MM_VMA_INTERVAL]++; -+ -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end, -+ struct mm_walk *walk) -+{ -+ int i; -+ pte_t *pte; -+ spinlock_t *ptl; -+ unsigned long addr; -+ int remote = 0; -+ struct mm_walk_args *args = walk->private; -+ int old_gen, new_gen = lru_gen_from_seq(args->max_seq); -+ -+ VM_BUG_ON(pmd_leaf(*pmd)); -+ -+ pte = pte_offset_map_lock(walk->mm, pmd, start & PMD_MASK, &ptl); -+ arch_enter_lazy_mmu_mode(); -+restart: -+ for (i = pte_index(start), addr = start; addr != end; i++, addr += PAGE_SIZE) { -+ struct page *page; -+ unsigned long pfn = pte_pfn(pte[i]); -+ -+ if (!pte_present(pte[i]) || is_zero_pfn(pfn)) { -+ args->mm_stats[MM_LEAF_HOLE]++; -+ continue; -+ } -+ -+ if (WARN_ON_ONCE(pte_devmap(pte[i]) || pte_special(pte[i]))) -+ continue; -+ -+ if (!pte_young(pte[i])) { -+ args->mm_stats[MM_LEAF_OLD]++; -+ continue; -+ } -+ -+ VM_BUG_ON(!pfn_valid(pfn)); -+ if (pfn < args->start_pfn || pfn >= args->end_pfn) { -+ args->mm_stats[MM_LEAF_OTHER_NODE]++; -+ remote++; -+ continue; -+ } -+ -+ page = compound_head(pfn_to_page(pfn)); -+ if (page_to_nid(page) != args->node_id) { -+ args->mm_stats[MM_LEAF_OTHER_NODE]++; -+ remote++; -+ continue; -+ } -+ -+ if (page_memcg_rcu(page) != args->memcg) { -+ args->mm_stats[MM_LEAF_OTHER_MEMCG]++; -+ continue; -+ } -+ -+ VM_BUG_ON(addr < walk->vma->vm_start || addr >= walk->vma->vm_end); -+ if (!ptep_test_and_clear_young(walk->vma, addr, pte + i)) -+ continue; -+ -+ if (pte_dirty(pte[i]) && !PageDirty(page) && -+ !(PageAnon(page) && PageSwapBacked(page) && !PageSwapCache(page))) { -+ set_page_dirty(page); -+ args->mm_stats[MM_LEAF_DIRTY]++; -+ } -+ -+ old_gen = page_update_gen(page, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ update_batch_size(page, old_gen, new_gen, args); -+ args->mm_stats[MM_LEAF_YOUNG]++; -+ } -+ -+ if (i < PTRS_PER_PTE && get_next_vma(walk, PMD_MASK, PAGE_SIZE, &start, &end)) -+ goto restart; -+ -+ arch_leave_lazy_mmu_mode(); -+ pte_unmap_unlock(pte, ptl); -+ -+ return IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && !remote; -+} -+ -+/* -+ * We scan PMD entries in two passes. The first pass reaches to PTE tables and -+ * doesn't take the PMD lock. The second pass clears the accessed bit on PMD -+ * entries and needs to take the PMD lock. -+ */ -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) -+static void walk_pmd_range_locked(pud_t *pud, unsigned long start, -+ struct vm_area_struct *vma, struct mm_walk *walk) -+{ -+ int i; -+ pmd_t *pmd; -+ spinlock_t *ptl; -+ struct mm_walk_args *args = walk->private; -+ int old_gen, new_gen = lru_gen_from_seq(args->max_seq); -+ -+ VM_BUG_ON(pud_leaf(*pud)); -+ -+ start &= PUD_MASK; -+ pmd = pmd_offset(pud, start); -+ ptl = pmd_lock(walk->mm, pmd); -+ arch_enter_lazy_mmu_mode(); -+ -+ for_each_set_bit(i, args->bitmap, PTRS_PER_PMD) { -+ struct page *page; -+ unsigned long pfn = pmd_pfn(pmd[i]); -+ unsigned long addr = start + i * PMD_SIZE; -+ -+ if (!pmd_present(pmd[i]) || is_huge_zero_pmd(pmd[i])) { -+ args->mm_stats[MM_LEAF_HOLE]++; -+ continue; -+ } -+ -+ if (WARN_ON_ONCE(pmd_devmap(pmd[i]))) -+ continue; -+ -+ if (!pmd_young(pmd[i])) { -+ args->mm_stats[MM_LEAF_OLD]++; -+ continue; -+ } -+ -+ if (!pmd_trans_huge(pmd[i])) { -+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && -+ pmdp_test_and_clear_young(vma, addr, pmd + i)) -+ args->mm_stats[MM_NONLEAF_YOUNG]++; -+ continue; -+ } -+ -+ VM_BUG_ON(!pfn_valid(pfn)); -+ if (pfn < args->start_pfn || pfn >= args->end_pfn) { -+ args->mm_stats[MM_LEAF_OTHER_NODE]++; -+ continue; -+ } -+ -+ page = pfn_to_page(pfn); -+ VM_BUG_ON_PAGE(PageTail(page), page); -+ if (page_to_nid(page) != args->node_id) { -+ args->mm_stats[MM_LEAF_OTHER_NODE]++; -+ continue; -+ } -+ -+ if (page_memcg_rcu(page) != args->memcg) { -+ args->mm_stats[MM_LEAF_OTHER_MEMCG]++; -+ continue; -+ } -+ -+ VM_BUG_ON(addr < vma->vm_start || addr >= vma->vm_end); -+ if (!pmdp_test_and_clear_young(vma, addr, pmd + i)) -+ continue; -+ -+ if (pmd_dirty(pmd[i]) && !PageDirty(page) && -+ !(PageAnon(page) && PageSwapBacked(page) && !PageSwapCache(page))) { -+ set_page_dirty(page); -+ args->mm_stats[MM_LEAF_DIRTY]++; -+ } -+ -+ old_gen = page_update_gen(page, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ update_batch_size(page, old_gen, new_gen, args); -+ args->mm_stats[MM_LEAF_YOUNG]++; -+ } -+ -+ arch_leave_lazy_mmu_mode(); -+ spin_unlock(ptl); -+ -+ bitmap_zero(args->bitmap, PTRS_PER_PMD); -+} -+#else -+static void walk_pmd_range_locked(pud_t *pud, unsigned long start, -+ struct vm_area_struct *vma, struct mm_walk *walk) -+{ -+} -+#endif -+ -+static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end, -+ struct mm_walk *walk) -+{ -+ int i; -+ pmd_t *pmd; -+ unsigned long next; -+ unsigned long addr; -+ struct vm_area_struct *vma; -+ int leaf = 0; -+ int nonleaf = 0; -+ struct mm_walk_args *args = walk->private; -+ -+ VM_BUG_ON(pud_leaf(*pud)); -+ -+ pmd = pmd_offset(pud, start & PUD_MASK); -+restart: -+ vma = walk->vma; -+ for (i = pmd_index(start), addr = start; addr != end; i++, addr = next) { -+ pmd_t val = pmd_read_atomic(pmd + i); -+ -+ /* for pmd_read_atomic() */ -+ barrier(); -+ -+ next = pmd_addr_end(addr, end); -+ -+ if (!pmd_present(val)) { -+ args->mm_stats[MM_LEAF_HOLE]++; -+ continue; -+ } -+ -+#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+ if (pmd_trans_huge(val)) { -+ unsigned long pfn = pmd_pfn(val); -+ -+ if (is_huge_zero_pmd(val)) { -+ args->mm_stats[MM_LEAF_HOLE]++; -+ continue; -+ } -+ -+ if (!pmd_young(val)) { -+ args->mm_stats[MM_LEAF_OLD]++; -+ continue; -+ } -+ -+ if (pfn < args->start_pfn || pfn >= args->end_pfn) { -+ args->mm_stats[MM_LEAF_OTHER_NODE]++; -+ continue; -+ } -+ -+ __set_bit(i, args->bitmap); -+ leaf++; -+ continue; -+ } -+#endif -+ -+#ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -+ if (!pmd_young(val)) { -+ args->mm_stats[MM_NONLEAF_OLD]++; -+ continue; -+ } -+#endif -+ if (walk_pte_range(&val, addr, next, walk)) { -+ __set_bit(i, args->bitmap); -+ nonleaf++; -+ } -+ } -+ -+ if (leaf) { -+ walk_pmd_range_locked(pud, start, vma, walk); -+ leaf = nonleaf = 0; -+ } -+ -+ if (i < PTRS_PER_PMD && get_next_vma(walk, PUD_MASK, PMD_SIZE, &start, &end)) -+ goto restart; -+ -+ if (nonleaf) -+ walk_pmd_range_locked(pud, start, vma, walk); -+} -+ -+static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end, -+ struct mm_walk *walk) -+{ -+ int i; -+ pud_t *pud; -+ unsigned long addr; -+ unsigned long next; -+ struct mm_walk_args *args = walk->private; -+ -+ VM_BUG_ON(p4d_leaf(*p4d)); -+ -+ pud = pud_offset(p4d, start & P4D_MASK); -+restart: -+ for (i = pud_index(start), addr = start; addr != end; i++, addr = next) { -+ pud_t val = READ_ONCE(pud[i]); -+ -+ next = pud_addr_end(addr, end); -+ -+ if (!pud_present(val) || WARN_ON_ONCE(pud_leaf(val))) -+ continue; -+ -+ walk_pmd_range(&val, addr, next, walk); -+ -+ if (args->batch_size >= MAX_BATCH_SIZE) { -+ end = (addr | ~PUD_MASK) + 1; -+ goto done; -+ } -+ } -+ -+ if (i < PTRS_PER_PUD && get_next_vma(walk, P4D_MASK, PUD_SIZE, &start, &end)) -+ goto restart; -+ -+ end = round_up(end, P4D_SIZE); -+done: -+ /* rounded-up boundaries can wrap to 0 */ -+ args->next_addr = end && walk->vma ? max(end, walk->vma->vm_start) : 0; -+ -+ return -EAGAIN; -+} -+ -+static void walk_mm(struct mm_walk_args *args, struct mm_struct *mm) -+{ -+ static const struct mm_walk_ops mm_walk_ops = { -+ .test_walk = should_skip_vma, -+ .p4d_entry = walk_pud_range, -+ }; -+ -+ int err; -+ struct mem_cgroup *memcg = args->memcg; -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(args->node_id)); -+ -+ args->next_addr = FIRST_USER_ADDRESS; -+ -+ do { -+ unsigned long start = args->next_addr; -+ unsigned long end = mm->highest_vm_end; -+ -+ err = -EBUSY; -+ -+ rcu_read_lock(); -+#ifdef CONFIG_MEMCG -+ if (memcg && atomic_read(&memcg->moving_account)) { -+ args->mm_stats[MM_LOCK_CONTENTION]++; -+ goto contended; -+ } -+#endif -+ if (!mmap_read_trylock(mm)) { -+ args->mm_stats[MM_LOCK_CONTENTION]++; -+ goto contended; -+ } -+ -+ err = walk_page_range(mm, start, end, &mm_walk_ops, args); -+ -+ mmap_read_unlock(mm); -+ -+ reset_batch_size(lruvec, args); -+contended: -+ rcu_read_unlock(); -+ -+ cond_resched(); -+ } while (err == -EAGAIN && args->next_addr && -+ !mm_is_oom_victim(mm) && !mm_is_migrated(mm, memcg)); -+} -+ -+static struct mm_walk_args *alloc_mm_walk_args(int nid) -+{ -+ struct pglist_data *pgdat; -+ int size = sizeof(struct mm_walk_args); -+ -+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) || -+ IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)) -+ size += sizeof(unsigned long) * BITS_TO_LONGS(PTRS_PER_PMD); -+ -+ if (!current_is_kswapd()) -+ return kvzalloc_node(size, GFP_KERNEL, nid); -+ -+ VM_BUG_ON(nid == NUMA_NO_NODE); -+ -+ pgdat = NODE_DATA(nid); -+ if (!pgdat->mm_walk_args) -+ pgdat->mm_walk_args = kvzalloc_node(size, GFP_KERNEL, nid); -+ -+ return pgdat->mm_walk_args; -+} -+ -+static void free_mm_walk_args(struct mm_walk_args *args) -+{ -+ if (!current_is_kswapd()) -+ kvfree(args); -+} -+ -+static bool inc_min_seq(struct lruvec *lruvec, int type) -+{ -+ int gen, zone; -+ int remaining = MAX_BATCH_SIZE; -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ VM_BUG_ON(!seq_is_valid(lruvec)); -+ -+ if (get_nr_gens(lruvec, type) != MAX_NR_GENS) -+ return true; -+ -+ gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ struct list_head *head = &lrugen->lists[gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ struct page *page = lru_to_page(head); -+ -+ VM_BUG_ON_PAGE(PageTail(page), page); -+ VM_BUG_ON_PAGE(PageUnevictable(page), page); -+ VM_BUG_ON_PAGE(PageActive(page), page); -+ VM_BUG_ON_PAGE(page_is_file_lru(page) != type, page); -+ VM_BUG_ON_PAGE(page_zonenum(page) != zone, page); -+ -+ prefetchw_prev_lru_page(page, head, flags); -+ -+ page_inc_gen(page, lruvec, false); -+ -+ if (!--remaining) -+ return false; -+ } -+ -+ VM_BUG_ON(lrugen->sizes[gen][type][zone]); -+ } -+ -+ reset_controller_pos(lruvec, gen, type); -+ WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1); -+ -+ return true; -+} -+ -+static bool try_to_inc_min_seq(struct lruvec *lruvec, int type) -+{ -+ int gen, zone; -+ bool success = false; -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ VM_BUG_ON(!seq_is_valid(lruvec)); -+ -+ while (get_nr_gens(lruvec, type) > MIN_NR_GENS) { -+ gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ if (!list_empty(&lrugen->lists[gen][type][zone])) -+ return success; -+ } -+ -+ reset_controller_pos(lruvec, gen, type); -+ WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1); -+ -+ success = true; -+ } -+ -+ return success; -+} -+ -+static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq) -+{ -+ int gen, type, zone; -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ VM_BUG_ON(!seq_is_valid(lruvec)); -+ -+ if (max_seq != lrugen->max_seq) -+ goto unlock; -+ -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ if (try_to_inc_min_seq(lruvec, type)) -+ continue; -+ -+ while (!inc_min_seq(lruvec, type)) { -+ spin_unlock_irq(&lruvec->lru_lock); -+ cond_resched(); -+ spin_lock_irq(&lruvec->lru_lock); -+ } -+ } -+ -+ gen = lru_gen_from_seq(lrugen->max_seq - 1); -+ for_each_type_zone(type, zone) { -+ enum lru_list lru = type * LRU_FILE; -+ long total = lrugen->sizes[gen][type][zone]; -+ -+ if (!total) -+ continue; -+ -+ WARN_ON_ONCE(total != (int)total); -+ -+ update_lru_size(lruvec, lru, zone, total); -+ update_lru_size(lruvec, lru + LRU_ACTIVE, zone, -total); -+ } -+ -+ gen = lru_gen_from_seq(lrugen->max_seq + 1); -+ for_each_type_zone(type, zone) { -+ VM_BUG_ON(lrugen->sizes[gen][type][zone]); -+ VM_BUG_ON(!list_empty(&lrugen->lists[gen][type][zone])); -+ } -+ -+ for (type = 0; type < ANON_AND_FILE; type++) -+ reset_controller_pos(lruvec, gen, type); -+ -+ WRITE_ONCE(lrugen->timestamps[gen], jiffies); -+ /* make sure all preceding modifications appear first */ -+ smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); -+unlock: -+ spin_unlock_irq(&lruvec->lru_lock); -+} -+ -+/* Main function used by the foreground, the background and the user-triggered aging. */ -+static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, -+ struct scan_control *sc, int swappiness) -+{ -+ bool last; -+ struct mm_walk_args *args; -+ struct mm_struct *mm = NULL; -+ struct lrugen *lrugen = &lruvec->evictable; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ int nid = pgdat->node_id; -+ -+ VM_BUG_ON(max_seq > READ_ONCE(lrugen->max_seq)); -+ -+ /* -+ * If we are not from run_aging() and clearing the accessed bit may -+ * trigger page faults, then don't proceed to clearing all accessed -+ * PTEs. Instead, fallback to lru_gen_scan_around(), which only clears a -+ * handful of accessed PTEs. This is less efficient but causes fewer -+ * page faults on CPUs that don't have the capability. -+ */ -+ if ((current->flags & PF_MEMALLOC) && !arch_has_hw_pte_young()) { -+ inc_max_seq(lruvec, max_seq); -+ return true; -+ } -+ -+ args = alloc_mm_walk_args(nid); -+ if (!args) -+ return false; -+ -+ args->memcg = memcg; -+ args->max_seq = max_seq; -+ args->start_pfn = pgdat->node_start_pfn; -+ args->end_pfn = pgdat_end_pfn(pgdat); -+ args->node_id = nid; -+ args->swappiness = swappiness; -+ -+ do { -+ last = get_next_mm(args, &mm); -+ if (mm) -+ walk_mm(args, mm); -+ -+ cond_resched(); -+ } while (mm); -+ -+ free_mm_walk_args(args); -+ -+ if (!last) { -+ /* don't wait unless we may have trouble reclaiming */ -+ if (!current_is_kswapd() && sc->priority < DEF_PRIORITY - 2) -+ wait_event_killable(mm_list->nodes[nid].wait, -+ max_seq < READ_ONCE(lrugen->max_seq)); -+ -+ return max_seq < READ_ONCE(lrugen->max_seq); -+ } -+ -+ VM_BUG_ON(max_seq != READ_ONCE(lrugen->max_seq)); -+ -+ inc_max_seq(lruvec, max_seq); -+ /* either we see any waiters or they will see updated max_seq */ -+ if (wq_has_sleeper(&mm_list->nodes[nid].wait)) -+ wake_up_all(&mm_list->nodes[nid].wait); -+ -+ wakeup_flusher_threads(WB_REASON_VMSCAN); -+ -+ return true; -+} -+ -+/* Protect the working set accessed within the last N milliseconds. */ -+static unsigned long lru_gen_min_ttl; -+ -+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ struct mem_cgroup *memcg; -+ -+ VM_BUG_ON(!current_is_kswapd()); -+ -+ if (sc->file_is_tiny && mutex_trylock(&oom_lock)) { -+ struct oom_control oc = { -+ .gfp_mask = sc->gfp_mask, -+ .order = sc->order, -+ }; -+ -+ /* to avoid overkilling */ -+ if (!oom_reaping_in_progress()) -+ out_of_memory(&oc); -+ -+ mutex_unlock(&oom_lock); -+ } -+ -+ if (READ_ONCE(lru_gen_min_ttl)) -+ sc->file_is_tiny = 1; -+ -+ if (!mem_cgroup_disabled() && !sc->force_deactivate) { -+ sc->force_deactivate = 1; -+ return; -+ } -+ -+ sc->force_deactivate = 0; -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ int swappiness = get_swappiness(memcg); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (get_lo_wmark(max_seq, min_seq, swappiness) == MIN_NR_GENS) -+ try_to_inc_max_seq(lruvec, max_seq, sc, swappiness); -+ -+ cond_resched(); -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+} -+ -+#define NR_TO_SCAN (SWAP_CLUSTER_MAX * 2) -+#define SIZE_TO_SCAN (NR_TO_SCAN * PAGE_SIZE) -+ -+/* Scan the vicinity of an accessed PTE when shrink_page_list() uses the rmap. */ -+void lru_gen_scan_around(struct page_vma_mapped_walk *pvmw) -+{ -+ int i; -+ pte_t *pte; -+ struct page *page; -+ int old_gen, new_gen; -+ unsigned long start; -+ unsigned long end; -+ unsigned long addr; -+ struct mem_cgroup *memcg = page_memcg(pvmw->page); -+ struct pglist_data *pgdat = page_pgdat(pvmw->page); -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ unsigned long bitmap[BITS_TO_LONGS(NR_TO_SCAN)] = {}; -+ -+ lockdep_assert_held(pvmw->ptl); -+ VM_BUG_ON_PAGE(PageLRU(pvmw->page), pvmw->page); -+ -+ start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start); -+ end = pmd_addr_end(pvmw->address, pvmw->vma->vm_end); -+ -+ if (end - start > SIZE_TO_SCAN) { -+ if (pvmw->address - start < SIZE_TO_SCAN / 2) -+ end = start + SIZE_TO_SCAN; -+ else if (end - pvmw->address < SIZE_TO_SCAN / 2) -+ start = end - SIZE_TO_SCAN; -+ else { -+ start = pvmw->address - SIZE_TO_SCAN / 2; -+ end = pvmw->address + SIZE_TO_SCAN / 2; -+ } -+ } -+ -+ pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE; -+ new_gen = lru_gen_from_seq(READ_ONCE(lruvec->evictable.max_seq)); -+ -+ rcu_read_lock(); -+ arch_enter_lazy_mmu_mode(); -+ -+ for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) { -+ unsigned long pfn = pte_pfn(pte[i]); -+ -+ if (!pte_present(pte[i]) || is_zero_pfn(pfn)) -+ continue; -+ -+ if (WARN_ON_ONCE(pte_devmap(pte[i]) || pte_special(pte[i]))) -+ continue; -+ -+ if (!pte_young(pte[i])) -+ continue; -+ -+ VM_BUG_ON(!pfn_valid(pfn)); -+ if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) -+ continue; -+ -+ page = compound_head(pfn_to_page(pfn)); -+ if (page_to_nid(page) != pgdat->node_id) -+ continue; -+ -+ if (page_memcg_rcu(page) != memcg) -+ continue; -+ -+ VM_BUG_ON(addr < pvmw->vma->vm_start || addr >= pvmw->vma->vm_end); -+ if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) -+ continue; -+ -+ old_gen = page_lru_gen(page); -+ if (old_gen < 0) -+ SetPageReferenced(page); -+ else if (old_gen != new_gen) -+ __set_bit(i, bitmap); -+ -+ if (pte_dirty(pte[i]) && !PageDirty(page) && -+ !(PageAnon(page) && PageSwapBacked(page) && !PageSwapCache(page))) -+ set_page_dirty(page); -+ } -+ -+ arch_leave_lazy_mmu_mode(); -+ rcu_read_unlock(); -+ -+ if (bitmap_weight(bitmap, NR_TO_SCAN) < PAGEVEC_SIZE) { -+ for_each_set_bit(i, bitmap, NR_TO_SCAN) -+ activate_page(pte_page(pte[i])); -+ return; -+ } -+ -+ lock_page_memcg(pvmw->page); -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ new_gen = lru_gen_from_seq(lruvec->evictable.max_seq); -+ -+ for_each_set_bit(i, bitmap, NR_TO_SCAN) { -+ page = compound_head(pte_page(pte[i])); -+ if (page_memcg_rcu(page) != memcg) -+ continue; -+ -+ old_gen = page_update_gen(page, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ lru_gen_update_size(page, lruvec, old_gen, new_gen); -+ } -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ unlock_page_memcg(pvmw->page); -+} -+ -+/****************************************************************************** -+ * the eviction -+ ******************************************************************************/ -+ -+static bool sort_page(struct page *page, struct lruvec *lruvec, int tier_to_isolate) -+{ -+ bool success; -+ int gen = page_lru_gen(page); -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ int tier = page_lru_tier(page); -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ VM_BUG_ON_PAGE(gen < 0, page); -+ VM_BUG_ON_PAGE(tier_to_isolate < 0, page); -+ -+ /* a lazy-free page that has been written into? */ -+ if (type && PageDirty(page) && PageAnon(page)) { -+ success = lru_gen_del_page(page, lruvec, false); -+ VM_BUG_ON_PAGE(!success, page); -+ SetPageSwapBacked(page); -+ add_page_to_lru_list_tail(page, lruvec); -+ return true; -+ } -+ -+ /* page_update_gen() has updated this page? */ -+ if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { -+ list_move(&page->lru, &lrugen->lists[gen][type][zone]); -+ return true; -+ } -+ -+ /* protect this page if its tier has a higher refault rate */ -+ if (tier_to_isolate < tier) { -+ int hist = lru_hist_from_seq(gen); -+ -+ page_inc_gen(page, lruvec, false); -+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1], -+ lrugen->protected[hist][type][tier - 1] + thp_nr_pages(page)); -+ inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + type); -+ return true; -+ } -+ -+ /* mark this page for reclaim if it's pending writeback */ -+ if (PageWriteback(page) || (type && PageDirty(page))) { -+ page_inc_gen(page, lruvec, true); -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool isolate_page(struct page *page, struct lruvec *lruvec, struct scan_control *sc) -+{ -+ bool success; -+ -+ if (!sc->may_unmap && page_mapped(page)) -+ return false; -+ -+ if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) && -+ (PageDirty(page) || (PageAnon(page) && !PageSwapCache(page)))) -+ return false; -+ -+ if (!get_page_unless_zero(page)) -+ return false; -+ -+ if (!TestClearPageLRU(page)) { -+ put_page(page); -+ return false; -+ } -+ -+ success = lru_gen_del_page(page, lruvec, true); -+ VM_BUG_ON_PAGE(!success, page); -+ -+ return true; -+} -+ -+static int scan_pages(struct lruvec *lruvec, struct scan_control *sc, long *nr_to_scan, -+ int type, int tier, struct list_head *list) -+{ -+ bool success; -+ int gen, zone; -+ enum vm_event_item item; -+ int sorted = 0; -+ int scanned = 0; -+ int isolated = 0; -+ int remaining = MAX_BATCH_SIZE; -+ struct lrugen *lrugen = &lruvec->evictable; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ VM_BUG_ON(!list_empty(list)); -+ -+ if (get_nr_gens(lruvec, type) == MIN_NR_GENS) -+ return -ENOENT; -+ -+ gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ for (zone = sc->reclaim_idx; zone >= 0; zone--) { -+ LIST_HEAD(moved); -+ int skipped = 0; -+ struct list_head *head = &lrugen->lists[gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ struct page *page = lru_to_page(head); -+ int delta = thp_nr_pages(page); -+ -+ VM_BUG_ON_PAGE(PageTail(page), page); -+ VM_BUG_ON_PAGE(PageUnevictable(page), page); -+ VM_BUG_ON_PAGE(PageActive(page), page); -+ VM_BUG_ON_PAGE(page_is_file_lru(page) != type, page); -+ VM_BUG_ON_PAGE(page_zonenum(page) != zone, page); -+ -+ prefetchw_prev_lru_page(page, head, flags); -+ -+ scanned += delta; -+ -+ if (sort_page(page, lruvec, tier)) -+ sorted += delta; -+ else if (isolate_page(page, lruvec, sc)) { -+ list_add(&page->lru, list); -+ isolated += delta; -+ } else { -+ list_move(&page->lru, &moved); -+ skipped += delta; -+ } -+ -+ if (!--remaining) -+ break; -+ -+ if (max(isolated, skipped) >= SWAP_CLUSTER_MAX) -+ break; -+ } -+ -+ list_splice(&moved, head); -+ __count_zid_vm_events(PGSCAN_SKIP, zone, skipped); -+ -+ if (!remaining || isolated >= SWAP_CLUSTER_MAX) -+ break; -+ } -+ -+ success = try_to_inc_min_seq(lruvec, type); -+ -+ *nr_to_scan -= scanned; -+ -+ item = current_is_kswapd() ? PGSCAN_KSWAPD : PGSCAN_DIRECT; -+ if (!cgroup_reclaim(sc)) { -+ __count_vm_events(item, isolated); -+ __count_vm_events(PGREFILL, sorted); -+ } -+ __count_memcg_events(memcg, item, isolated); -+ __count_memcg_events(memcg, PGREFILL, sorted); -+ __count_vm_events(PGSCAN_ANON + type, isolated); -+ -+ if (isolated) -+ return isolated; -+ /* -+ * We may have trouble finding eligible pages due to reclaim_idx, -+ * may_unmap and may_writepage. The following check makes sure we won't -+ * be stuck if we aren't making enough progress. -+ */ -+ return !remaining || success || *nr_to_scan <= 0 ? 0 : -ENOENT; -+} -+ -+static int get_tier_to_isolate(struct lruvec *lruvec, int type) -+{ -+ int tier; -+ struct controller_pos sp, pv; -+ -+ /* -+ * Ideally we don't want to evict upper tiers that have higher refault -+ * rates. However, we need to leave a margin for the fluctuations in -+ * refault rates. So we use a larger gain factor to make sure upper -+ * tiers are indeed more active. We choose 2 because the lowest upper -+ * tier would have twice of the refault rate of the base tier, according -+ * to their numbers of accesses. -+ */ -+ read_controller_pos(&sp, lruvec, type, 0, 1); -+ for (tier = 1; tier < MAX_NR_TIERS; tier++) { -+ read_controller_pos(&pv, lruvec, type, tier, 2); -+ if (!positive_ctrl_err(&sp, &pv)) -+ break; -+ } -+ -+ return tier - 1; -+} -+ -+static int get_type_to_scan(struct lruvec *lruvec, int swappiness, int *tier_to_isolate) -+{ -+ int type, tier; -+ struct controller_pos sp, pv; -+ int gain[ANON_AND_FILE] = { swappiness, 200 - swappiness }; -+ -+ /* -+ * Compare the refault rates between the base tiers of anon and file to -+ * determine which type to evict. Also need to compare the refault rates -+ * of the upper tiers of the selected type with that of the base tier of -+ * the other type to determine which tier of the selected type to evict. -+ */ -+ read_controller_pos(&sp, lruvec, 0, 0, gain[0]); -+ read_controller_pos(&pv, lruvec, 1, 0, gain[1]); -+ type = positive_ctrl_err(&sp, &pv); -+ -+ read_controller_pos(&sp, lruvec, !type, 0, gain[!type]); -+ for (tier = 1; tier < MAX_NR_TIERS; tier++) { -+ read_controller_pos(&pv, lruvec, type, tier, gain[type]); -+ if (!positive_ctrl_err(&sp, &pv)) -+ break; -+ } -+ -+ *tier_to_isolate = tier - 1; -+ -+ return type; -+} -+ -+static int isolate_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -+ long *nr_to_scan, int *type_to_scan, struct list_head *list) -+{ -+ int i; -+ int type; -+ int isolated; -+ int tier = -1; -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ VM_BUG_ON(!seq_is_valid(lruvec)); -+ -+ if (get_hi_wmark(max_seq, min_seq, swappiness) == MIN_NR_GENS) -+ return 0; -+ /* -+ * Try to select a type based on generations and swappiness, and if that -+ * fails, fall back to get_type_to_scan(). When anon and file are both -+ * available from the same generation, swappiness 200 is interpreted as -+ * anon first and swappiness 1 is interpreted as file first. -+ */ -+ if (!swappiness) -+ type = 1; -+ else if (min_seq[0] > min_seq[1]) -+ type = 1; -+ else if (min_seq[0] < min_seq[1]) -+ type = 0; -+ else if (swappiness == 1) -+ type = 1; -+ else if (swappiness == 200) -+ type = 0; -+ else -+ type = get_type_to_scan(lruvec, swappiness, &tier); -+ -+ if (tier == -1) -+ tier = get_tier_to_isolate(lruvec, type); -+ -+ for (i = !swappiness; i < ANON_AND_FILE; i++) { -+ isolated = scan_pages(lruvec, sc, nr_to_scan, type, tier, list); -+ if (isolated >= 0) -+ break; -+ -+ type = !type; -+ tier = get_tier_to_isolate(lruvec, type); -+ } -+ -+ if (isolated < 0) -+ isolated = *nr_to_scan = 0; -+ -+ *type_to_scan = type; -+ -+ return isolated; -+} -+ -+/* Main function used by the foreground, the background and the user-triggered eviction. */ -+static bool evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -+ long *nr_to_scan) -+{ -+ int type; -+ int isolated; -+ int reclaimed; -+ LIST_HEAD(list); -+ struct page *page; -+ enum vm_event_item item; -+ struct reclaim_stat stat; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ isolated = isolate_pages(lruvec, sc, swappiness, nr_to_scan, &type, &list); -+ VM_BUG_ON(list_empty(&list) == !!isolated); -+ -+ if (isolated) -+ __mod_node_page_state(pgdat, NR_ISOLATED_ANON + type, isolated); -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ if (!isolated) -+ goto done; -+ -+ reclaimed = shrink_page_list(&list, pgdat, sc, &stat, false); -+ /* -+ * We need to prevent rejected pages from being added back to the same -+ * lists they were isolated from. Otherwise we may risk looping on them -+ * forever. -+ */ -+ list_for_each_entry(page, &list, lru) { -+ if (!page_evictable(page)) -+ continue; -+ -+ if (!PageReclaim(page) || !(PageDirty(page) || PageWriteback(page))) -+ SetPageActive(page); -+ -+ ClearPageReferenced(page); -+ ClearPageWorkingset(page); -+ } -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ move_pages_to_lru(lruvec, &list); -+ -+ __mod_node_page_state(pgdat, NR_ISOLATED_ANON + type, -isolated); -+ -+ item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT; -+ if (!cgroup_reclaim(sc)) -+ __count_vm_events(item, reclaimed); -+ __count_memcg_events(memcg, item, reclaimed); -+ __count_vm_events(PGSTEAL_ANON + type, reclaimed); -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ mem_cgroup_uncharge_list(&list); -+ free_unref_page_list(&list); -+ -+ sc->nr_reclaimed += reclaimed; -+done: -+ return *nr_to_scan > 0 && sc->nr_reclaimed < sc->nr_to_reclaim; -+} -+ -+static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, int swappiness) -+{ -+ int gen, type, zone; -+ int nr_gens; -+ long nr_to_scan = 0; -+ struct lrugen *lrugen = &lruvec->evictable; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ for (type = !swappiness; type < ANON_AND_FILE; type++) { -+ unsigned long seq; -+ -+ for (seq = min_seq[type]; seq <= max_seq; seq++) { -+ gen = lru_gen_from_seq(seq); -+ -+ for (zone = 0; zone <= sc->reclaim_idx; zone++) -+ nr_to_scan += READ_ONCE(lrugen->sizes[gen][type][zone]); -+ } -+ } -+ -+ if (nr_to_scan <= 0) -+ return 0; -+ -+ nr_gens = get_hi_wmark(max_seq, min_seq, swappiness); -+ -+ if (current_is_kswapd()) { -+ gen = lru_gen_from_seq(max_seq - nr_gens + 1); -+ if (time_is_before_eq_jiffies(READ_ONCE(lrugen->timestamps[gen]) + -+ READ_ONCE(lru_gen_min_ttl))) -+ sc->file_is_tiny = 0; -+ -+ /* leave the work to lru_gen_age_node() */ -+ if (nr_gens == MIN_NR_GENS) -+ return 0; -+ -+ if (nr_to_scan >= sc->nr_to_reclaim) -+ sc->force_deactivate = 0; -+ } -+ -+ nr_to_scan = max(nr_to_scan >> sc->priority, (long)!mem_cgroup_online(memcg)); -+ if (!nr_to_scan || nr_gens > MIN_NR_GENS) -+ return nr_to_scan; -+ -+ /* move onto other memcgs if we haven't tried them all yet */ -+ if (!mem_cgroup_disabled() && !sc->force_deactivate) { -+ sc->skipped_deactivate = 1; -+ return 0; -+ } -+ -+ return try_to_inc_max_seq(lruvec, max_seq, sc, swappiness) ? nr_to_scan : 0; -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ struct blk_plug plug; -+ long scanned = 0; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ lru_add_drain(); -+ -+ blk_start_plug(&plug); -+ -+ while (true) { -+ long nr_to_scan; -+ int swappiness = sc->may_swap ? get_swappiness(memcg) : 0; -+ -+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness) - scanned; -+ if (nr_to_scan <= 0) -+ break; -+ -+ scanned += nr_to_scan; -+ -+ if (!evict_pages(lruvec, sc, swappiness, &nr_to_scan)) -+ break; -+ -+ scanned -= nr_to_scan; -+ -+ if (mem_cgroup_below_min(memcg) || -+ (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) -+ break; -+ -+ cond_resched(); -+ } -+ -+ blk_finish_plug(&plug); -+} -+ -+/****************************************************************************** -+ * state change -+ ******************************************************************************/ -+ -+#ifdef CONFIG_LRU_GEN_ENABLED -+DEFINE_STATIC_KEY_TRUE(lru_gen_static_key); -+#else -+DEFINE_STATIC_KEY_FALSE(lru_gen_static_key); -+#endif -+ -+static DEFINE_MUTEX(lru_gen_state_mutex); -+static int lru_gen_nr_swapfiles; -+ -+static bool __maybe_unused state_is_valid(struct lruvec *lruvec) -+{ -+ int gen, type, zone; -+ enum lru_list lru; -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ for_each_evictable_lru(lru) { -+ type = is_file_lru(lru); -+ -+ if (lrugen->enabled[type] && !list_empty(&lruvec->lists[lru])) -+ return false; -+ } -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ if (!lrugen->enabled[type] && !list_empty(&lrugen->lists[gen][type][zone])) -+ return false; -+ -+ VM_WARN_ON_ONCE(!lrugen->enabled[type] && lrugen->sizes[gen][type][zone]); -+ } -+ -+ return true; -+} -+ -+static bool fill_lists(struct lruvec *lruvec) -+{ -+ enum lru_list lru; -+ int remaining = MAX_BATCH_SIZE; -+ -+ for_each_evictable_lru(lru) { -+ int type = is_file_lru(lru); -+ bool active = is_active_lru(lru); -+ struct list_head *head = &lruvec->lists[lru]; -+ -+ if (!lruvec->evictable.enabled[type]) -+ continue; -+ -+ while (!list_empty(head)) { -+ bool success; -+ struct page *page = lru_to_page(head); -+ -+ VM_BUG_ON_PAGE(PageTail(page), page); -+ VM_BUG_ON_PAGE(PageUnevictable(page), page); -+ VM_BUG_ON_PAGE(PageActive(page) != active, page); -+ VM_BUG_ON_PAGE(page_is_file_lru(page) != type, page); -+ VM_BUG_ON_PAGE(page_lru_gen(page) >= 0, page); -+ -+ prefetchw_prev_lru_page(page, head, flags); -+ -+ del_page_from_lru_list(page, lruvec); -+ success = lru_gen_add_page(page, lruvec, false); -+ VM_BUG_ON(!success); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static bool drain_lists(struct lruvec *lruvec) -+{ -+ int gen, type, zone; -+ int remaining = MAX_BATCH_SIZE; -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ struct list_head *head = &lruvec->evictable.lists[gen][type][zone]; -+ -+ if (lruvec->evictable.enabled[type]) -+ continue; -+ -+ while (!list_empty(head)) { -+ bool success; -+ struct page *page = lru_to_page(head); -+ -+ VM_BUG_ON_PAGE(PageTail(page), page); -+ VM_BUG_ON_PAGE(PageUnevictable(page), page); -+ VM_BUG_ON_PAGE(PageActive(page), page); -+ VM_BUG_ON_PAGE(page_is_file_lru(page) != type, page); -+ VM_BUG_ON_PAGE(page_zonenum(page) != zone, page); -+ -+ prefetchw_prev_lru_page(page, head, flags); -+ -+ success = lru_gen_del_page(page, lruvec, false); -+ VM_BUG_ON(!success); -+ add_page_to_lru_list(page, lruvec); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+/* -+ * For file page tracking, we enable/disable it according to the main switch. -+ * For anon page tracking, we only enabled it when the main switch is on and -+ * there is at least one swapfile; we disable it when there are no swapfiles -+ * regardless of the value of the main switch. Otherwise, we will eventually -+ * reach the max size of the sliding window and have to call inc_min_seq(). -+ */ -+void lru_gen_set_state(bool enable, bool main, bool swap) -+{ -+ struct mem_cgroup *memcg; -+ -+ mem_hotplug_begin(); -+ mutex_lock(&lru_gen_state_mutex); -+ cgroup_lock(); -+ -+ if (swap) { -+ if (enable) -+ swap = !lru_gen_nr_swapfiles++; -+ else -+ swap = !--lru_gen_nr_swapfiles; -+ } -+ -+ if (main && enable != lru_gen_enabled()) { -+ if (enable) -+ static_branch_enable(&lru_gen_static_key); -+ else -+ static_branch_disable(&lru_gen_static_key); -+ } else if (!swap || !lru_gen_enabled()) -+ goto unlock; -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ int nid; -+ -+ for_each_node_state(nid, N_MEMORY) { -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(nid)); -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ VM_BUG_ON(!seq_is_valid(lruvec)); -+ VM_BUG_ON(!state_is_valid(lruvec)); -+ -+ lrugen->enabled[0] = lru_gen_enabled() && lru_gen_nr_swapfiles; -+ lrugen->enabled[1] = lru_gen_enabled(); -+ -+ while (!(enable ? fill_lists(lruvec) : drain_lists(lruvec))) { -+ spin_unlock_irq(&lruvec->lru_lock); -+ cond_resched(); -+ spin_lock_irq(&lruvec->lru_lock); -+ } -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ } -+ -+ cond_resched(); -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+unlock: -+ cgroup_unlock(); -+ mutex_unlock(&lru_gen_state_mutex); -+ mem_hotplug_done(); -+} -+ -+static int __meminit __maybe_unused mem_notifier(struct notifier_block *self, -+ unsigned long action, void *arg) -+{ -+ struct mem_cgroup *memcg; -+ struct pglist_data *pgdat; -+ struct memory_notify *mn = arg; -+ int nid = mn->status_change_nid; -+ -+ if (nid == NUMA_NO_NODE) -+ return NOTIFY_DONE; -+ -+ pgdat = NODE_DATA(nid); -+ -+ if (action == MEM_CANCEL_ONLINE || action == MEM_OFFLINE) { -+ free_mm_walk_args(pgdat->mm_walk_args); -+ pgdat->mm_walk_args = NULL; -+ return NOTIFY_DONE; -+ } -+ -+ if (action != MEM_GOING_ONLINE) -+ return NOTIFY_DONE; -+ -+ if (!WARN_ON_ONCE(pgdat->mm_walk_args)) -+ pgdat->mm_walk_args = alloc_mm_walk_args(NUMA_NO_NODE); -+ -+ mutex_lock(&lru_gen_state_mutex); -+ cgroup_lock(); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ VM_BUG_ON(!seq_is_valid(lruvec)); -+ VM_BUG_ON(!state_is_valid(lruvec)); -+ -+ lrugen->enabled[0] = lru_gen_enabled() && lru_gen_nr_swapfiles; -+ lrugen->enabled[1] = lru_gen_enabled(); -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+ -+ cgroup_unlock(); -+ mutex_unlock(&lru_gen_state_mutex); -+ -+ return NOTIFY_DONE; -+} -+ -+/****************************************************************************** -+ * sysfs interface -+ ******************************************************************************/ -+ -+static ssize_t show_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%u\n", jiffies_to_msecs(READ_ONCE(lru_gen_min_ttl))); -+} -+ -+static ssize_t store_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t len) -+{ -+ unsigned int msecs; -+ -+ if (kstrtouint(buf, 10, &msecs)) -+ return -EINVAL; -+ -+ WRITE_ONCE(lru_gen_min_ttl, msecs_to_jiffies(msecs)); -+ -+ return len; -+} -+ -+static struct kobj_attribute lru_gen_min_ttl_attr = __ATTR( -+ min_ttl_ms, 0644, show_min_ttl, store_min_ttl -+); -+ -+static ssize_t show_enable(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%d\n", lru_gen_enabled()); -+} -+ -+static ssize_t store_enable(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t len) -+{ -+ int enable; -+ -+ if (kstrtoint(buf, 10, &enable)) -+ return -EINVAL; -+ -+ lru_gen_set_state(enable, true, false); -+ -+ return len; -+} -+ -+static struct kobj_attribute lru_gen_enabled_attr = __ATTR( -+ enabled, 0644, show_enable, store_enable -+); -+ -+static struct attribute *lru_gen_attrs[] = { -+ &lru_gen_min_ttl_attr.attr, -+ &lru_gen_enabled_attr.attr, -+ NULL -+}; -+ -+static struct attribute_group lru_gen_attr_group = { -+ .name = "lru_gen", -+ .attrs = lru_gen_attrs, -+}; -+ -+/****************************************************************************** -+ * debugfs interface -+ ******************************************************************************/ -+ -+static void *lru_gen_seq_start(struct seq_file *m, loff_t *pos) -+{ -+ struct mem_cgroup *memcg; -+ loff_t nr_to_skip = *pos; -+ -+ m->private = kvmalloc(PATH_MAX, GFP_KERNEL); -+ if (!m->private) -+ return ERR_PTR(-ENOMEM); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ int nid; -+ -+ for_each_node_state(nid, N_MEMORY) { -+ if (!nr_to_skip--) -+ return mem_cgroup_lruvec(memcg, NODE_DATA(nid)); -+ } -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+ -+ return NULL; -+} -+ -+static void lru_gen_seq_stop(struct seq_file *m, void *v) -+{ -+ if (!IS_ERR_OR_NULL(v)) -+ mem_cgroup_iter_break(NULL, lruvec_memcg(v)); -+ -+ kvfree(m->private); -+ m->private = NULL; -+} -+ -+static void *lru_gen_seq_next(struct seq_file *m, void *v, loff_t *pos) -+{ -+ int nid = lruvec_pgdat(v)->node_id; -+ struct mem_cgroup *memcg = lruvec_memcg(v); -+ -+ ++*pos; -+ -+ nid = next_memory_node(nid); -+ if (nid == MAX_NUMNODES) { -+ memcg = mem_cgroup_iter(NULL, memcg, NULL); -+ if (!memcg) -+ return NULL; -+ -+ nid = first_memory_node; -+ } -+ -+ return mem_cgroup_lruvec(memcg, NODE_DATA(nid)); -+} -+ -+static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec, -+ unsigned long max_seq, unsigned long *min_seq, -+ unsigned long seq) -+{ -+ int i; -+ int type, tier; -+ int hist = lru_hist_from_seq(seq); -+ struct lrugen *lrugen = &lruvec->evictable; -+ int nid = lruvec_pgdat(lruvec)->node_id; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ -+ for (tier = 0; tier < MAX_NR_TIERS; tier++) { -+ seq_printf(m, " %10d", tier); -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ unsigned long n[3] = {}; -+ -+ if (seq == max_seq) { -+ n[0] = READ_ONCE(lrugen->avg_refaulted[type][tier]); -+ n[1] = READ_ONCE(lrugen->avg_total[type][tier]); -+ -+ seq_printf(m, " %10luR %10luT %10lu ", n[0], n[1], n[2]); -+ } else if (seq == min_seq[type] || NR_STAT_GENS > 1) { -+ n[0] = atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ n[1] = atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ n[2] = READ_ONCE(lrugen->protected[hist][type][tier - 1]); -+ -+ seq_printf(m, " %10lur %10lue %10lup", n[0], n[1], n[2]); -+ } else -+ seq_puts(m, " 0 0 0 "); -+ } -+ seq_putc(m, '\n'); -+ } -+ -+ seq_puts(m, " "); -+ for (i = 0; i < NR_MM_STATS; i++) { -+ if (i == 6) -+ seq_puts(m, "\n "); -+ -+ if (seq == max_seq && NR_STAT_GENS == 1) -+ seq_printf(m, " %10lu%c", READ_ONCE(mm_list->nodes[nid].stats[hist][i]), -+ toupper(MM_STAT_CODES[i])); -+ else if (seq != max_seq && NR_STAT_GENS > 1) -+ seq_printf(m, " %10lu%c", READ_ONCE(mm_list->nodes[nid].stats[hist][i]), -+ MM_STAT_CODES[i]); -+ else -+ seq_puts(m, " 0 "); -+ } -+ seq_putc(m, '\n'); -+} -+ -+static int lru_gen_seq_show(struct seq_file *m, void *v) -+{ -+ unsigned long seq; -+ bool full = !debugfs_real_fops(m->file)->write; -+ struct lruvec *lruvec = v; -+ struct lrugen *lrugen = &lruvec->evictable; -+ int nid = lruvec_pgdat(lruvec)->node_id; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (nid == first_memory_node) { -+ const char *path = memcg ? m->private : ""; -+ -+#ifdef CONFIG_MEMCG -+ if (memcg) -+ cgroup_path(memcg->css.cgroup, m->private, PATH_MAX); -+#endif -+ seq_printf(m, "memcg %5hu %s\n", mem_cgroup_id(memcg), path); -+ } -+ -+ seq_printf(m, " node %5d\n", nid); -+ -+ if (!full) -+ seq = min(min_seq[0], min_seq[1]); -+ else if (max_seq >= MAX_NR_GENS) -+ seq = max_seq - MAX_NR_GENS + 1; -+ else -+ seq = 0; -+ -+ for (; seq <= max_seq; seq++) { -+ int gen, type, zone; -+ unsigned int msecs; -+ -+ gen = lru_gen_from_seq(seq); -+ msecs = jiffies_to_msecs(jiffies - READ_ONCE(lrugen->timestamps[gen])); -+ -+ seq_printf(m, " %10lu %10u", seq, msecs); -+ -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ long size = 0; -+ -+ if (seq < min_seq[type]) { -+ seq_puts(m, " -0 "); -+ continue; -+ } -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ size += READ_ONCE(lrugen->sizes[gen][type][zone]); -+ -+ seq_printf(m, " %10lu ", max(size, 0L)); -+ } -+ -+ seq_putc(m, '\n'); -+ -+ if (full) -+ lru_gen_seq_show_full(m, lruvec, max_seq, min_seq, seq); -+ } -+ -+ return 0; -+} -+ -+static const struct seq_operations lru_gen_seq_ops = { -+ .start = lru_gen_seq_start, -+ .stop = lru_gen_seq_stop, -+ .next = lru_gen_seq_next, -+ .show = lru_gen_seq_show, -+}; -+ -+static int run_aging(struct lruvec *lruvec, unsigned long seq, int swappiness) -+{ -+ struct scan_control sc = {}; -+ DEFINE_MAX_SEQ(lruvec); -+ -+ if (seq == max_seq) -+ try_to_inc_max_seq(lruvec, max_seq, &sc, swappiness); -+ -+ return seq > max_seq ? -EINVAL : 0; -+} -+ -+static int run_eviction(struct lruvec *lruvec, unsigned long seq, int swappiness, -+ unsigned long nr_to_reclaim) -+{ -+ unsigned int flags; -+ struct blk_plug plug; -+ int err = -EINTR; -+ long nr_to_scan = LONG_MAX; -+ struct scan_control sc = { -+ .nr_to_reclaim = nr_to_reclaim, -+ .may_writepage = 1, -+ .may_unmap = 1, -+ .may_swap = 1, -+ .reclaim_idx = MAX_NR_ZONES - 1, -+ .gfp_mask = GFP_KERNEL, -+ }; -+ DEFINE_MAX_SEQ(lruvec); -+ -+ if (seq >= max_seq - 1) -+ return -EINVAL; -+ -+ flags = memalloc_noreclaim_save(); -+ -+ blk_start_plug(&plug); -+ -+ while (!signal_pending(current)) { -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (seq < min(min_seq[!swappiness], min_seq[swappiness < 200]) || -+ !evict_pages(lruvec, &sc, swappiness, &nr_to_scan)) { -+ err = 0; -+ break; -+ } -+ -+ cond_resched(); -+ } -+ -+ blk_finish_plug(&plug); -+ -+ memalloc_noreclaim_restore(flags); -+ -+ return err; -+} -+ -+static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq, -+ int swappiness, unsigned long nr_to_reclaim) -+{ -+ struct lruvec *lruvec; -+ int err = -EINVAL; -+ struct mem_cgroup *memcg = NULL; -+ -+ if (!mem_cgroup_disabled()) { -+ rcu_read_lock(); -+ memcg = mem_cgroup_from_id(memcg_id); -+#ifdef CONFIG_MEMCG -+ if (memcg && !css_tryget(&memcg->css)) -+ memcg = NULL; -+#endif -+ rcu_read_unlock(); -+ -+ if (!memcg) -+ goto done; -+ } -+ if (memcg_id != mem_cgroup_id(memcg)) -+ goto done; -+ -+ if (nid < 0 || nid >= MAX_NUMNODES || !node_state(nid, N_MEMORY)) -+ goto done; -+ -+ lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(nid)); -+ -+ if (swappiness == -1) -+ swappiness = get_swappiness(memcg); -+ else if (swappiness > 200U) -+ goto done; -+ -+ switch (cmd) { -+ case '+': -+ err = run_aging(lruvec, seq, swappiness); -+ break; -+ case '-': -+ err = run_eviction(lruvec, seq, swappiness, nr_to_reclaim); -+ break; -+ } -+done: -+ mem_cgroup_put(memcg); -+ -+ return err; -+} -+ -+static ssize_t lru_gen_seq_write(struct file *file, const char __user *src, -+ size_t len, loff_t *pos) -+{ -+ void *buf; -+ char *cur, *next; -+ int err = 0; -+ -+ buf = kvmalloc(len + 1, GFP_USER); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (copy_from_user(buf, src, len)) { -+ kvfree(buf); -+ return -EFAULT; -+ } -+ -+ next = buf; -+ next[len] = '\0'; -+ -+ while ((cur = strsep(&next, ",;\n"))) { -+ int n; -+ int end; -+ char cmd; -+ unsigned int memcg_id; -+ unsigned int nid; -+ unsigned long seq; -+ unsigned int swappiness = -1; -+ unsigned long nr_to_reclaim = -1; -+ -+ cur = skip_spaces(cur); -+ if (!*cur) -+ continue; -+ -+ n = sscanf(cur, "%c %u %u %lu %n %u %n %lu %n", &cmd, &memcg_id, &nid, -+ &seq, &end, &swappiness, &end, &nr_to_reclaim, &end); -+ if (n < 4 || cur[end]) { -+ err = -EINVAL; -+ break; -+ } -+ -+ err = run_cmd(cmd, memcg_id, nid, seq, swappiness, nr_to_reclaim); -+ if (err) -+ break; -+ } -+ -+ kvfree(buf); -+ -+ return err ? : len; -+} -+ -+static int lru_gen_seq_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &lru_gen_seq_ops); -+} -+ -+static const struct file_operations lru_gen_rw_fops = { -+ .open = lru_gen_seq_open, -+ .read = seq_read, -+ .write = lru_gen_seq_write, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+static const struct file_operations lru_gen_ro_fops = { -+ .open = lru_gen_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+/****************************************************************************** -+ * initialization -+ ******************************************************************************/ -+ -+void lru_gen_init_lrugen(struct lruvec *lruvec) -+{ -+ int i; -+ int gen, type, zone; -+ struct lrugen *lrugen = &lruvec->evictable; -+ -+ lrugen->max_seq = MIN_NR_GENS + 1; -+ lrugen->enabled[0] = lru_gen_enabled() && lru_gen_nr_swapfiles; -+ lrugen->enabled[1] = lru_gen_enabled(); -+ -+ for (i = 0; i <= MIN_NR_GENS + 1; i++) -+ lrugen->timestamps[i] = jiffies; -+ -+ for_each_gen_type_zone(gen, type, zone) -+ INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -+} -+ -+static int __init init_lru_gen(void) -+{ -+ BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS); -+ BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS); -+ BUILD_BUG_ON(sizeof(MM_STAT_CODES) != NR_MM_STATS + 1); -+ -+ VM_BUG_ON(PMD_SIZE / PAGE_SIZE != PTRS_PER_PTE); -+ VM_BUG_ON(PUD_SIZE / PMD_SIZE != PTRS_PER_PMD); -+ VM_BUG_ON(P4D_SIZE / PUD_SIZE != PTRS_PER_PUD); -+ -+ if (mem_cgroup_disabled()) { -+ global_mm_list = alloc_mm_list(); -+ if (!global_mm_list) -+ return -ENOMEM; -+ } -+ -+ if (hotplug_memory_notifier(mem_notifier, 0)) -+ pr_err("lru_gen: failed to subscribe hotplug notifications\n"); -+ -+ if (sysfs_create_group(mm_kobj, &lru_gen_attr_group)) -+ pr_err("lru_gen: failed to create sysfs group\n"); -+ -+ debugfs_create_file("lru_gen", 0644, NULL, NULL, &lru_gen_rw_fops); -+ debugfs_create_file("lru_gen_full", 0444, NULL, NULL, &lru_gen_ro_fops); -+ -+ return 0; -+}; -+/* -+ * We want to run as early as possible because debug code may call mm_alloc() -+ * and mmput(). Our only dependency mm_kobj is initialized one stage earlier. -+ */ -+arch_initcall(init_lru_gen); -+ -+#else /* CONFIG_LRU_GEN */ -+ -+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - unsigned long nr[NR_LRU_LISTS]; -@@ -2656,6 +5226,11 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - struct blk_plug plug; - bool scan_adjusted; - -+ if (lru_gen_enabled()) { -+ lru_gen_shrink_lruvec(lruvec, sc); -+ return; -+ } -+ - get_scan_count(lruvec, sc, nr); - - /* Record the original scan target for proportional adjustments later */ -@@ -2893,7 +5468,6 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) - unsigned long nr_reclaimed, nr_scanned; - struct lruvec *target_lruvec; - bool reclaimable = false; -- unsigned long file; - - target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); - -@@ -2903,93 +5477,7 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) - nr_reclaimed = sc->nr_reclaimed; - nr_scanned = sc->nr_scanned; - -- /* -- * Determine the scan balance between anon and file LRUs. -- */ -- spin_lock_irq(&target_lruvec->lru_lock); -- sc->anon_cost = target_lruvec->anon_cost; -- sc->file_cost = target_lruvec->file_cost; -- spin_unlock_irq(&target_lruvec->lru_lock); -- -- /* -- * Target desirable inactive:active list ratios for the anon -- * and file LRU lists. -- */ -- if (!sc->force_deactivate) { -- unsigned long refaults; -- -- refaults = lruvec_page_state(target_lruvec, -- WORKINGSET_ACTIVATE_ANON); -- if (refaults != target_lruvec->refaults[0] || -- inactive_is_low(target_lruvec, LRU_INACTIVE_ANON)) -- sc->may_deactivate |= DEACTIVATE_ANON; -- else -- sc->may_deactivate &= ~DEACTIVATE_ANON; -- -- /* -- * When refaults are being observed, it means a new -- * workingset is being established. Deactivate to get -- * rid of any stale active pages quickly. -- */ -- refaults = lruvec_page_state(target_lruvec, -- WORKINGSET_ACTIVATE_FILE); -- if (refaults != target_lruvec->refaults[1] || -- inactive_is_low(target_lruvec, LRU_INACTIVE_FILE)) -- sc->may_deactivate |= DEACTIVATE_FILE; -- else -- sc->may_deactivate &= ~DEACTIVATE_FILE; -- } else -- sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE; -- -- /* -- * If we have plenty of inactive file pages that aren't -- * thrashing, try to reclaim those first before touching -- * anonymous pages. -- */ -- file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE); -- if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE)) -- sc->cache_trim_mode = 1; -- else -- sc->cache_trim_mode = 0; -- -- /* -- * Prevent the reclaimer from falling into the cache trap: as -- * cache pages start out inactive, every cache fault will tip -- * the scan balance towards the file LRU. And as the file LRU -- * shrinks, so does the window for rotation from references. -- * This means we have a runaway feedback loop where a tiny -- * thrashing file LRU becomes infinitely more attractive than -- * anon pages. Try to detect this based on file LRU size. -- */ -- if (!cgroup_reclaim(sc)) { -- unsigned long total_high_wmark = 0; -- unsigned long free, anon; -- int z; -- -- free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES); -- file = node_page_state(pgdat, NR_ACTIVE_FILE) + -- node_page_state(pgdat, NR_INACTIVE_FILE); -- -- for (z = 0; z < MAX_NR_ZONES; z++) { -- struct zone *zone = &pgdat->node_zones[z]; -- if (!managed_zone(zone)) -- continue; -- -- total_high_wmark += high_wmark_pages(zone); -- } -- -- /* -- * Consider anon: if that's low too, this isn't a -- * runaway file reclaim problem, but rather just -- * extreme pressure. Reclaim as per usual then. -- */ -- anon = node_page_state(pgdat, NR_INACTIVE_ANON); -- -- sc->file_is_tiny = -- file + free <= total_high_wmark && -- !(sc->may_deactivate & DEACTIVATE_ANON) && -- anon >> sc->priority; -- } -+ prepare_scan_count(pgdat, sc); - - shrink_node_memcgs(pgdat, sc); - -@@ -3209,6 +5697,9 @@ static void snapshot_refaults(struct mem_cgroup *target_memcg, pg_data_t *pgdat) - struct lruvec *target_lruvec; - unsigned long refaults; - -+ if (lru_gen_enabled()) -+ return; -+ - target_lruvec = mem_cgroup_lruvec(target_memcg, pgdat); - refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_ANON); - target_lruvec->refaults[0] = refaults; -@@ -3583,6 +6074,11 @@ static void age_active_anon(struct pglist_data *pgdat, - struct mem_cgroup *memcg; - struct lruvec *lruvec; - -+ if (lru_gen_enabled()) { -+ lru_gen_age_node(pgdat, sc); -+ return; -+ } -+ - if (!total_swap_pages) - return; - -diff --git a/mm/workingset.c b/mm/workingset.c -index 5ba3e42446fa..75dbfba773a6 100644 ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -187,7 +187,6 @@ static unsigned int bucket_order __read_mostly; - static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction, - bool workingset) - { -- eviction >>= bucket_order; - eviction &= EVICTION_MASK; - eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid; - eviction = (eviction << NODES_SHIFT) | pgdat->node_id; -@@ -212,10 +211,116 @@ static void unpack_shadow(void *shadow, int *memcgidp, pg_data_t **pgdat, - - *memcgidp = memcgid; - *pgdat = NODE_DATA(nid); -- *evictionp = entry << bucket_order; -+ *evictionp = entry; - *workingsetp = workingset; - } - -+#ifdef CONFIG_LRU_GEN -+ -+static int page_get_usage(struct page *page) -+{ -+ unsigned long flags = READ_ONCE(page->flags); -+ -+ BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_USAGE_WIDTH > BITS_PER_LONG - EVICTION_SHIFT); -+ -+ /* see the comment on MAX_NR_TIERS */ -+ return flags & BIT(PG_workingset) ? -+ (flags & LRU_USAGE_MASK) >> LRU_USAGE_PGOFF : 0; -+} -+ -+/* Return a token to be stored in the shadow entry of a page being evicted. */ -+static void *lru_gen_eviction(struct page *page) -+{ -+ int hist, tier; -+ unsigned long token; -+ unsigned long min_seq; -+ struct lruvec *lruvec; -+ struct lrugen *lrugen; -+ int type = page_is_file_lru(page); -+ int usage = page_get_usage(page); -+ bool workingset = PageWorkingset(page); -+ struct mem_cgroup *memcg = page_memcg(page); -+ struct pglist_data *pgdat = page_pgdat(page); -+ -+ lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ lrugen = &lruvec->evictable; -+ min_seq = READ_ONCE(lrugen->min_seq[type]); -+ token = (min_seq << LRU_USAGE_WIDTH) | usage; -+ -+ hist = lru_hist_from_seq(min_seq); -+ tier = lru_tier_from_usage(usage + workingset); -+ atomic_long_add(thp_nr_pages(page), &lrugen->evicted[hist][type][tier]); -+ -+ return pack_shadow(mem_cgroup_id(memcg), pgdat, token, workingset); -+} -+ -+/* Count a refaulted page based on the token stored in its shadow entry. */ -+static void lru_gen_refault(struct page *page, void *shadow) -+{ -+ int hist, tier, usage; -+ int memcg_id; -+ bool workingset; -+ unsigned long token; -+ unsigned long min_seq; -+ struct lruvec *lruvec; -+ struct lrugen *lrugen; -+ struct mem_cgroup *memcg; -+ struct pglist_data *pgdat; -+ int type = page_is_file_lru(page); -+ -+ unpack_shadow(shadow, &memcg_id, &pgdat, &token, &workingset); -+ if (page_pgdat(page) != pgdat) -+ return; -+ -+ rcu_read_lock(); -+ memcg = page_memcg_rcu(page); -+ if (mem_cgroup_id(memcg) != memcg_id) -+ goto unlock; -+ -+ usage = token & (BIT(LRU_USAGE_WIDTH) - 1); -+ if (usage && !workingset) -+ goto unlock; -+ -+ token >>= LRU_USAGE_WIDTH; -+ lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ lrugen = &lruvec->evictable; -+ min_seq = READ_ONCE(lrugen->min_seq[type]); -+ if (token != (min_seq & (EVICTION_MASK >> LRU_USAGE_WIDTH))) -+ goto unlock; -+ -+ hist = lru_hist_from_seq(min_seq); -+ tier = lru_tier_from_usage(usage + workingset); -+ atomic_long_add(thp_nr_pages(page), &lrugen->refaulted[hist][type][tier]); -+ inc_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + type); -+ -+ /* -+ * Tiers don't offer any protection to pages accessed via page tables. -+ * That's what generations do. Tiers can't fully protect pages after -+ * their usage has exceeded the max value. Conservatively count these -+ * two conditions as stalls even though they might not indicate any real -+ * memory pressure. -+ */ -+ if (task_in_nonseq_fault() || usage + workingset == BIT(LRU_USAGE_WIDTH)) { -+ SetPageWorkingset(page); -+ inc_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type); -+ } -+unlock: -+ rcu_read_unlock(); -+} -+ -+#else /* CONFIG_LRU_GEN */ -+ -+static void *lru_gen_eviction(struct page *page) -+{ -+ return NULL; -+} -+ -+static void lru_gen_refault(struct page *page, void *shadow) -+{ -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - /** - * workingset_age_nonresident - age non-resident entries as LRU ages - * @lruvec: the lruvec that was aged -@@ -264,10 +369,14 @@ void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg) - VM_BUG_ON_PAGE(page_count(page), page); - VM_BUG_ON_PAGE(!PageLocked(page), page); - -+ if (lru_gen_enabled()) -+ return lru_gen_eviction(page); -+ - lruvec = mem_cgroup_lruvec(target_memcg, pgdat); - /* XXX: target_memcg can be NULL, go through lruvec */ - memcgid = mem_cgroup_id(lruvec_memcg(lruvec)); - eviction = atomic_long_read(&lruvec->nonresident_age); -+ eviction >>= bucket_order; - workingset_age_nonresident(lruvec, thp_nr_pages(page)); - return pack_shadow(memcgid, pgdat, eviction, PageWorkingset(page)); - } -@@ -296,7 +405,13 @@ void workingset_refault(struct page *page, void *shadow) - bool workingset; - int memcgid; - -+ if (lru_gen_enabled()) { -+ lru_gen_refault(page, shadow); -+ return; -+ } -+ - unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset); -+ eviction <<= bucket_order; - - rcu_read_lock(); - /* --- -2.33.0 - diff --git a/sys-kernel_arch-sources-g14_files-0039-asus-wmi-Add-panel-overdrive-functionality.patch b/sys-kernel_arch-sources-g14_files-0039-asus-wmi-Add-panel-overdrive-functionality.patch deleted file mode 100644 index 9ee246ce3398..000000000000 --- a/sys-kernel_arch-sources-g14_files-0039-asus-wmi-Add-panel-overdrive-functionality.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 4fb0353bff3b881de7709b114d4607a0988c3420 Mon Sep 17 00:00:00 2001 -From: "Luke D. Jones" <luke@ljones.dev> -Date: Sat, 17 Jul 2021 20:13:21 +1200 -Subject: [PATCH 101/103] asus-wmi: Add panel overdrive functionality - -Some ASUS ROG laptops have the ability to drive the display panel -a higher rate to eliminate or reduce ghosting. - -Signed-off-by: Luke D. Jones <luke@ljones.dev> ---- - drivers/platform/x86/asus-wmi.c | 91 ++++++++++++++++++++++ - include/linux/platform_data/x86/asus-wmi.h | 1 + - 2 files changed, 92 insertions(+) - -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index ebaeb7bb80f5..cd881443bc2f 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -216,6 +216,9 @@ struct asus_wmi { - // The RSOC controls the maximum charging percentage. - bool battery_rsoc_available; - -+ bool panel_overdrive_available; -+ bool panel_overdrive; -+ - struct hotplug_slot hotplug_slot; - struct mutex hotplug_lock; - struct mutex wmi_lock; -@@ -1221,6 +1224,86 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus) - return result; - } - -+/* Panel Overdrive ************************************************************/ -+static int panel_od_check_present(struct asus_wmi *asus) -+{ -+ u32 result; -+ int err; -+ -+ asus->panel_overdrive_available = false; -+ -+ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_PANEL_OD, &result); -+ if (err) { -+ if (err == -ENODEV) -+ return 0; -+ return err; -+ } -+ -+ if (result & ASUS_WMI_DSTS_PRESENCE_BIT) { -+ asus->panel_overdrive_available = true; -+ asus->panel_overdrive = result & ASUS_WMI_DSTS_STATUS_BIT; -+ } -+ -+ return 0; -+} -+ -+static int panel_od_write(struct asus_wmi *asus) -+{ -+ int err; -+ u8 value; -+ u32 retval; -+ -+ value = asus->panel_overdrive; -+ -+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, value, &retval); -+ -+ if (err) { -+ pr_warn("Failed to set panel overdrive: %d\n", err); -+ return err; -+ } -+ -+ if (retval > 1 || retval < 0) { -+ pr_warn("Failed to set panel overdrive (retval): 0x%x\n", retval); -+ return -EIO; -+ } -+ -+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od"); -+ -+ return 0; -+} -+ -+static ssize_t panel_od_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ bool mode = asus->panel_overdrive; -+ -+ return sysfs_emit(buf, "%d\n", mode); -+} -+ -+static ssize_t panel_od_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int result; -+ bool overdrive; -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ -+ result = kstrtobool(buf, &overdrive); -+ if (result == -EINVAL) -+ return result; -+ -+ asus->panel_overdrive = overdrive; -+ result = panel_od_write(asus); -+ -+ if (result != 0) -+ return result; -+ -+ return count; -+} -+ -+static DEVICE_ATTR_RW(panel_od); -+ - /* Quirks *********************************************************************/ - - static void asus_wmi_set_xusb2pr(struct asus_wmi *asus) -@@ -2332,6 +2415,7 @@ static struct attribute *platform_attributes[] = { - &dev_attr_als_enable.attr, - &dev_attr_fan_boost_mode.attr, - &dev_attr_throttle_thermal_policy.attr, -+ &dev_attr_panel_od.attr, - NULL - }; - -@@ -2357,6 +2441,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, - ok = asus->fan_boost_mode_available; - else if (attr == &dev_attr_throttle_thermal_policy.attr) - ok = asus->throttle_thermal_policy_available; -+ else if (attr == &dev_attr_panel_od.attr) -+ ok = asus->panel_overdrive_available; - - if (devid != -1) - ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); -@@ -2622,6 +2708,10 @@ static int asus_wmi_add(struct platform_device *pdev) - else - throttle_thermal_policy_set_default(asus); - -+ err = panel_od_check_present(asus); -+ if (err) -+ goto fail_panel_od; -+ - err = asus_wmi_sysfs_init(asus->platform_device); - if (err) - goto fail_sysfs; -@@ -2709,6 +2799,7 @@ static int asus_wmi_add(struct platform_device *pdev) - fail_throttle_thermal_policy: - fail_fan_boost_mode: - fail_platform: -+fail_panel_od: - kfree(asus); - return err; - } -diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h -index 2f274cf52805..428aea701c7b 100644 ---- a/include/linux/platform_data/x86/asus-wmi.h -+++ b/include/linux/platform_data/x86/asus-wmi.h -@@ -61,6 +61,7 @@ - #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075 - - /* Misc */ -+#define ASUS_WMI_DEVID_PANEL_OD 0x00050019 - #define ASUS_WMI_DEVID_CAMERA 0x00060013 - #define ASUS_WMI_DEVID_LID_FLIP 0x00060062 - --- -2.32.0 - diff --git a/sys-kernel_arch-sources-g14_files-0043-ALSA-hda-realtek-Fix-speakers-not-working-on-Asus-Fl.patch b/sys-kernel_arch-sources-g14_files-0043-ALSA-hda-realtek-Fix-speakers-not-working-on-Asus-Fl.patch deleted file mode 100644 index 3152a2006190..000000000000 --- a/sys-kernel_arch-sources-g14_files-0043-ALSA-hda-realtek-Fix-speakers-not-working-on-Asus-Fl.patch +++ /dev/null @@ -1,25 +0,0 @@ -From d3fcb93a34ad9065cd7d4adc2023ec6ead6eb1ee Mon Sep 17 00:00:00 2001 -From: Bobi Mihalca <bobby@mihalca.eu> -Date: Tue, 27 Apr 2021 01:14:24 +0300 -Subject: [PATCH] ALSA: hda/realtek: Fix speakers not working on Asus Flow x13 - -Signed-off-by: Bobi Mihalca <bobby@mihalca.eu> ---- - sound/pci/hda/patch_realtek.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index cc13a68197f3..7a18b19c5062 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -8336,6 +8336,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), - SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), - SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), -+ SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), - SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS), - SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), --- -2.32.0 - diff --git a/sys-kernel_arch-sources-g14_files-0044-claymore.patch b/sys-kernel_arch-sources-g14_files-0044-claymore.patch deleted file mode 100644 index 0b92ccba5a35..000000000000 --- a/sys-kernel_arch-sources-g14_files-0044-claymore.patch +++ /dev/null @@ -1,52 +0,0 @@ -diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c -index fb807c8e989b..0cce348cd50d 100644 ---- a/drivers/hid/hid-asus.c -+++ b/drivers/hid/hid-asus.c -@@ -82,6 +82,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); - #define QUIRK_T90CHI BIT(9) - #define QUIRK_MEDION_E1239T BIT(10) - #define QUIRK_ROG_NKEY_KEYBOARD BIT(11) -+#define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12) - - #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ - QUIRK_NO_INIT_REPORTS | \ -@@ -366,6 +367,17 @@ static int asus_raw_event(struct hid_device *hdev, - - } - -+ if (drvdata->quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD) { -+ /* -+ * CLAYMORE II keyboard sends this packet when it goes to sleep -+ * this causes the whole system to go into suspend. -+ */ -+ -+ if(size == 2 && data[0] == 0x02 && data[1] == 0x00) { -+ return -1; -+ } -+ } -+ - return 0; - } - -@@ -1225,6 +1237,9 @@ static const struct hid_device_id asus_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, -+ USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), -+ QUIRK_ROG_CLAYMORE_II_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD), - QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES }, -diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h -index 63ca5959dc67..ee02e87a75b0 100644 ---- a/drivers/hid/hid-ids.h -+++ b/drivers/hid/hid-ids.h -@@ -197,6 +197,7 @@ - #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 0x1822 - #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866 - #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 -+#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b - #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 - - #define USB_VENDOR_ID_ATEN 0x0557 diff --git a/sys-kernel_arch-sources-g14_files-0045-v5-asus-wmi-Add-support-for-platform_profile.patch b/sys-kernel_arch-sources-g14_files-0045-v5-asus-wmi-Add-support-for-platform_profile.patch deleted file mode 100644 index 737c3bd2c15c..000000000000 --- a/sys-kernel_arch-sources-g14_files-0045-v5-asus-wmi-Add-support-for-platform_profile.patch +++ /dev/null @@ -1,239 +0,0 @@ -From ecb125585d4e69dda57647af19b8a8736b876cee Mon Sep 17 00:00:00 2001 -From: "Luke D. Jones" <luke@ljones.dev> -Date: Fri, 13 Aug 2021 14:36:01 +1200 -Subject: [PATCH v5 1/1] asus-wmi: Add support for platform_profile - -Add initial support for platform_profile where the support is -based on availability of ASUS_THROTTLE_THERMAL_POLICY. - -Because throttle_thermal_policy is used by platform_profile and is -writeable separately to platform_profile any userspace changes to -throttle_thermal_policy need to notify platform_profile. - -In future throttle_thermal_policy sysfs should be removed so that -only one method controls the laptop power profile. - -Signed-off-by: Luke D. Jones <luke@ljones.dev> ---- - drivers/platform/x86/Kconfig | 1 + - drivers/platform/x86/asus-wmi.c | 130 +++++++++++++++++++++++++++++++- - 2 files changed, 127 insertions(+), 4 deletions(-) - -diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig -index d12db6c316ea..46dec48a36c1 100644 ---- a/drivers/platform/x86/Kconfig -+++ b/drivers/platform/x86/Kconfig -@@ -281,6 +281,7 @@ config ASUS_WMI - select INPUT_SPARSEKMAP - select LEDS_CLASS - select NEW_LEDS -+ select ACPI_PLATFORM_PROFILE - help - Say Y here if you have a WMI aware Asus laptop (like Eee PCs or new - Asus Notebooks). -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 90a6a0d00deb..cc5811844012 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -26,6 +26,7 @@ - #include <linux/rfkill.h> - #include <linux/pci.h> - #include <linux/pci_hotplug.h> -+#include <linux/platform_profile.h> - #include <linux/power_supply.h> - #include <linux/hwmon.h> - #include <linux/hwmon-sysfs.h> -@@ -219,6 +220,9 @@ struct asus_wmi { - bool throttle_thermal_policy_available; - u8 throttle_thermal_policy_mode; - -+ struct platform_profile_handler platform_profile_handler; -+ bool platform_profile_support; -+ - // The RSOC controls the maximum charging percentage. - bool battery_rsoc_available; - -@@ -2103,12 +2107,23 @@ static int throttle_thermal_policy_set_default(struct asus_wmi *asus) - static int throttle_thermal_policy_switch_next(struct asus_wmi *asus) - { - u8 new_mode = asus->throttle_thermal_policy_mode + 1; -+ int err; - - if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT) - new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT; - - asus->throttle_thermal_policy_mode = new_mode; -- return throttle_thermal_policy_write(asus); -+ err = throttle_thermal_policy_write(asus); -+ if (err) -+ return err; -+ -+ /* -+ * Ensure that platform_profile updates userspace with the change to ensure -+ * that platform_profile and throttle_thermal_policy_mode are in sync. -+ */ -+ platform_profile_notify(); -+ -+ return 0; - } - - static ssize_t throttle_thermal_policy_show(struct device *dev, -@@ -2124,9 +2139,10 @@ static ssize_t throttle_thermal_policy_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) - { -- int result; -- u8 new_mode; - struct asus_wmi *asus = dev_get_drvdata(dev); -+ u8 new_mode; -+ int result; -+ int err; - - result = kstrtou8(buf, 10, &new_mode); - if (result < 0) -@@ -2136,7 +2152,15 @@ static ssize_t throttle_thermal_policy_store(struct device *dev, - return -EINVAL; - - asus->throttle_thermal_policy_mode = new_mode; -- throttle_thermal_policy_write(asus); -+ err = throttle_thermal_policy_write(asus); -+ if (err) -+ return err; -+ -+ /* -+ * Ensure that platform_profile updates userspace with the change to ensure -+ * that platform_profile and throttle_thermal_policy_mode are in sync. -+ */ -+ platform_profile_notify(); - - return count; - } -@@ -2144,6 +2168,94 @@ static ssize_t throttle_thermal_policy_store(struct device *dev, - // Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent - static DEVICE_ATTR_RW(throttle_thermal_policy); - -+/* Platform profile ***********************************************************/ -+static int platform_profile_get(struct platform_profile_handler *pprof, -+ enum platform_profile_option *profile) -+{ -+ struct asus_wmi *asus; -+ int tp; -+ -+ asus = container_of(pprof, struct asus_wmi, platform_profile_handler); -+ -+ tp = asus->throttle_thermal_policy_mode; -+ -+ if (tp < 0) -+ return tp; -+ -+ switch (tp) { -+ case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT: -+ *profile = PLATFORM_PROFILE_BALANCED; -+ break; -+ case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST: -+ *profile = PLATFORM_PROFILE_PERFORMANCE; -+ break; -+ case ASUS_THROTTLE_THERMAL_POLICY_SILENT: -+ *profile = PLATFORM_PROFILE_QUIET; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int platform_profile_set(struct platform_profile_handler *pprof, -+ enum platform_profile_option profile) -+{ -+ struct asus_wmi *asus; -+ int tp; -+ -+ asus = container_of(pprof, struct asus_wmi, platform_profile_handler); -+ -+ switch (profile) { -+ case PLATFORM_PROFILE_PERFORMANCE: -+ tp = ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST; -+ break; -+ case PLATFORM_PROFILE_BALANCED: -+ tp = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT; -+ break; -+ case PLATFORM_PROFILE_QUIET: -+ tp = ASUS_THROTTLE_THERMAL_POLICY_SILENT; -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ asus->throttle_thermal_policy_mode = tp; -+ return throttle_thermal_policy_write(asus); -+} -+ -+static int platform_profile_setup(struct asus_wmi *asus) -+{ -+ struct device *dev = &asus->platform_device->dev; -+ int err; -+ -+ /* -+ * Not an error if a component platform_profile relies on is unavailable -+ * so early return, skipping the setup of platform_profile. -+ */ -+ if (!asus->throttle_thermal_policy_available) -+ return 0; -+ -+ dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n"); -+ -+ asus->platform_profile_handler.profile_get = platform_profile_get; -+ asus->platform_profile_handler.profile_set = platform_profile_set; -+ -+ set_bit(PLATFORM_PROFILE_QUIET, asus->platform_profile_handler.choices); -+ set_bit(PLATFORM_PROFILE_BALANCED, -+ asus->platform_profile_handler.choices); -+ set_bit(PLATFORM_PROFILE_PERFORMANCE, -+ asus->platform_profile_handler.choices); -+ -+ err = platform_profile_register(&asus->platform_profile_handler); -+ if (err) -+ return err; -+ -+ asus->platform_profile_support = true; -+ return 0; -+} -+ - /* Backlight ******************************************************************/ - - static int read_backlight_power(struct asus_wmi *asus) -@@ -2904,6 +3016,10 @@ static int asus_wmi_add(struct platform_device *pdev) - else - throttle_thermal_policy_set_default(asus); - -+ err = platform_profile_setup(asus); -+ if (err) -+ goto fail_platform_profile_setup; -+ - err = panel_od_check_present(asus); - if (err) - goto fail_panel_od; -@@ -2993,6 +3109,9 @@ static int asus_wmi_add(struct platform_device *pdev) - asus_wmi_sysfs_exit(asus->platform_device); - fail_sysfs: - fail_throttle_thermal_policy: -+fail_platform_profile_setup: -+ if (asus->platform_profile_support) -+ platform_profile_remove(); - fail_fan_boost_mode: - fail_egpu_enable: - fail_dgpu_disable: -@@ -3017,6 +3136,9 @@ static int asus_wmi_remove(struct platform_device *device) - asus_fan_set_auto(asus); - asus_wmi_battery_exit(asus); - -+ if (asus->platform_profile_support) -+ platform_profile_remove(); -+ - kfree(asus); - return 0; - } --- -2.31.1 - diff --git a/sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch b/sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch deleted file mode 100644 index be11606fad13..000000000000 --- a/sys-kernel_arch-sources-g14_files-0046-fan-curvers.patch +++ /dev/null @@ -1,772 +0,0 @@ -From b9e2eae999333fc1ad9ddf4cf0e36a0eaee239e2 Mon Sep 17 00:00:00 2001 -From: "Luke D. Jones" <luke@ljones.dev> -Date: Sun, 29 Aug 2021 13:21:23 +1200 -Subject: [PATCH v15] asus-wmi: Add support for custom fan curves - -Add support for custom fan curves found on some ASUS ROG laptops. - -These laptops have the ability to set a custom curve for the CPU -and GPU fans via two ACPI methods. - -This patch adds two pwm<N> attributes to the hwmon sysfs, -pwm1 for CPU fan, pwm2 for GPU fan. Both are under the hwmon of the -name `asus_custom_fan_curve`. There is no safety check of the set -fan curves - this must be done in userspace. - -The fans have settings [1,2,3] under pwm<N>_enable: -1. Enable and write settings out -2. Disable and use factory fan mode -3. Same as 2, additionally restoring default factory curve. - -Use of 2 means that the curve the user has set is still stored and -won't be erased, but the laptop will be using its default auto-fan -mode. Re-enabling the manual mode then activates the curves again. - -Notes: -- pwm<N>_enable = 0 is an invalid setting. -- pwm is actually a percentage and is scaled on writing to device. - -Signed-off-by: Luke D. Jones <luke@ljones.dev> ---- - drivers/platform/x86/asus-wmi.c | 608 ++++++++++++++++++++- - include/linux/platform_data/x86/asus-wmi.h | 2 + - 2 files changed, 602 insertions(+), 8 deletions(-) - -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index e14fb5fa7324..8b0ed1969d86 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -106,8 +106,17 @@ module_param(fnlock_default, bool, 0444); - - #define WMI_EVENT_MASK 0xFFFF - -+#define FAN_CURVE_POINTS 8 -+#define FAN_CURVE_BUF_LEN (FAN_CURVE_POINTS * 2) -+#define FAN_CURVE_DEV_CPU 0x00 -+#define FAN_CURVE_DEV_GPU 0x01 -+/* Mask to determine if setting temperature or percentage */ -+#define FAN_CURVE_PWM_MASK 0x04 -+ - static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; - -+static int throttle_thermal_policy_write(struct asus_wmi *); -+ - static bool ashs_present(void) - { - int i = 0; -@@ -122,7 +131,8 @@ struct bios_args { - u32 arg0; - u32 arg1; - u32 arg2; /* At least TUF Gaming series uses 3 dword input buffer. */ -- u32 arg4; -+ u32 arg3; -+ u32 arg4; /* Some ROG laptops require a full 5 input args */ - u32 arg5; - } __packed; - -@@ -173,6 +183,12 @@ enum fan_type { - FAN_TYPE_SPEC83, /* starting in Spec 8.3, use CPU_FAN_CTRL */ - }; - -+struct fan_curve_data { -+ bool enabled; -+ u8 temps[FAN_CURVE_POINTS]; -+ u8 percents[FAN_CURVE_POINTS]; -+}; -+ - struct asus_wmi { - int dsts_id; - int spec; -@@ -220,6 +236,10 @@ struct asus_wmi { - bool throttle_thermal_policy_available; - u8 throttle_thermal_policy_mode; - -+ bool cpu_fan_curve_available; -+ bool gpu_fan_curve_available; -+ struct fan_curve_data custom_fan_curves[2]; -+ - struct platform_profile_handler platform_profile_handler; - bool platform_profile_support; - -@@ -285,6 +305,103 @@ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval) - } - EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method); - -+static int asus_wmi_evaluate_method5(u32 method_id, -+ u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 *retval) -+{ -+ struct bios_args args = { -+ .arg0 = arg0, -+ .arg1 = arg1, -+ .arg2 = arg2, -+ .arg3 = arg3, -+ .arg4 = arg4, -+ }; -+ struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; -+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; -+ acpi_status status; -+ union acpi_object *obj; -+ u32 tmp = 0; -+ -+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id, -+ &input, &output); -+ -+ if (ACPI_FAILURE(status)) -+ return -EIO; -+ -+ obj = (union acpi_object *)output.pointer; -+ if (obj && obj->type == ACPI_TYPE_INTEGER) -+ tmp = (u32) obj->integer.value; -+ -+ if (retval) -+ *retval = tmp; -+ -+ kfree(obj); -+ -+ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) -+ return -ENODEV; -+ -+ return 0; -+} -+ -+/* -+ * Returns as an error if the method output is not a buffer. Typically this -+ * means that the method called is unsupported. -+ */ -+static int asus_wmi_evaluate_method_buf(u32 method_id, -+ u32 arg0, u32 arg1, u8 *ret_buffer, size_t size) -+{ -+ struct bios_args args = { -+ .arg0 = arg0, -+ .arg1 = arg1, -+ .arg2 = 0, -+ }; -+ struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; -+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; -+ acpi_status status; -+ union acpi_object *obj; -+ int err = 0; -+ -+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id, -+ &input, &output); -+ -+ if (ACPI_FAILURE(status)) -+ return -EIO; -+ -+ obj = (union acpi_object *)output.pointer; -+ -+ switch (obj->type) { -+ case ACPI_TYPE_BUFFER: -+ if (obj->buffer.length > size) -+ err = -ENOSPC; -+ if (obj->buffer.length == 0) -+ err = -ENODATA; -+ -+ memcpy(ret_buffer, obj->buffer.pointer, obj->buffer.length); -+ break; -+ case ACPI_TYPE_INTEGER: -+ err = (u32)obj->integer.value; -+ -+ if (err == ASUS_WMI_UNSUPPORTED_METHOD) -+ err = -ENODEV; -+ /* -+ * At least one method returns a 0 with no buffer if no arg -+ * is provided, such as ASUS_WMI_DEVID_CPU_FAN_CURVE -+ */ -+ if (err == 0) -+ err = -ENODATA; -+ break; -+ default: -+ err = -ENODATA; -+ break; -+ } -+ -+ kfree(obj); -+ -+ if (err) -+ return err; -+ -+ return 0; -+} -+ - static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args) - { - struct acpi_buffer input; -@@ -1806,6 +1923,13 @@ static ssize_t pwm1_enable_store(struct device *dev, - } - - asus->fan_pwm_mode = state; -+ -+ /* Must set to disabled if mode is toggled */ -+ if (asus->cpu_fan_curve_available) -+ asus->custom_fan_curves[FAN_CURVE_DEV_CPU].enabled = false; -+ if (asus->gpu_fan_curve_available) -+ asus->custom_fan_curves[FAN_CURVE_DEV_GPU].enabled = false; -+ - return count; - } - -@@ -1953,9 +2077,9 @@ static int fan_boost_mode_check_present(struct asus_wmi *asus) - - static int fan_boost_mode_write(struct asus_wmi *asus) - { -- int err; -- u8 value; - u32 retval; -+ u8 value; -+ int err; - - value = asus->fan_boost_mode; - -@@ -2013,10 +2137,10 @@ static ssize_t fan_boost_mode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) - { -- int result; -- u8 new_mode; - struct asus_wmi *asus = dev_get_drvdata(dev); - u8 mask = asus->fan_boost_mode_mask; -+ u8 new_mode; -+ int result; - - result = kstrtou8(buf, 10, &new_mode); - if (result < 0) { -@@ -2043,6 +2167,462 @@ static ssize_t fan_boost_mode_store(struct device *dev, - // Fan boost mode: 0 - normal, 1 - overboost, 2 - silent - static DEVICE_ATTR_RW(fan_boost_mode); - -+/* Custom fan curves *********************************************************/ -+ -+static void fan_curve_copy_from_buf(struct fan_curve_data *data, u8 *buf) -+{ -+ int i; -+ -+ for (i = 0; i < FAN_CURVE_POINTS; i++) { -+ data->temps[i] = buf[i]; -+ } -+ -+ for (i = 0; i < FAN_CURVE_POINTS; i++) { -+ data->percents[i] = -+ 255 * buf[i + FAN_CURVE_POINTS] / 100; -+ } -+} -+ -+static int fan_curve_get_factory_default(struct asus_wmi *asus, u32 fan_dev) -+{ -+ struct fan_curve_data *curves; -+ u8 buf[FAN_CURVE_BUF_LEN]; -+ int fan_idx = 0; -+ u8 mode = 0; -+ int err; -+ -+ if (asus->throttle_thermal_policy_available) -+ mode = asus->throttle_thermal_policy_mode; -+ /* DEVID_<C/G>PU_FAN_CURVE is switched for OVERBOOST vs SILENT */ -+ if (mode == 2) -+ mode = 1; -+ else if (mode == 1) -+ mode = 2; -+ -+ if (fan_dev == ASUS_WMI_DEVID_GPU_FAN_CURVE) -+ fan_idx = FAN_CURVE_DEV_GPU; -+ -+ curves = &asus->custom_fan_curves[fan_idx]; -+ err = asus_wmi_evaluate_method_buf(asus->dsts_id, fan_dev, mode, buf, -+ FAN_CURVE_BUF_LEN); -+ if (err) -+ return err; -+ -+ fan_curve_copy_from_buf(curves, buf); -+ -+ return 0; -+} -+ -+/* Check if capability exists, and populate defaults */ -+static int fan_curve_check_present(struct asus_wmi *asus, bool *available, -+ u32 fan_dev) -+{ -+ int err; -+ -+ *available = false; -+ -+ err = fan_curve_get_factory_default(asus, fan_dev); -+ if (err) { -+ if (err == -ENODEV) -+ return 0; -+ return err; -+ } -+ -+ *available = true; -+ return 0; -+} -+ -+/* Determine which fan the attribute is for if SENSOR_ATTR */ -+static struct fan_curve_data *fan_curve_attr_select(struct asus_wmi *asus, -+ struct device_attribute *attr) -+{ -+ int index = to_sensor_dev_attr(attr)->index; -+ -+ return &asus->custom_fan_curves[index & FAN_CURVE_DEV_GPU]; -+} -+ -+/* Determine which fan the attribute is for if SENSOR_ATTR_2 */ -+static struct fan_curve_data *fan_curve_attr_2_select(struct asus_wmi *asus, -+ struct device_attribute *attr) -+{ -+ int nr = to_sensor_dev_attr_2(attr)->nr; -+ -+ return &asus->custom_fan_curves[nr & FAN_CURVE_DEV_GPU]; -+} -+ -+static ssize_t fan_curve_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr); -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ struct fan_curve_data *data; -+ int value, index, nr; -+ -+ data = fan_curve_attr_2_select(asus, attr); -+ index = dev_attr->index; -+ nr = dev_attr->nr; -+ -+ if (nr & FAN_CURVE_PWM_MASK) -+ value = data->percents[index]; -+ else -+ value = data->temps[index]; -+ -+ return sysfs_emit(buf, "%d\n", value); -+} -+ -+/* -+ * "fan_dev" is the related WMI method such as ASUS_WMI_DEVID_CPU_FAN_CURVE. -+ */ -+static int fan_curve_write(struct asus_wmi *asus, -+ struct device_attribute *attr, u32 fan_dev) -+{ -+ struct fan_curve_data *data = fan_curve_attr_2_select(asus, attr); -+ u32 arg1 = 0, arg2 = 0, arg3 = 0, arg4 = 0; -+ u8 *percents = data->percents; -+ u8 *temps = data->temps; -+ int ret, i, shift = 0; -+ -+ for (i = 0; i < FAN_CURVE_POINTS / 2; i++) { -+ arg1 += (temps[i]) << shift; -+ arg2 += (temps[i + 4]) << shift; -+ /* Scale to percentage for device */ -+ arg3 += (100 * percents[i] / 255) << shift; -+ arg4 += (100 * percents[i + 4] / 255) << shift; -+ shift += 8; -+ } -+ -+ return asus_wmi_evaluate_method5(ASUS_WMI_METHODID_DEVS, fan_dev, arg1, -+ arg2, arg3, arg4, &ret); -+} -+ -+/* -+ * Called on curve enable/disable. This should be the only way to write out the -+ * fan curves. This avoids potential lockups on write to ACPI for every change. -+ */ -+static int fan_curve_write_data(struct asus_wmi *asus, -+ struct device_attribute *attr) -+{ -+ int err; -+ -+ if (asus->cpu_fan_curve_available) { -+ err = fan_curve_write(asus, attr, ASUS_WMI_DEVID_CPU_FAN_CURVE); -+ if (err) -+ return err; -+ } -+ -+ if (asus->gpu_fan_curve_available) { -+ err = fan_curve_write(asus, attr, ASUS_WMI_DEVID_GPU_FAN_CURVE); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static ssize_t fan_curve_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr); -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ struct fan_curve_data *data; -+ u8 value; -+ int err; -+ -+ int pwm = dev_attr->nr & FAN_CURVE_PWM_MASK; -+ int index = dev_attr->index; -+ -+ data = fan_curve_attr_2_select(asus, attr); -+ -+ err = kstrtou8(buf, 10, &value); -+ if (err < 0) -+ return err; -+ -+ if (pwm) { -+ data->percents[index] = value; -+ } else { -+ data->temps[index] = value; -+ } -+ -+ /* -+ * Mark as disabled so the user has to explicitly enable to apply a -+ * changed fan curve. This prevents potential lockups from writing out -+ * many changes as one-write-per-change. -+ */ -+ data->enabled = false; -+ -+ return count; -+} -+ -+static ssize_t fan_curve_enable_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ struct fan_curve_data *data; -+ int out = 2; -+ -+ data = fan_curve_attr_select(asus, attr); -+ -+ if (data->enabled) -+ out = 1; -+ -+ return sysfs_emit(buf, "%d\n", out); -+} -+ -+static int fan_curve_set_default(struct asus_wmi *asus) -+{ -+ int err; -+ -+ err = fan_curve_get_factory_default( -+ asus, ASUS_WMI_DEVID_CPU_FAN_CURVE); -+ if (err) -+ return err; -+ -+ err = fan_curve_get_factory_default( -+ asus, ASUS_WMI_DEVID_GPU_FAN_CURVE); -+ if (err) -+ return err; -+ return 0; -+} -+ -+static ssize_t fan_curve_enable_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ struct fan_curve_data *data; -+ int value, err; -+ -+ data = fan_curve_attr_select(asus, attr); -+ -+ err = kstrtoint(buf, 10, &value); -+ if (err < 0) -+ return err; -+ -+ switch (value) { -+ case 1: -+ data->enabled = true; -+ break; -+ case 2: -+ data->enabled = false; -+ break; -+ /* -+ * Auto + reset the fan curve data to defaults. Make it an explicit -+ * option so that users don't accidentally overwrite a set fan curve. -+ */ -+ case 3: -+ err = fan_curve_set_default(asus); -+ if (err) -+ return err; -+ data->enabled = false; -+ break; -+ default: -+ return -EINVAL; -+ }; -+ -+ /* -+ * For machines with throttle this is the only way to reset fans to -+ * default mode of operation (does not erase curve data). -+ */ -+ if (asus->throttle_thermal_policy_available && !data->enabled) { -+ err = throttle_thermal_policy_write(asus); -+ if (err) -+ return err; -+ } -+ /* Similar is true for laptops with this fan */ -+ if (asus->fan_type == FAN_TYPE_SPEC83) { -+ err = asus_fan_set_auto(asus); -+ if (err) -+ return err; -+ } -+ /* -+ * Machines without either need to write their defaults back always. -+ * This is more of a safeguard against ASUS faulty ACPI tables. -+ */ -+ if (!asus->throttle_thermal_policy_available -+ && asus->fan_type != FAN_TYPE_SPEC83 && !data->enabled) { -+ err = fan_curve_set_default(asus); -+ if (err) -+ return err; -+ err = fan_curve_write_data(asus, attr); -+ if (err) -+ return err; -+ } -+ -+ if (data->enabled) { -+ err = fan_curve_write_data(asus, attr); -+ if (err) -+ return err; -+ } -+ -+ return count; -+} -+ -+/* CPU */ -+static SENSOR_DEVICE_ATTR_RW(pwm1_enable, fan_curve_enable, FAN_CURVE_DEV_CPU); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 0); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point2_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 1); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point3_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 2); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point4_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 3); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point5_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 4); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point6_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 5); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point7_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 6); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point8_temp, fan_curve, -+ FAN_CURVE_DEV_CPU, 7); -+ -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 0); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point2_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 1); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point3_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 2); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point4_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 3); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point5_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 4); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point6_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 5); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point7_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 6); -+static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point8_pwm, fan_curve, -+ FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 7); -+ -+/* GPU */ -+static SENSOR_DEVICE_ATTR_RW(pwm2_enable, fan_curve_enable, FAN_CURVE_DEV_GPU); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point1_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 0); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point2_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 1); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point3_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 2); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point4_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 3); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point5_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 4); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point6_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 5); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point7_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 6); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point8_temp, fan_curve, -+ FAN_CURVE_DEV_GPU, 7); -+ -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point1_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 0); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point2_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 1); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point3_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 2); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point4_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 3); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point5_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 4); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point6_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 5); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point7_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 6); -+static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point8_pwm, fan_curve, -+ FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 7); -+ -+static struct attribute *asus_fan_curve_attr[] = { -+ /* CPU */ -+ &sensor_dev_attr_pwm1_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point6_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point7_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point8_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point6_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point7_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm1_auto_point8_pwm.dev_attr.attr, -+ /* GPU */ -+ &sensor_dev_attr_pwm2_enable.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point5_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point6_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point7_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point8_temp.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point5_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point6_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point7_pwm.dev_attr.attr, -+ &sensor_dev_attr_pwm2_auto_point8_pwm.dev_attr.attr, -+ NULL -+}; -+ -+static umode_t asus_fan_curve_is_visible(struct kobject *kobj, -+ struct attribute *attr, int idx) -+{ -+ struct device *dev = container_of(kobj, struct device, kobj); -+ struct asus_wmi *asus = dev_get_drvdata(dev->parent); -+ -+ if (asus->cpu_fan_curve_available) -+ return 0644; -+ -+ if (asus->gpu_fan_curve_available) -+ return 0644; -+ -+ return 0; -+} -+ -+static const struct attribute_group asus_fan_curve_attr_group = { -+ .is_visible = asus_fan_curve_is_visible, -+ .attrs = asus_fan_curve_attr, -+}; -+__ATTRIBUTE_GROUPS(asus_fan_curve_attr); -+ -+/* -+ * Must be initialised after throttle_thermal_policy_check_present() as -+ * we check the status of throttle_thermal_policy_available during init. -+ */ -+static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus) -+{ -+ struct device *dev = &asus->platform_device->dev; -+ struct device *hwmon; -+ int err; -+ -+ err = fan_curve_check_present(asus, &asus->cpu_fan_curve_available, -+ ASUS_WMI_DEVID_CPU_FAN_CURVE); -+ if (err) -+ return err; -+ -+ err = fan_curve_check_present(asus, &asus->gpu_fan_curve_available, -+ ASUS_WMI_DEVID_GPU_FAN_CURVE); -+ if (err) -+ return err; -+ -+ hwmon = devm_hwmon_device_register_with_groups( -+ dev, "asus_custom_fan_curve", asus, asus_fan_curve_attr_groups); -+ -+ if (IS_ERR(hwmon)) { -+ dev_err(dev, -+ "Could not register asus_custom_fan_curve device\n"); -+ return PTR_ERR(hwmon); -+ } -+ -+ return 0; -+} -+ - /* Throttle thermal policy ****************************************************/ - - static int throttle_thermal_policy_check_present(struct asus_wmi *asus) -@@ -2053,8 +2633,8 @@ static int throttle_thermal_policy_check_present(struct asus_wmi *asus) - asus->throttle_thermal_policy_available = false; - - err = asus_wmi_get_devstate(asus, -- ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, -- &result); -+ ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, -+ &result); - if (err) { - if (err == -ENODEV) - return 0; -@@ -2092,6 +2672,12 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus) - return -EIO; - } - -+ /* Must set to disabled if mode is toggled */ -+ if (asus->cpu_fan_curve_available) -+ asus->custom_fan_curves[FAN_CURVE_DEV_CPU].enabled = false; -+ if (asus->gpu_fan_curve_available) -+ asus->custom_fan_curves[FAN_CURVE_DEV_GPU].enabled = false; -+ - return 0; - } - -@@ -2901,7 +3487,7 @@ static int show_call(struct seq_file *m, void *data) - if (ACPI_FAILURE(status)) - return -EIO; - -- obj = (union acpi_object *)output.pointer; -+ obj = output.pointer; - if (obj && obj->type == ACPI_TYPE_INTEGER) - seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id, - asus->debug.dev_id, asus->debug.ctrl_param, -@@ -3035,6 +3621,10 @@ static int asus_wmi_add(struct platform_device *pdev) - if (err) - goto fail_hwmon; - -+ err = asus_wmi_custom_fan_curve_init(asus); -+ if (err) -+ goto fail_custom_fan_curve; -+ - err = asus_wmi_led_init(asus); - if (err) - goto fail_leds; -@@ -3106,6 +3696,7 @@ static int asus_wmi_add(struct platform_device *pdev) - asus_wmi_sysfs_exit(asus->platform_device); - fail_sysfs: - fail_throttle_thermal_policy: -+fail_custom_fan_curve: - fail_platform_profile_setup: - if (asus->platform_profile_support) - platform_profile_remove(); -@@ -3131,6 +3722,7 @@ static int asus_wmi_remove(struct platform_device *device) - asus_wmi_debugfs_exit(asus); - asus_wmi_sysfs_exit(asus->platform_device); - asus_fan_set_auto(asus); -+ throttle_thermal_policy_set_default(asus); - asus_wmi_battery_exit(asus); - - if (asus->platform_profile_support) -diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h -index 17dc5cb6f3f2..a571b47ff362 100644 ---- a/include/linux/platform_data/x86/asus-wmi.h -+++ b/include/linux/platform_data/x86/asus-wmi.h -@@ -77,6 +77,8 @@ - #define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011 - #define ASUS_WMI_DEVID_FAN_CTRL 0x00110012 /* deprecated */ - #define ASUS_WMI_DEVID_CPU_FAN_CTRL 0x00110013 -+#define ASUS_WMI_DEVID_CPU_FAN_CURVE 0x00110024 -+#define ASUS_WMI_DEVID_GPU_FAN_CURVE 0x00110025 - - /* Power */ - #define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012 --- -2.32.0 - diff --git a/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-Allow-configuring-SW_TABLET.patch b/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-Allow-configuring-SW_TABLET.patch deleted file mode 100644 index d497fb6171be..000000000000 --- a/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-Allow-configuring-SW_TABLET.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0c2f287ea670acbf9d4ed68efd55b5f2b76b50ca Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 28 Jul 2021 20:35:15 +0200 -Subject: [PATCH 1/2] platform/x86: asus-nb-wmi: Allow configuring - SW_TABLET_MODE method with a module option - -Unfortunately we have been unable to find a reliable way to detect if -and how SW_TABLET_MODE reporting is supported, so we are relying on -DMI quirks for this. - -Add a module-option to specify the SW_TABLET_MODE method so that this can -be easily tested without needing to rebuild the kernel. - -BugLink: https://gitlab.freedesktop.org/libinput/libinput/-/issues/639 -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/platform/x86/asus-nb-wmi.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c -index 0cb927f0f301..9929eedf7dd8 100644 ---- a/drivers/platform/x86/asus-nb-wmi.c -+++ b/drivers/platform/x86/asus-nb-wmi.c -@@ -41,6 +41,10 @@ static int wapf = -1; - module_param(wapf, uint, 0444); - MODULE_PARM_DESC(wapf, "WAPF value"); - -+static int tablet_mode_sw = -1; -+module_param(tablet_mode_sw, uint, 0444); -+MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip"); -+ - static struct quirk_entry *quirks; - - static bool asus_q500a_i8042_filter(unsigned char data, unsigned char str, -@@ -477,6 +481,21 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) - else - wapf = quirks->wapf; - -+ switch (tablet_mode_sw) { -+ case 0: -+ quirks->use_kbd_dock_devid = false; -+ quirks->use_lid_flip_devid = false; -+ break; -+ case 1: -+ quirks->use_kbd_dock_devid = true; -+ quirks->use_lid_flip_devid = false; -+ break; -+ case 2: -+ quirks->use_kbd_dock_devid = false; -+ quirks->use_lid_flip_devid = true; -+ break; -+ } -+ - if (quirks->i8042_filter) { - ret = i8042_install_filter(quirks->i8042_filter); - if (ret) { --- -2.31.1 diff --git a/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch b/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch index 6327dc76407f..caafcce952e3 100644 --- a/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch +++ b/sys-kernel_arch-sources-g14_files-0048-asus-nb-wmi-fix-tablet_mode_sw_int.patch @@ -1,5 +1,4 @@ diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c -index f24e002ca703..f85fec0e1b76 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -42,7 +42,7 @@ module_param(wapf, uint, 0444); @@ -8,6 +7,6 @@ index f24e002ca703..f85fec0e1b76 100644 static int tablet_mode_sw = -1; -module_param(tablet_mode_sw, uint, 0444); +module_param(tablet_mode_sw, int, 0444); - MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip"); + MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip 3:lid-flip-rog"); - static struct quirk_entry *quirks;
\ No newline at end of file + static struct quirk_entry *quirks; diff --git a/sys-kernel_arch-sources-g14_files-0049-ALSA-hda-realtek-Add-quirk-for-ASUS-M16-GU603H.patch b/sys-kernel_arch-sources-g14_files-0049-ALSA-hda-realtek-Add-quirk-for-ASUS-M16-GU603H.patch new file mode 100644 index 000000000000..c9ead3024540 --- /dev/null +++ b/sys-kernel_arch-sources-g14_files-0049-ALSA-hda-realtek-Add-quirk-for-ASUS-M16-GU603H.patch @@ -0,0 +1,12 @@ +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 72b7e2127f4c..899b380fc395 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -8791,6 +8791,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), ++ SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603H", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS), diff --git a/sys-kernel_arch-sources-g14_files-8002-hwmon-k10temp-support-Zen3-APUs.patch b/sys-kernel_arch-sources-g14_files-8002-hwmon-k10temp-support-Zen3-APUs.patch deleted file mode 100644 index 9f117f8f4365..000000000000 --- a/sys-kernel_arch-sources-g14_files-8002-hwmon-k10temp-support-Zen3-APUs.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 02c6edd4b1a07f24b187a550d413a07260eb696d Mon Sep 17 00:00:00 2001 -From: David Bartley <andareed@gmail.com> -Date: Sun, 16 May 2021 23:41:31 -0700 -Subject: hwmon: (k10temp) support Zen3 APUs - -Add support for Zen3 Ryzen APU. - -Signed-off-by: David Bartley <andareed@gmail.com> -Link: https://lore.kernel.org/r/20210517064131.4369-1-andareed@gmail.com -Signed-off-by: Guenter Roeck <linux@roeck-us.net> ---- - drivers/hwmon/k10temp.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c -index 5ff3669c2b608..fe3d92152e359 100644 ---- a/drivers/hwmon/k10temp.c -+++ b/drivers/hwmon/k10temp.c -@@ -450,6 +450,7 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) - switch (boot_cpu_data.x86_model) { - case 0x0 ... 0x1: /* Zen3 SP3/TR */ - case 0x21: /* Zen3 Ryzen Desktop */ -+ case 0x50: /* Zen3 Ryzen APU */ - k10temp_get_ccd_support(pdev, data, 8); - break; - } -@@ -491,6 +492,7 @@ static const struct pci_device_id k10temp_id_table[] = { - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) }, -+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) }, - { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) }, - {} - }; --- -cgit 1.2.3-1.el7 - diff --git a/sys-kernel_arch-sources-g14_files-8011-Bluetooth-btusb-Enable-MSFT-extension-for-Mediatek-Chip-MT7921.patch b/sys-kernel_arch-sources-g14_files-8011-Bluetooth-btusb-Enable-MSFT-extension-for-Mediatek-Chip-MT7921.patch deleted file mode 100644 index c13ab0806638..000000000000 --- a/sys-kernel_arch-sources-g14_files-8011-Bluetooth-btusb-Enable-MSFT-extension-for-Mediatek-Chip-MT7921.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: <mark-yw.chen@mediatek.com> -To: <marcel@holtmann.org>, <johan.hedberg@gmail.com> -CC: <chris.lu@mediatek.com>, <will-cy.lee@mediatek.com>, - <sean.wang@mediatek.com>, <linux-bluetooth@vger.kernel.org>, - <linux-mediatek@lists.infradead.org>, <linux-kernel@vger.kernel.org>, - <michaelfsun@google.com>, <shawnku@google.com>, <jemele@google.com>, - <apusaka@google.com>, mark-yw.chen <mark-yw.chen@mediatek.com> -Subject: [PATCH 1/1] Bluetooth: btusb: Enable MSFT extension for Mediatek Chip - (MT7921) -Date: Mon, 2 Aug 2021 20:59:41 +0800 - -From: "mark-yw.chen" <mark-yw.chen@mediatek.com> - -The Mdiatek MT7921(7961) support MSFT HCI extensions, we are using -0xFD30 for VsMsftOpCode. - -Signed-off-by: mark-yw.chen <mark-yw.chen@mediatek.com> ---- - drivers/bluetooth/btusb.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index fec798dadd99..b1a05bb9f4bf 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -3775,6 +3775,8 @@ static int btusb_mtk_setup(struct hci_dev *hdev) - bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); - return err; - } -+ -+ hci_set_msft_opcode(hdev, 0xFD30); - goto done; - default: - bt_dev_err(hdev, "Unsupported hardware variant (%08x)", diff --git a/sys-kernel_arch-sources-g14_files-8012-mt76-mt7915-send-EAPOL-frames-at-lowest-rate.patch b/sys-kernel_arch-sources-g14_files-8012-mt76-mt7915-send-EAPOL-frames-at-lowest-rate.patch deleted file mode 100644 index c2e18b71ae18..000000000000 --- a/sys-kernel_arch-sources-g14_files-8012-mt76-mt7915-send-EAPOL-frames-at-lowest-rate.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Ryder Lee <ryder.lee@mediatek.com> -To: Felix Fietkau <nbd@nbd.name> -CC: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>, Shayne Chen - <shayne.chen@mediatek.com>, Evelyn Tsai <evelyn.tsai@mediatek.com>, Sean Wang - <sean.wang@mediatek.com>, <linux-wireless@vger.kernel.org>, - <linux-mediatek@lists.infradead.org>, Ryder Lee <ryder.lee@mediatek.com> -Subject: [PATCH 1/2] mt76: mt7915: send EAPOL frames at lowest rate -Date: Sat, 17 Jul 2021 13:05:48 +0800 - -The firmware rate control may choose the high rate for EAPOL frames, -so checking IEEE80211_TX_CTL_USE_MINRATE to use the lowest TX rate. - -Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> ---- - drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c -index 2462704094b0..d47dd0f96bdb 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c -@@ -869,7 +869,8 @@ mt7915_mac_write_txwi_80211(struct mt7915_dev *dev, __le32 *txwi, - txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); - } - -- if (!ieee80211_is_data(fc) || multicast) -+ if (!ieee80211_is_data(fc) || multicast || -+ info->flags & IEEE80211_TX_CTL_USE_MINRATE) - val |= MT_TXD2_FIX_RATE; - - txwi[2] |= cpu_to_le32(val); diff --git a/sys-kernel_arch-sources-g14_files-8013-mt76-mt7921-robustify-hardware-initialization-flow.patch b/sys-kernel_arch-sources-g14_files-8013-mt76-mt7921-robustify-hardware-initialization-flow.patch deleted file mode 100644 index f475476f8832..000000000000 --- a/sys-kernel_arch-sources-g14_files-8013-mt76-mt7921-robustify-hardware-initialization-flow.patch +++ /dev/null @@ -1,125 +0,0 @@ -From: <sean.wang@mediatek.com> -To: <nbd@nbd.name>, <lorenzo.bianconi@redhat.com> -CC: <sean.wang@mediatek.com>, <Soul.Huang@mediatek.com>, - <YN.Chen@mediatek.com>, <Leon.Yen@mediatek.com>, - <Eric-SY.Chang@mediatek.com>, <Deren.Wu@mediatek.com>, <km.lin@mediatek.com>, - <robin.chiu@mediatek.com>, <ch.yeh@mediatek.com>, <posh.sun@mediatek.com>, - <ted.huang@mediatek.com>, <Eric.Liang@mediatek.com>, - <Stella.Chang@mediatek.com>, <jemele@google.com>, - <linux-wireless@vger.kernel.org>, <linux-mediatek@lists.infradead.org> -Subject: [PATCH 1/2] mt76: mt7921: robustify hardware initialization flow -Date: Tue, 14 Sep 2021 23:50:21 +0800 - -From: Sean Wang <sean.wang@mediatek.com> - -Robustify hardware initialization in the current driver probing flow -to get rid of the device is possibly lost after the machine boot due -to possible firmware abnormal state by trying to recover the failure -with more chances. - -Tested-by: Leon Yen <Leon.Yen@mediatek.com> -Tested-by: YN Chen <YN.Chen@mediatek.com> -Signed-off-by: Sean Wang <sean.wang@mediatek.com> ---- - .../net/wireless/mediatek/mt76/mt7921/init.c | 53 ++++++++++++++----- - .../wireless/mediatek/mt76/mt7921/mt7921.h | 1 + - 2 files changed, 41 insertions(+), 13 deletions(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -index 1f37e64b6038..d26166a612f0 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -@@ -146,33 +146,60 @@ int mt7921_mac_init(struct mt7921_dev *dev) - return mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b, 0); - } - --static int mt7921_init_hardware(struct mt7921_dev *dev) -+static int __mt7921_init_hardware(struct mt7921_dev *dev) - { -- int ret, idx; -- -- ret = mt7921_dma_init(dev); -- if (ret) -- return ret; -- -- set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); -+ struct mt76_dev *mdev = &dev->mt76; -+ int ret; - - /* force firmware operation mode into normal state, - * which should be set before firmware download stage. - */ - mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE); -- - ret = mt7921_mcu_init(dev); - if (ret) -- return ret; -+ goto out; - - ret = mt7921_eeprom_init(dev); -- if (ret < 0) -- return ret; -+ if (ret) -+ goto out; - - ret = mt7921_mcu_set_eeprom(dev); -+ if (ret) -+ goto out; -+ -+ ret = mt7921_mac_init(dev); -+out: -+ if (ret && mdev->eeprom.data) { -+ devm_kfree(mdev->dev, mdev->eeprom.data); -+ mdev->eeprom.data = NULL; -+ } -+ -+ return ret; -+} -+ -+static int mt7921_init_hardware(struct mt7921_dev *dev) -+{ -+ int ret, idx, i; -+ -+ ret = mt7921_dma_init(dev); - if (ret) - return ret; - -+ set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); -+ -+ for (i = 0; i < MT7921_MCU_INIT_RETRY_COUNT; i++) { -+ ret = __mt7921_init_hardware(dev); -+ if (!ret) -+ break; -+ -+ mt7921_wpdma_reset(dev, true); -+ } -+ -+ if (i == MT7921_MCU_INIT_RETRY_COUNT) { -+ dev_err(dev->mt76.dev, "hardware init failed\n"); -+ return ret; -+ } -+ - /* Beacon and mgmt frames should occupy wcid 0 */ - idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7921_WTBL_STA - 1); - if (idx) -@@ -183,7 +210,7 @@ static int mt7921_init_hardware(struct mt7921_dev *dev) - dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET; - rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid); - -- return mt7921_mac_init(dev); -+ return 0; - } - - int mt7921_register_device(struct mt7921_dev *dev) -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h -index 6a47ba65b96e..cee7a2507224 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h -@@ -29,6 +29,7 @@ - #define MT7921_RX_MCU_RING_SIZE 512 - - #define MT7921_DRV_OWN_RETRY_COUNT 10 -+#define MT7921_MCU_INIT_RETRY_COUNT 10 - - #define MT7921_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7961_1.bin" - #define MT7921_ROM_PATCH "mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin" diff --git a/sys-kernel_arch-sources-g14_files-8014-mt76-mt7921-fix-retrying-release-semaphore-without-end.patch b/sys-kernel_arch-sources-g14_files-8014-mt76-mt7921-fix-retrying-release-semaphore-without-end.patch deleted file mode 100644 index 04ef192d9482..000000000000 --- a/sys-kernel_arch-sources-g14_files-8014-mt76-mt7921-fix-retrying-release-semaphore-without-end.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: <sean.wang@mediatek.com> -To: <nbd@nbd.name>, <lorenzo.bianconi@redhat.com> -CC: <sean.wang@mediatek.com>, <Soul.Huang@mediatek.com>, - <YN.Chen@mediatek.com>, <Leon.Yen@mediatek.com>, - <Eric-SY.Chang@mediatek.com>, <Deren.Wu@mediatek.com>, <km.lin@mediatek.com>, - <robin.chiu@mediatek.com>, <ch.yeh@mediatek.com>, <posh.sun@mediatek.com>, - <ted.huang@mediatek.com>, <Eric.Liang@mediatek.com>, - <Stella.Chang@mediatek.com>, <jemele@google.com>, - <linux-wireless@vger.kernel.org>, <linux-mediatek@lists.infradead.org> -Subject: [PATCH 2/2] mt76: mt7921: fix retrying release semaphore without end -Date: Tue, 14 Sep 2021 23:50:22 +0800 - -From: Sean Wang <sean.wang@mediatek.com> - -We should pass the error code to the caller immediately -to avoid the possible infinite retry to release the semaphore. - -Fixes: 1c099ab44727 ("mt76: mt7921: add MCU support") -Co-developed-by: YN Chen <YN.Chen@mediatek.com> -Signed-off-by: YN Chen <YN.Chen@mediatek.com> -Signed-off-by: Sean Wang <sean.wang@mediatek.com> ---- - drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -index 9b35b5da3619..db33506567dc 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -@@ -876,7 +876,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev) - default: - ret = -EAGAIN; - dev_err(dev->mt76.dev, "Failed to release patch semaphore\n"); -- goto out; -+ break; - } - release_firmware(fw); - diff --git a/sys-kernel_arch-sources-g14_files-8015-mt76-mt7921-send-EAPOL-frames-at-lowest-rate.patch b/sys-kernel_arch-sources-g14_files-8015-mt76-mt7921-send-EAPOL-frames-at-lowest-rate.patch deleted file mode 100644 index 0812eb4e785c..000000000000 --- a/sys-kernel_arch-sources-g14_files-8015-mt76-mt7921-send-EAPOL-frames-at-lowest-rate.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Ryder Lee <ryder.lee@mediatek.com> -To: Felix Fietkau <nbd@nbd.name> -CC: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>, Shayne Chen - <shayne.chen@mediatek.com>, Evelyn Tsai <evelyn.tsai@mediatek.com>, Sean Wang - <sean.wang@mediatek.com>, <linux-wireless@vger.kernel.org>, - <linux-mediatek@lists.infradead.org>, Ryder Lee <ryder.lee@mediatek.com> -Subject: [PATCH 2/2] mt76: mt7921: send EAPOL frames at lowest rate -Date: Sat, 17 Jul 2021 13:05:49 +0800 - -The firmware rate control may choose the high rate for EAPOL frames, -so checking IEEE80211_TX_CTL_USE_MINRATE to use the lowest TX rate. - -Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> ---- - drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -index 7fe2e3a50428..eb0d98c8d5d8 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -@@ -702,7 +702,8 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi, - txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); - } - -- if (!ieee80211_is_data(fc) || multicast) -+ if (!ieee80211_is_data(fc) || multicast || -+ info->flags & IEEE80211_TX_CTL_USE_MINRATE) - val |= MT_TXD2_FIX_RATE; - - txwi[2] |= cpu_to_le32(val); diff --git a/sys-kernel_arch-sources-g14_files-8016-mt76-mt7921-Add-mt7922-support.patch b/sys-kernel_arch-sources-g14_files-8016-mt76-mt7921-Add-mt7922-support.patch deleted file mode 100644 index d11143822c5f..000000000000 --- a/sys-kernel_arch-sources-g14_files-8016-mt76-mt7921-Add-mt7922-support.patch +++ /dev/null @@ -1,221 +0,0 @@ -From ad4ffe33fd9d517ef27e213c6bd9d11675658fe2 Mon Sep 17 00:00:00 2001 -From: Deren Wu <deren.wu@mediatek.com> -Date: Fri, 16 Jul 2021 01:34:19 +0800 -Subject: [PATCH 8014/8014] mt76: mt7921: Add mt7922 support - -Add new chip mt7922 in mt7921 module with following items -1. new chip ID / fw bin name -2. is_mt7922() - check chip type for different fw files -3. mt7921_get_data_mode() - check security type of fw (backward compatible) - -Co-developed-by: Jimmy Hu <Jimmy.Hu@mediatek.com> -Signed-off-by: Jimmy Hu <Jimmy.Hu@mediatek.com> -Signed-off-by: Deren Wu <deren.wu@mediatek.com> ---- - .../net/wireless/mediatek/mt76/mt76_connac.h | 7 +- - .../wireless/mediatek/mt76/mt7921/eeprom.c | 1 + - .../net/wireless/mediatek/mt76/mt7921/mcu.c | 71 +++++++++++++++++-- - .../wireless/mediatek/mt76/mt7921/mt7921.h | 3 + - .../net/wireless/mediatek/mt76/mt7921/pci.c | 3 + - 5 files changed, 80 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h -index 6c889b90fd12..f6e7671fc3be 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h -+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h -@@ -82,9 +82,14 @@ struct mt76_connac_coredump { - - extern const struct wiphy_wowlan_support mt76_connac_wowlan_support; - -+static inline bool is_mt7922(struct mt76_dev *dev) -+{ -+ return mt76_chip(dev) == 0x7922; -+} -+ - static inline bool is_mt7921(struct mt76_dev *dev) - { -- return mt76_chip(dev) == 0x7961; -+ return mt76_chip(dev) == 0x7961 || is_mt7922(dev); - } - - static inline bool is_mt7663(struct mt76_dev *dev) -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c -index 691d14a1a7bf..4d0a4aeac6bf 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c -@@ -36,6 +36,7 @@ static int mt7921_check_eeprom(struct mt7921_dev *dev) - val = get_unaligned_le16(eeprom); - - switch (val) { -+ case 0x7922: - case 0x7961: - return 0; - default: -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -index bc8e3327a49f..798ddfde205a 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -@@ -82,9 +82,17 @@ struct mt7921_fw_region { - #define FW_START_OVERRIDE BIT(0) - #define FW_START_WORKING_PDA_CR4 BIT(2) - -+#define PATCH_SEC_NOT_SUPPORT GENMASK(31, 0) - #define PATCH_SEC_TYPE_MASK GENMASK(15, 0) - #define PATCH_SEC_TYPE_INFO 0x2 - -+#define PATCH_SEC_ENC_TYPE_MASK GENMASK(31, 24) -+#define PATCH_SEC_ENC_TYPE_PLAIN 0x00 -+#define PATCH_SEC_ENC_TYPE_AES 0x01 -+#define PATCH_SEC_ENC_TYPE_SCRAMBLE 0x02 -+#define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK GENMASK(15, 0) -+#define PATCH_SEC_ENC_AES_KEY_MASK GENMASK(7, 0) -+ - #define to_wcid_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id) - #define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id) - -@@ -722,6 +730,46 @@ static int mt7921_driver_own(struct mt7921_dev *dev) - return 0; - } - -+static u32 mt7921_get_data_mode(struct mt7921_dev *dev, u32 info) -+{ -+ u32 mode = DL_MODE_NEED_RSP; -+ -+ if (info == PATCH_SEC_NOT_SUPPORT) -+ return mode; -+ -+ switch (FIELD_GET(PATCH_SEC_ENC_TYPE_MASK, info)) { -+ case PATCH_SEC_ENC_TYPE_PLAIN: -+ break; -+ case PATCH_SEC_ENC_TYPE_AES: -+ mode |= DL_MODE_ENCRYPT; -+ mode |= FIELD_PREP(DL_MODE_KEY_IDX, -+ (info & PATCH_SEC_ENC_AES_KEY_MASK)) & DL_MODE_KEY_IDX; -+ mode |= DL_MODE_RESET_SEC_IV; -+ break; -+ case PATCH_SEC_ENC_TYPE_SCRAMBLE: -+ mode |= DL_MODE_ENCRYPT; -+ mode |= DL_CONFIG_ENCRY_MODE_SEL; -+ mode |= DL_MODE_RESET_SEC_IV; -+ break; -+ default: -+ dev_err(dev->mt76.dev, "Encryption type not support!\n"); -+ } -+ -+ return mode; -+} -+ -+static char *mt7921_patch_name(struct mt7921_dev *dev) -+{ -+ char *ret; -+ -+ if (is_mt7922(&dev->mt76)) -+ ret = MT7922_ROM_PATCH; -+ else -+ ret = MT7921_ROM_PATCH; -+ -+ return ret; -+} -+ - static int mt7921_load_patch(struct mt7921_dev *dev) - { - const struct mt7921_patch_hdr *hdr; -@@ -739,7 +787,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev) - return -EAGAIN; - } - -- ret = request_firmware(&fw, MT7921_ROM_PATCH, dev->mt76.dev); -+ ret = request_firmware(&fw, mt7921_patch_name(dev), dev->mt76.dev); - if (ret) - goto out; - -@@ -757,7 +805,8 @@ static int mt7921_load_patch(struct mt7921_dev *dev) - for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) { - struct mt7921_patch_sec *sec; - const u8 *dl; -- u32 len, addr; -+ u32 len, addr, mode; -+ u32 sec_info = 0; - - sec = (struct mt7921_patch_sec *)(fw->data + sizeof(*hdr) + - i * sizeof(*sec)); -@@ -770,9 +819,11 @@ static int mt7921_load_patch(struct mt7921_dev *dev) - addr = be32_to_cpu(sec->info.addr); - len = be32_to_cpu(sec->info.len); - dl = fw->data + be32_to_cpu(sec->offs); -+ sec_info = be32_to_cpu(sec->info.sec_key_idx); -+ mode = mt7921_get_data_mode(dev, sec_info); - - ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len, -- DL_MODE_NEED_RSP); -+ mode); - if (ret) { - dev_err(dev->mt76.dev, "Download request failed\n"); - goto out; -@@ -869,13 +920,25 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev, - return mt76_connac_mcu_start_firmware(&dev->mt76, override, option); - } - -+static char *mt7921_ram_name(struct mt7921_dev *dev) -+{ -+ char *ret; -+ -+ if (is_mt7922(&dev->mt76)) -+ ret = MT7922_FIRMWARE_WM; -+ else -+ ret = MT7921_FIRMWARE_WM; -+ -+ return ret; -+} -+ - static int mt7921_load_ram(struct mt7921_dev *dev) - { - const struct mt7921_fw_trailer *hdr; - const struct firmware *fw; - int ret; - -- ret = request_firmware(&fw, MT7921_FIRMWARE_WM, dev->mt76.dev); -+ ret = request_firmware(&fw, mt7921_ram_name(dev), dev->mt76.dev); - if (ret) - return ret; - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h -index 59862ea4951c..d8e616229e9f 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h -@@ -33,6 +33,9 @@ - #define MT7921_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7961_1.bin" - #define MT7921_ROM_PATCH "mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin" - -+#define MT7922_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7922_1.bin" -+#define MT7922_ROM_PATCH "mediatek/WIFI_MT7922_patch_mcu_1_1_hdr.bin" -+ - #define MT7921_EEPROM_SIZE 3584 - #define MT7921_TOKEN_SIZE 8192 - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c -index fa02d934f0bf..684d0568a92a 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c -@@ -14,6 +14,7 @@ - - static const struct pci_device_id mt7921_pci_device_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922) }, - { }, - }; - -@@ -317,6 +318,8 @@ module_pci_driver(mt7921_pci_driver); - MODULE_DEVICE_TABLE(pci, mt7921_pci_device_table); - MODULE_FIRMWARE(MT7921_FIRMWARE_WM); - MODULE_FIRMWARE(MT7921_ROM_PATCH); -+MODULE_FIRMWARE(MT7922_FIRMWARE_WM); -+MODULE_FIRMWARE(MT7922_ROM_PATCH); - MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); - MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); - MODULE_LICENSE("Dual BSD/GPL"); --- -2.32.0 - diff --git a/sys-kernel_arch-sources-g14_files-8017-mt76-mt7921-enable-VO-tx-aggregation.patch b/sys-kernel_arch-sources-g14_files-8017-mt76-mt7921-enable-VO-tx-aggregation.patch deleted file mode 100644 index b94147a0fbbe..000000000000 --- a/sys-kernel_arch-sources-g14_files-8017-mt76-mt7921-enable-VO-tx-aggregation.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Deren Wu <Deren.Wu@mediatek.com> -To: Felix Fietkau <nbd@nbd.name>, Lorenzo Bianconi - <lorenzo.bianconi@redhat.com> -CC: Sean Wang <sean.wang@mediatek.com>, Soul Huang <Soul.Huang@mediatek.com>, - YN Chen <YN.Chen@mediatek.com>, Leon Yen <Leon.Yen@mediatek.com>, "Eric-SY - Chang" <Eric-SY.Chang@mediatek.com>, Deren Wu <Deren.Wu@mediatek.com>, - KM Lin <km.lin@mediatek.com>, Robin Chiu <robin.chiu@mediatek.com>, CH Yeh - <ch.yeh@mediatek.com>, Posh Sun <posh.sun@mediatek.com>, Eric Liang - <Eric.Liang@mediatek.com>, Stella Chang <Stella.Chang@mediatek.com>, - <jemele@google.com>, <yenlinlai@google.com>, linux-wireless - <linux-wireless@vger.kernel.org>, linux-mediatek - <linux-mediatek@lists.infradead.org>, Deren Wu <deren.wu@mediatek.com> -Subject: [PATCH] mt76: mt7921: enable VO tx aggregation -Date: Wed, 4 Aug 2021 18:11:53 +0800 - -From: Deren Wu <deren.wu@mediatek.com> - -From: YN Chen <YN.Chen@mediatek.com> - -Avoid throughput drop in VO streaming, enable TX BA by default. - -Signed-off-by: Deren Wu <deren.wu@mediatek.com> -Signed-off-by: YN Chen <YN.Chen@mediatek.com> ---- - drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -index 296e0f7a1d14..1be1e07ae786 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -@@ -913,8 +913,6 @@ mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) - return; - - tid = FIELD_GET(MT_TXD1_TID, le32_to_cpu(txwi[1])); -- if (tid >= 6) /* skip VO queue */ -- return; - - val = le32_to_cpu(txwi[2]); - fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 | diff --git a/sys-kernel_arch-sources-g14_files-8018-mt76-mt7921-fix-dma-hang-in-rmmod.patch b/sys-kernel_arch-sources-g14_files-8018-mt76-mt7921-fix-dma-hang-in-rmmod.patch deleted file mode 100644 index 7b353ab3e5eb..000000000000 --- a/sys-kernel_arch-sources-g14_files-8018-mt76-mt7921-fix-dma-hang-in-rmmod.patch +++ /dev/null @@ -1,55 +0,0 @@ -From: Deren Wu <Deren.Wu@mediatek.com> -To: Felix Fietkau <nbd@nbd.name>, Lorenzo Bianconi - <lorenzo.bianconi@redhat.com> -CC: Sean Wang <sean.wang@mediatek.com>, Soul Huang <Soul.Huang@mediatek.com>, - YN Chen <YN.Chen@mediatek.com>, Leon Yen <Leon.Yen@mediatek.com>, "Eric-SY - Chang" <Eric-SY.Chang@mediatek.com>, Deren Wu <Deren.Wu@mediatek.com>, - KM Lin <km.lin@mediatek.com>, Robin Chiu <robin.chiu@mediatek.com>, CH Yeh - <ch.yeh@mediatek.com>, Posh Sun <posh.sun@mediatek.com>, Eric Liang - <Eric.Liang@mediatek.com>, Stella Chang <Stella.Chang@mediatek.com>, Jimmy Hu - <Jimmy.Hu@mediatek.com>, <jemele@google.com>, <yenlinlai@google.com>, - linux-wireless <linux-wireless@vger.kernel.org>, linux-mediatek - <linux-mediatek@lists.infradead.org>, Deren Wu <deren.wu@mediatek.com> -Subject: [PATCH] mt76: mt7921: fix dma hang in rmmod -Date: Tue, 27 Jul 2021 17:47:09 +0800 - -From: Deren Wu <deren.wu@mediatek.com> - -The dma would be broken after rmmod flow. There are two different -cases causing this issue. -1. dma access without privilege. -2. hw access sequence borken by another context. - -This patch handle both cases to avoid hw crash. - -Fixes: 2b9ea5a8cf1bd ("mt76: mt7921: add mt7921_dma_cleanup in mt7921_unregister_device") -Signed-off-by: Deren Wu <deren.wu@mediatek.com> ---- - drivers/net/wireless/mediatek/mt76/mt7921/init.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -index 49725caca7ed..1f37e64b6038 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -@@ -266,10 +266,20 @@ int mt7921_register_device(struct mt7921_dev *dev) - - void mt7921_unregister_device(struct mt7921_dev *dev) - { -+ int i; -+ struct mt76_connac_pm *pm = &dev->pm; -+ - mt76_unregister_device(&dev->mt76); -+ mt76_for_each_q_rx(&dev->mt76, i) -+ napi_disable(&dev->mt76.napi[i]); -+ cancel_delayed_work_sync(&pm->ps_work); -+ cancel_work_sync(&pm->wake_work); -+ - mt7921_tx_token_put(dev); -+ mt7921_mcu_drv_pmctrl(dev); - mt7921_dma_cleanup(dev); - mt7921_mcu_exit(dev); -+ mt7921_mcu_fw_pmctrl(dev); - - tasklet_disable(&dev->irq_tasklet); - mt76_free_device(&dev->mt76); diff --git a/sys-kernel_arch-sources-g14_files-8019-mt76-mt7921-fix-firmware-usage-of-RA-info-using-legacy-rates.patch b/sys-kernel_arch-sources-g14_files-8019-mt76-mt7921-fix-firmware-usage-of-RA-info-using-legacy-rates.patch deleted file mode 100644 index 870e24a3a1ff..000000000000 --- a/sys-kernel_arch-sources-g14_files-8019-mt76-mt7921-fix-firmware-usage-of-RA-info-using-legacy-rates.patch +++ /dev/null @@ -1,72 +0,0 @@ -From: <sean.wang@mediatek.com> -To: <nbd@nbd.name>, <lorenzo.bianconi@redhat.com> -CC: <sean.wang@mediatek.com>, <Soul.Huang@mediatek.com>, - <YN.Chen@mediatek.com>, <Leon.Yen@mediatek.com>, - <Eric-SY.Chang@mediatek.com>, <Deren.Wu@mediatek.com>, <km.lin@mediatek.com>, - <robin.chiu@mediatek.com>, <ch.yeh@mediatek.com>, <posh.sun@mediatek.com>, - <Eric.Liang@mediatek.com>, <Stella.Chang@mediatek.com>, <jemele@google.com>, - <yenlinlai@google.com>, <linux-wireless@vger.kernel.org>, - <linux-mediatek@lists.infradead.org> -Subject: [PATCH] mt76: mt7921: fix firmware usage of RA info using legacy - rates -Date: Wed, 11 Aug 2021 13:58:24 +0800 - -From: Sean Wang <sean.wang@mediatek.com> - -According to the firmware usage, OFDM rates should fill out bit 6 - 13 -while CCK rates should fill out bit 0 - 3 in legacy field of RA info to -make the rate adaption runs propertly. Otherwise, a unicast frame might be -picking up the unsupported rate to send out. - -Fixes: 1c099ab44727 ("mt76: mt7921: add MCU support") -Reported-by: Joshua Emele <jemele@chromium.org> -Co-developed-by: YN Chen <YN.Chen@mediatek.com> -Signed-off-by: YN Chen <YN.Chen@mediatek.com> -Signed-off-by: Sean Wang <sean.wang@mediatek.com> ---- - drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 11 ++++++++++- - drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h | 2 ++ - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c -index a2555dc0f003..27e45f4fc05f 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c -@@ -719,6 +719,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, - struct sta_rec_state *state; - struct sta_rec_phy *phy; - struct tlv *tlv; -+ u16 supp_rates; - - /* starec ht */ - if (sta->ht_cap.ht_supported) { -@@ -767,7 +768,15 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, - - tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info)); - ra_info = (struct sta_rec_ra_info *)tlv; -- ra_info->legacy = cpu_to_le16((u16)sta->supp_rates[band]); -+ -+ supp_rates = sta->supp_rates[band]; -+ if (band == NL80211_BAND_2GHZ) -+ supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) | -+ FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf); -+ else -+ supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates); -+ -+ ra_info->legacy = cpu_to_le16(supp_rates); - - if (sta->ht_cap.ht_supported) - memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask, -diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h -index ab77289c0541..9dfdf7625844 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h -+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h -@@ -124,6 +124,8 @@ struct sta_rec_state { - u8 rsv[1]; - } __packed; - -+#define RA_LEGACY_OFDM GENMASK(13, 6) -+#define RA_LEGACY_CCK GENMASK(3, 0) - #define HT_MCS_MASK_NUM 10 - struct sta_rec_ra_info { - __le16 tag; diff --git a/sys-kernel_arch-sources-g14_files-8020-mt76-mt7921-Fix-out-of-order-process-by-invalid-even.patch b/sys-kernel_arch-sources-g14_files-8020-mt76-mt7921-Fix-out-of-order-process-by-invalid-even.patch deleted file mode 100644 index e3c25ccae6f9..000000000000 --- a/sys-kernel_arch-sources-g14_files-8020-mt76-mt7921-Fix-out-of-order-process-by-invalid-even.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 8c7b55f401ae8cf172fd9766178ef20cda322e42 Mon Sep 17 00:00:00 2001 -From: Deren Wu <deren.wu@mediatek.com> -Date: Wed, 14 Jul 2021 23:50:52 +0800 -Subject: [PATCH 8013/8014] mt76: mt7921: Fix out of order process by invalid - event pkt - -The acceptable event report should inlcude original CMD-ID. Otherwise, -drop unexpected result from fw. - -Fixes: 1c099ab44727c ("mt76: mt7921: add MCU support") -Signed-off-by: Jimmy Hu <Jimmy.Hu@mediatek.com> -Signed-off-by: Deren Wu <deren.wu@mediatek.com> ---- - drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -index f7459ad2a073..bc8e3327a49f 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -@@ -157,6 +157,7 @@ mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, - struct sk_buff *skb, int seq) - { - struct mt7921_mcu_rxd *rxd; -+ int mcu_cmd = cmd & MCU_CMD_MASK; - int ret = 0; - - if (!skb) { -@@ -194,6 +195,9 @@ mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, - skb_pull(skb, sizeof(*rxd)); - event = (struct mt7921_mcu_uni_event *)skb->data; - ret = le32_to_cpu(event->status); -+ /* skip invalid event */ -+ if (mcu_cmd != event->cid) -+ ret = -EAGAIN; - break; - } - case MCU_CMD_REG_READ: { --- -2.32.0 - diff --git a/sys-kernel_arch-sources-g14_files-8021-mt76-mt7921-fix-the-inconsistent-state-between-bind-and-unbind.patch b/sys-kernel_arch-sources-g14_files-8021-mt76-mt7921-fix-the-inconsistent-state-between-bind-and-unbind.patch deleted file mode 100644 index c1a9eabc6f02..000000000000 --- a/sys-kernel_arch-sources-g14_files-8021-mt76-mt7921-fix-the-inconsistent-state-between-bind-and-unbind.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: <sean.wang@mediatek.com> -To: <nbd@nbd.name>, <lorenzo.bianconi@redhat.com> -CC: <sean.wang@mediatek.com>, <Soul.Huang@mediatek.com>, - <YN.Chen@mediatek.com>, <Leon.Yen@mediatek.com>, - <Eric-SY.Chang@mediatek.com>, <Deren.Wu@mediatek.com>, <km.lin@mediatek.com>, - <robin.chiu@mediatek.com>, <ch.yeh@mediatek.com>, <posh.sun@mediatek.com>, - <Eric.Liang@mediatek.com>, <Stella.Chang@mediatek.com>, <jemele@google.com>, - <linux-wireless@vger.kernel.org>, <linux-mediatek@lists.infradead.org> -Subject: [PATCH] mt76: mt7921: fix the inconsistent state between bind and - unbind -Date: Mon, 23 Aug 2021 10:26:51 +0800 - -From: Sean Wang <sean.wang@mediatek.com> - -We shouldn't put back the device into fw own state after wifi reset at -driver unbind stage to fix the following error because that is not the -consistent state the current driver bind stage expects. - -localhost ~ # echo 0000:01:00.0 > /sys/bus/pci/drivers/mt7921e/unbind -localhost ~ # echo 0000:01:00.0 > /sys/bus/pci/drivers/mt7921e/bind -... -[ 481.172969] mt7921e 0000:01:00.0: ASIC revision: feed0000 -[ 482.133547] mt7921e: probe of 0000:01:00.0 failed with error -110 --bash: echo: write error: No such device - -Fixes: c1af184ba830 ("mt76: mt7921: fix dma hang in rmmod") -Co-developed-by: YN Chen <YN.Chen@mediatek.com> -Signed-off-by: YN Chen <YN.Chen@mediatek.com> -Signed-off-by: Sean Wang <sean.wang@mediatek.com> -Tested-by: Chen-Yu Tsai <wenst@chromium.org> ---- - drivers/net/wireless/mediatek/mt76/mt7921/init.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -index 1f37e64b6038..3e84ef8f5358 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -@@ -279,7 +279,6 @@ void mt7921_unregister_device(struct mt7921_dev *dev) - mt7921_mcu_drv_pmctrl(dev); - mt7921_dma_cleanup(dev); - mt7921_mcu_exit(dev); -- mt7921_mcu_fw_pmctrl(dev); - - tasklet_disable(&dev->irq_tasklet); - mt76_free_device(&dev->mt76); diff --git a/sys-kernel_arch-sources-g14_files-8022-mt76-mt7921-report-HE-MU-radiotap.patch b/sys-kernel_arch-sources-g14_files-8022-mt76-mt7921-report-HE-MU-radiotap.patch deleted file mode 100644 index ebb44077b5f8..000000000000 --- a/sys-kernel_arch-sources-g14_files-8022-mt76-mt7921-report-HE-MU-radiotap.patch +++ /dev/null @@ -1,187 +0,0 @@ -From: <sean.wang@mediatek.com> -To: <nbd@nbd.name>, <lorenzo.bianconi@redhat.com> -CC: <sean.wang@mediatek.com>, <Soul.Huang@mediatek.com>, - <YN.Chen@mediatek.com>, <Leon.Yen@mediatek.com>, - <Eric-SY.Chang@mediatek.com>, <Deren.Wu@mediatek.com>, <km.lin@mediatek.com>, - <robin.chiu@mediatek.com>, <ch.yeh@mediatek.com>, <posh.sun@mediatek.com>, - <Eric.Liang@mediatek.com>, <Stella.Chang@mediatek.com>, <jemele@google.com>, - <yenlinlai@google.com>, <linux-wireless@vger.kernel.org>, - <linux-mediatek@lists.infradead.org>, Ryder Lee <ryder.lee@mediatek.com> -Subject: [PATCH] mt76: mt7921: report HE MU radiotap -Date: Fri, 13 Aug 2021 06:48:24 +0800 - -From: Sean Wang <sean.wang@mediatek.com> - -Report HE MU/BF radiotap. - -That fixed HE MU packets dropped by mac80211 because they are missing the -ieee80211_radiotap_he_mu header. - -Fixes: 163f4d22c118d ("mt76: mt7921: add MAC support") -Co-developed-by: Ryder Lee <ryder.lee@mediatek.com> -Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> -Co-developed-by: Eric-SY Chang <Eric-SY.Chang@mediatek.com> -Signed-off-by: Eric-SY Chang <Eric-SY.Chang@mediatek.com> -Tested-by: Eric-SY Chang <Eric-SY.Chang@mediatek.com> -Signed-off-by: Sean Wang <sean.wang@mediatek.com> ---- - .../net/wireless/mediatek/mt76/mt7921/mac.c | 65 ++++++++++++++++--- - .../net/wireless/mediatek/mt76/mt7921/mac.h | 8 +++ - 2 files changed, 65 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -index 296e0f7a1d14..7ee9ef2fb9f0 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -@@ -180,12 +180,56 @@ mt7921_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, - IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); - } - -+static void -+mt7921_mac_decode_he_mu_radiotap(struct sk_buff *skb, -+ struct mt76_rx_status *status, -+ __le32 *rxv) -+{ -+ static const struct ieee80211_radiotap_he_mu mu_known = { -+ .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | -+ HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | -+ HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | -+ HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN) | -+ HE_BITS(MU_FLAGS1_SIG_B_COMP_KNOWN), -+ .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN) | -+ HE_BITS(MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN), -+ }; -+ struct ieee80211_radiotap_he_mu *he_mu = NULL; -+ -+ he_mu = skb_push(skb, sizeof(mu_known)); -+ memcpy(he_mu, &mu_known, sizeof(mu_known)); -+ -+#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) -+ -+ he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); -+ if (status->he_dcm) -+ he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); -+ -+ he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | -+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS, -+ le32_get_bits(rxv[2], MT_CRXV_HE_NUM_USER)); -+ -+ he_mu->ru_ch1[0] = FIELD_GET(MT_CRXV_HE_RU0, cpu_to_le32(rxv[3])); -+ -+ if (status->bw >= RATE_INFO_BW_40) { -+ he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); -+ he_mu->ru_ch2[0] = -+ FIELD_GET(MT_CRXV_HE_RU1, cpu_to_le32(rxv[3])); -+ } -+ -+ if (status->bw >= RATE_INFO_BW_80) { -+ he_mu->ru_ch1[1] = -+ FIELD_GET(MT_CRXV_HE_RU2, cpu_to_le32(rxv[3])); -+ he_mu->ru_ch2[1] = -+ FIELD_GET(MT_CRXV_HE_RU3, cpu_to_le32(rxv[3])); -+ } -+} -+ - static void - mt7921_mac_decode_he_radiotap(struct sk_buff *skb, - struct mt76_rx_status *status, - __le32 *rxv, u32 phy) - { -- /* TODO: struct ieee80211_radiotap_he_mu */ - static const struct ieee80211_radiotap_he known = { - .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | - HE_BITS(DATA1_DATA_DCM_KNOWN) | -@@ -193,6 +237,7 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb, - HE_BITS(DATA1_CODING_KNOWN) | - HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | - HE_BITS(DATA1_DOPPLER_KNOWN) | -+ HE_BITS(DATA1_SPTL_REUSE_KNOWN) | - HE_BITS(DATA1_BSS_COLOR_KNOWN), - .data2 = HE_BITS(DATA2_GI_KNOWN) | - HE_BITS(DATA2_TXBF_KNOWN) | -@@ -207,9 +252,12 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb, - - he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[14]) | - HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[2]); -+ he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]); - he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) | - le16_encode_bits(ltf_size, - IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); -+ if (cpu_to_le32(rxv[0]) & MT_PRXV_TXBF) -+ he->data5 |= HE_BITS(DATA5_TXBF); - he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) | - HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]); - -@@ -217,8 +265,7 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb, - case MT_PHY_TYPE_HE_SU: - he->data1 |= HE_BITS(DATA1_FORMAT_SU) | - HE_BITS(DATA1_UL_DL_KNOWN) | -- HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | -- HE_BITS(DATA1_SPTL_REUSE_KNOWN); -+ HE_BITS(DATA1_BEAM_CHANGE_KNOWN); - - he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) | - HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); -@@ -232,17 +279,15 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb, - break; - case MT_PHY_TYPE_HE_MU: - he->data1 |= HE_BITS(DATA1_FORMAT_MU) | -- HE_BITS(DATA1_UL_DL_KNOWN) | -- HE_BITS(DATA1_SPTL_REUSE_KNOWN); -+ HE_BITS(DATA1_UL_DL_KNOWN); - - he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); -- he->data4 |= HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]); -+ he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]); - - mt7921_mac_decode_he_radiotap_ru(status, he, rxv); - break; - case MT_PHY_TYPE_HE_TB: - he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | -- HE_BITS(DATA1_SPTL_REUSE_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE4_KNOWN); -@@ -606,9 +651,13 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) - - mt7921_mac_assoc_rssi(dev, skb); - -- if (rxv && status->flag & RX_FLAG_RADIOTAP_HE) -+ if (rxv && status->flag & RX_FLAG_RADIOTAP_HE) { - mt7921_mac_decode_he_radiotap(skb, status, rxv, mode); - -+ if (status->flag & RX_FLAG_RADIOTAP_HE_MU) -+ mt7921_mac_decode_he_mu_radiotap(skb, status, rxv); -+ } -+ - if (!status->wcid || !ieee80211_is_data_qos(fc)) - return 0; - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h -index 3af67fac213d..f0194c878037 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h -@@ -116,6 +116,7 @@ enum rx_pkt_type { - #define MT_PRXV_TX_DCM BIT(4) - #define MT_PRXV_TX_ER_SU_106T BIT(5) - #define MT_PRXV_NSTS GENMASK(9, 7) -+#define MT_PRXV_TXBF BIT(10) - #define MT_PRXV_HT_AD_CODE BIT(11) - #define MT_PRXV_FRAME_MODE GENMASK(14, 12) - #define MT_PRXV_SGI GENMASK(16, 15) -@@ -138,8 +139,15 @@ enum rx_pkt_type { - #define MT_CRXV_HE_LTF_SIZE GENMASK(18, 17) - #define MT_CRXV_HE_LDPC_EXT_SYM BIT(20) - #define MT_CRXV_HE_PE_DISAMBIG BIT(23) -+#define MT_CRXV_HE_NUM_USER GENMASK(30, 24) - #define MT_CRXV_HE_UPLINK BIT(31) - -+#define MT_CRXV_HE_RU0 GENMASK(7, 0) -+#define MT_CRXV_HE_RU1 GENMASK(15, 8) -+#define MT_CRXV_HE_RU2 GENMASK(23, 16) -+#define MT_CRXV_HE_RU3 GENMASK(31, 24) -+#define MT_CRXV_HE_MU_AID GENMASK(30, 20) -+ - #define MT_CRXV_HE_SR_MASK GENMASK(11, 8) - #define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) - #define MT_CRXV_HE_SR2_MASK GENMASK(20, 17) diff --git a/sys-kernel_arch-sources-g14_files-8023-v2-mt76-mt7921-fix-kernel-warning-from-cfg80211_calculate_bitrate.patch b/sys-kernel_arch-sources-g14_files-8023-v2-mt76-mt7921-fix-kernel-warning-from-cfg80211_calculate_bitrate.patch deleted file mode 100644 index b71d4dc6db89..000000000000 --- a/sys-kernel_arch-sources-g14_files-8023-v2-mt76-mt7921-fix-kernel-warning-from-cfg80211_calculate_bitrate.patch +++ /dev/null @@ -1,99 +0,0 @@ -From: <sean.wang@mediatek.com> -To: <nbd@nbd.name>, <lorenzo.bianconi@redhat.com> -CC: <sean.wang@mediatek.com>, <Soul.Huang@mediatek.com>, - <YN.Chen@mediatek.com>, <Leon.Yen@mediatek.com>, - <Eric-SY.Chang@mediatek.com>, <Deren.Wu@mediatek.com>, <km.lin@mediatek.com>, - <robin.chiu@mediatek.com>, <ch.yeh@mediatek.com>, <posh.sun@mediatek.com>, - <Eric.Liang@mediatek.com>, <Stella.Chang@mediatek.com>, <jemele@google.com>, - <yenlinlai@google.com>, <linux-wireless@vger.kernel.org>, - <linux-mediatek@lists.infradead.org> -Subject: [PATCH v2] mt76: mt7921: fix kernel warning from - cfg80211_calculate_bitrate -Date: Sat, 14 Aug 2021 02:09:18 +0800 - -From: Sean Wang <sean.wang@mediatek.com> - -Fix the kernel warning from cfg80211_calculate_bitrate -due to the legacy rate is not parsed well in the current driver. - -Also, zeros struct rate_info before we fill it out to avoid the old value -is kept such as rate->legacy. - -[ 790.921560] WARNING: CPU: 7 PID: 970 at net/wireless/util.c:1298 cfg80211_calculate_bitrate+0x354/0x35c [cfg80211] -[ 790.987738] Hardware name: MediaTek Asurada rev1 board (DT) -[ 790.993298] pstate: a0400009 (NzCv daif +PAN -UAO) -[ 790.998104] pc : cfg80211_calculate_bitrate+0x354/0x35c [cfg80211] -[ 791.004295] lr : cfg80211_calculate_bitrate+0x180/0x35c [cfg80211] -[ 791.010462] sp : ffffffc0129c3880 -[ 791.013765] x29: ffffffc0129c3880 x28: ffffffd38305bea8 -[ 791.019065] x27: ffffffc0129c3970 x26: 0000000000000013 -[ 791.024364] x25: 00000000000003ca x24: 000000000000002f -[ 791.029664] x23: 00000000000000d0 x22: ffffff8d108bc000 -[ 791.034964] x21: ffffff8d108bc0d0 x20: ffffffc0129c39a8 -[ 791.040264] x19: ffffffc0129c39a8 x18: 00000000ffff0a10 -[ 791.045563] x17: 0000000000000050 x16: 00000000000000ec -[ 791.050910] x15: ffffffd3f9ebed9c x14: 0000000000000006 -[ 791.056211] x13: 00000000000b2eea x12: 0000000000000000 -[ 791.061511] x11: 00000000ffffffff x10: 0000000000000000 -[ 791.066811] x9 : 0000000000000000 x8 : 0000000000000000 -[ 791.072110] x7 : 0000000000000000 x6 : ffffffd3fafa5a7b -[ 791.077409] x5 : 0000000000000000 x4 : 0000000000000000 -[ 791.082708] x3 : 0000000000000000 x2 : 0000000000000000 -[ 791.088008] x1 : ffffff8d3f79c918 x0 : 0000000000000000 -[ 791.093308] Call trace: -[ 791.095770] cfg80211_calculate_bitrate+0x354/0x35c [cfg80211] -[ 791.101615] nl80211_put_sta_rate+0x6c/0x2c0 [cfg80211] -[ 791.106853] nl80211_send_station+0x980/0xaa4 [cfg80211] -[ 791.112178] nl80211_get_station+0xb4/0x134 [cfg80211] -[ 791.117308] genl_rcv_msg+0x3a0/0x440 -[ 791.120960] netlink_rcv_skb+0xcc/0x118 -[ 791.124785] genl_rcv+0x34/0x48 -[ 791.127916] netlink_unicast+0x144/0x1dc - -Fixes: 1c099ab44727 ("mt76: mt7921: add MCU support") -Signed-off-by: Sean Wang <sean.wang@mediatek.com> ---- -v2: don't do unnecessary line removal ---- - drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -index cadb633639d3..9b35b5da3619 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -@@ -328,11 +328,13 @@ mt7921_mcu_tx_rate_parse(struct mt76_phy *mphy, - struct rate_info *rate, u16 r) - { - struct ieee80211_supported_band *sband; -- u16 flags = 0; -+ u16 flags = 0, rate_idx; - u8 txmode = FIELD_GET(MT_WTBL_RATE_TX_MODE, r); - u8 gi = 0; - u8 bw = 0; -+ bool cck = false; - -+ memset(rate, 0, sizeof(*rate)); - rate->mcs = FIELD_GET(MT_WTBL_RATE_MCS, r); - rate->nss = FIELD_GET(MT_WTBL_RATE_NSS, r) + 1; - -@@ -357,13 +359,18 @@ mt7921_mcu_tx_rate_parse(struct mt76_phy *mphy, - - switch (txmode) { - case MT_PHY_TYPE_CCK: -+ cck = true; -+ fallthrough; - case MT_PHY_TYPE_OFDM: - if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) - sband = &mphy->sband_5g.sband; - else - sband = &mphy->sband_2g.sband; - -- rate->legacy = sband->bitrates[rate->mcs].bitrate; -+ rate_idx = FIELD_GET(MT_TX_RATE_IDX, r); -+ rate_idx = mt76_get_rate(mphy->dev, sband, rate_idx, -+ cck); -+ rate->legacy = sband->bitrates[rate_idx].bitrate; - break; - case MT_PHY_TYPE_HT: - case MT_PHY_TYPE_HT_GF: diff --git a/sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch b/sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch deleted file mode 100644 index b6011f06913f..000000000000 --- a/sys-kernel_arch-sources-g14_files-8024-mediatek-more-bt-patches.patch +++ /dev/null @@ -1,60 +0,0 @@ -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index a9855a2dd561..b71dbb2c9f5e 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -411,6 +411,9 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK}, - - /* Additional MediaTek MT7921 Bluetooth devices */ -+ { USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - { USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, - -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index b71dbb2c9f5e..e2a6f0c99e3f 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -417,6 +417,9 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - - /* Additional Realtek 8723AE Bluetooth devices */ - { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, - - -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index 1e5cac6f071b..7b69a97bd0e9 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -422,6 +422,9 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x13d3, 0x3563), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - - /* Additional Realtek 8723AE Bluetooth devices */ - { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, - -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index 66c8f3cdc0c0..cd961d5977d3 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -410,6 +410,9 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x13d3, 0x3563), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, diff --git a/sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch b/sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/sys-kernel_arch-sources-g14_files-9001-v5.14.6-s0ix-patch-2021-09-18.patch +++ /dev/null diff --git a/sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch b/sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch deleted file mode 100644 index b623f875f138..000000000000 --- a/sys-kernel_arch-sources-g14_files-9001-v5.14.9-s0ix-patch-2021-10-01.patch +++ /dev/null @@ -1,492 +0,0 @@ -From 6b1881a52169644ae314fa082a2c4daa152c46b3 Mon Sep 17 00:00:00 2001 -From: Scott B <arglebargle@arglebargle.dev> -Date: Fri, 1 Oct 2021 08:26:54 -0700 -Subject: [PATCH] v5.14.9 s0ix patch 2021-10-01 - -Squashed commit of the following: - -commit 9d22c6f69dce036dab2a4d17911bc2ce84df9537 -Author: Lijo Lazar <lijo.lazar@amd.com> -Date: Fri Oct 1 18:16:25 2021 +0800 - - drm/amdgpu: During s0ix don't wait to signal GFXOFF - - In the rare event when GFX IP suspend coincides with a s0ix entry, don't - schedule a delayed work, instead signal PMFW immediately to allow GFXOFF - entry. GFXOFF is a prerequisite for s0ix entry. PMFW needs to be - signaled about GFXOFF status before amd-pmc module passes OS HINT - to PMFW telling that everything is ready for a safe s0ix entry. - - Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1712 - - Signed-off-by: Lijo Lazar <lijo.lazar@amd.com> - Reviewed-by: Alex Deucher <alexander.deucher@amd.com> - Reviewed-by: Mario Limonciello <mario.limonciell@amd.com> - -commit 0c5d3b01b4d999992439ca9f749e202cc0cc8578 -Author: Sanket Goswami <Sanket.Goswami@amd.com> -Date: Tue Sep 21 17:30:20 2021 +0530 - - platform/x86: amd-pmc: Add a message to print resume time info - - Add a message to print the resume time information obtained from the - smu_metrics structure. - - Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> - Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com> - -commit bae72b8e72aac7590d2677830926d960e72edade -Author: Sanket Goswami <Sanket.Goswami@amd.com> -Date: Tue Sep 21 17:29:10 2021 +0530 - - platform/x86: amd-pmc: Send command to dump data after clearing OS_HINT - - It was reported that the resume stats received from the firmware are - always zero. This happens because the SMU expects the driver to send the - command to dump the log data after clearing the OS_HINT. - - Adjust the order of the commands sent to SMU. - - Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> - Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com> - -commit 6e5d6b64bff6e2a863cae9b22c5f5a8f7f7462ff -Author: Sanket Goswami <Sanket.Goswami@amd.com> -Date: Thu Sep 16 18:11:30 2021 +0530 - - platform/x86: amd-pmc: Check s0i3 cycle status - - As the PM firmware returns the status of the last s0i3 in the smu_metrics - structure, the existing name "s0i3_cyclecount" seems to be a misnomer. - Change it accordingly to "s0i3_last_entry_status". - - Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com> - Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> - -commit fdf1b62b3ad1a54a041ebf49ba9b081deb8a6634 -Author: Sanket Goswami <Sanket.Goswami@amd.com> -Date: Thu Sep 16 18:10:02 2021 +0530 - - platform/x86: amd-pmc: Export Idlemask values based on the APU - - IdleMask is the metric used by the PM firmware to know the status of each - of the Hardware IP blocks monitored by the PM firmware. - - Knowing this value is key to get the information of s2idle suspend/resume - status. This value is mapped to PMC scratch registers, retrieve them - accordingly based on the CPU family and the underlying firmware support. - - Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> - Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> - Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com> - Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> - Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> - -commit 994c36c63556c54eaa3f02ea8b7e5b28fc1836cf -Author: Mario Limonciello <mario.limonciello@amd.com> -Date: Wed Sep 15 16:52:16 2021 -0500 - - ACPI: processor idle: Allow playing dead in C3 - - commit 1a022e3f1be1 ("idle, x86: Allow off-lined CPU to enter - deeper C states") originally allowed offlined CPUs to play dead - up to ACPI C2. Although this improves power consumption of offlined - CPUs, it does not allow the CPUs to get into the deepest state - on AMD platforms blocking s0i3 entry. - - BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1708 - Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> - -commit ffa37ed37e917dfa225598dcef8a86324784a4ff -Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com> -Date: Tue Aug 31 17:36:12 2021 +0530 - - pinctrl: amd: Add irq field data - - pinctrl_amd use gpiochip_get_data() to get their local state containers - back from the gpiochip passed as amd_gpio chip data. - - Hence added irq field data to get directly using amd_gpio chip data. - - Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> - -commit b6c769a9687c626c8e068215035975b57fe954e8 -Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com> -Date: Tue Aug 31 17:36:13 2021 +0530 - - pinctrl: amd: Handle wake-up interrupt - - Enable/disable power management wakeup mode, which is disabled by - default. enable_irq_wake enables wakes the system from sleep. - - Hence added enable/disable irq_wake to handle wake-up interrupt. - - Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> - -commit 1fef466dd8e750ea6c86803277226cfee04df5d5 -Author: Scott B <28817345+foundObjects@users.noreply.github.com> -Date: Wed Jul 21 18:10:28 2021 -0700 - - DEBUG: amd-pmc smu register dump for diagnostics - - patch this per Mario's request: - https://gitlab.freedesktop.org/drm/amd/-/issues/1629#note_1000332 - -commit 497175cc42db2ec66a9c17687c15eb8c45644c2c -Author: Scott B <28817345+foundObjects@users.noreply.github.com> -Date: Tue Jul 20 23:33:01 2021 -0700 - - drm/amd/pm: Add information about SMU12 firmware version - - hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066835.html - - This information is useful for root causing issues with S0ix. - - Signed-off-by: Mario Limonciello <mario.limonciello at amd.com> - -commit 07447fae7c12ba3d9c014cfbb69ebda8fe0b4239 -Author: Scott B <28817345+foundObjects@users.noreply.github.com> -Date: Tue Jul 20 23:31:31 2021 -0700 - - drm/amd/pm: Add information about SMU11 firmware version - - hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066834.html - - This information is useful for root causing issues with S0ix. - - Signed-off-by: Mario Limonciello <mario.limonciello at amd.com> ---- - drivers/acpi/processor_idle.c | 3 +- - drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 14 ++- - .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 3 + - .../gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c | 3 + - drivers/pinctrl/pinctrl-amd.c | 19 ++-- - drivers/pinctrl/pinctrl-amd.h | 1 + - drivers/platform/x86/amd-pmc.c | 90 +++++++++++++++++-- - 7 files changed, 120 insertions(+), 13 deletions(-) - -diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c -index 095c8aca141e..1b6529396371 100644 ---- a/drivers/acpi/processor_idle.c -+++ b/drivers/acpi/processor_idle.c -@@ -789,7 +789,8 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr) - state->enter = acpi_idle_enter; - - state->flags = 0; -- if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) { -+ if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2 -+ || cx->type == ACPI_STATE_C3) { - state->enter_dead = acpi_idle_play_dead; - drv->safe_state_index = count; - } -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -index b4ced45301be..1795d448c700 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -@@ -31,6 +31,8 @@ - /* delay 0.1 second to enable gfx off feature */ - #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100) - -+#define GFX_OFF_NO_DELAY 0 -+ - /* - * GPU GFX IP block helpers function. - */ -@@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev) - - void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) - { -+ unsigned long delay = GFX_OFF_DELAY_ENABLE; -+ - if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) - return; - -@@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) - - adev->gfx.gfx_off_req_count--; - -- if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) -- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); -+ if (adev->gfx.gfx_off_req_count == 0 && -+ !adev->gfx.gfx_off_state) { -+ /* If going to s2idle, no need to wait */ -+ if (adev->in_s0ix) -+ delay = GFX_OFF_NO_DELAY; -+ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, -+ delay); -+ } - } else { - if (adev->gfx.gfx_off_req_count == 0) { - cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c -index 0a5d46ac9ccd..626d7c2bdf66 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c -@@ -272,6 +272,9 @@ int smu_v11_0_check_fw_version(struct smu_context *smu) - break; - } - -+ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n", -+ smu_version, smu_major, smu_minor, smu_debug); -+ - /* - * 1. if_version mismatch is not critical as our fw is designed - * to be backward compatible. -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c -index d60b8c5e8715..00ebc381a605 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c -@@ -88,6 +88,9 @@ int smu_v12_0_check_fw_version(struct smu_context *smu) - if (smu->is_apu) - adev->pm.fw_version = smu_version; - -+ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n", -+ smu_version, smu_major, smu_minor, smu_debug); -+ - /* - * 1. if_version mismatch is not critical as our fw is designed - * to be backward compatible. -diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c -index 5b764740b829..d19974aceb2e 100644 ---- a/drivers/pinctrl/pinctrl-amd.c -+++ b/drivers/pinctrl/pinctrl-amd.c -@@ -445,6 +445,7 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on) - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct amd_gpio *gpio_dev = gpiochip_get_data(gc); - u32 wake_mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3); -+ int err; - - raw_spin_lock_irqsave(&gpio_dev->lock, flags); - pin_reg = readl(gpio_dev->base + (d->hwirq)*4); -@@ -457,6 +458,15 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on) - writel(pin_reg, gpio_dev->base + (d->hwirq)*4); - raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); - -+ if (on) -+ err = enable_irq_wake(gpio_dev->irq); -+ else -+ err = disable_irq_wake(gpio_dev->irq); -+ -+ if (err) -+ dev_err(&gpio_dev->pdev->dev, "failed to %s wake-up interrupt\n", -+ on ? "enable" : "disable"); -+ - return 0; - } - -@@ -904,7 +914,6 @@ static struct pinctrl_desc amd_pinctrl_desc = { - static int amd_gpio_probe(struct platform_device *pdev) - { - int ret = 0; -- int irq_base; - struct resource *res; - struct amd_gpio *gpio_dev; - struct gpio_irq_chip *girq; -@@ -927,9 +936,9 @@ static int amd_gpio_probe(struct platform_device *pdev) - if (!gpio_dev->base) - return -ENOMEM; - -- irq_base = platform_get_irq(pdev, 0); -- if (irq_base < 0) -- return irq_base; -+ gpio_dev->irq = platform_get_irq(pdev, 0); -+ if (gpio_dev->irq < 0) -+ return gpio_dev->irq; - - #ifdef CONFIG_PM_SLEEP - gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins, -@@ -989,7 +998,7 @@ static int amd_gpio_probe(struct platform_device *pdev) - goto out2; - } - -- ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, -+ ret = devm_request_irq(&pdev->dev, gpio_dev->irq, amd_gpio_irq_handler, - IRQF_SHARED, KBUILD_MODNAME, gpio_dev); - if (ret) - goto out2; -diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h -index 95e763424042..1d4317073654 100644 ---- a/drivers/pinctrl/pinctrl-amd.h -+++ b/drivers/pinctrl/pinctrl-amd.h -@@ -98,6 +98,7 @@ struct amd_gpio { - struct resource *res; - struct platform_device *pdev; - u32 *saved_regs; -+ int irq; - }; - - /* KERNCZ configuration*/ -diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c -index d6a7c896ac86..81b000241648 100644 ---- a/drivers/platform/x86/amd-pmc.c -+++ b/drivers/platform/x86/amd-pmc.c -@@ -29,6 +29,10 @@ - #define AMD_PMC_REGISTER_RESPONSE 0x980 - #define AMD_PMC_REGISTER_ARGUMENT 0x9BC - -+/* PMC Scratch Registers */ -+#define AMD_PMC_SCRATCH_REG_CZN 0x94 -+#define AMD_PMC_SCRATCH_REG_YC 0xD14 -+ - /* Base address of SMU for mapping physical address to virtual address */ - #define AMD_PMC_SMU_INDEX_ADDRESS 0xB8 - #define AMD_PMC_SMU_INDEX_DATA 0xBC -@@ -110,6 +114,10 @@ struct amd_pmc_dev { - u32 base_addr; - u32 cpu_id; - u32 active_ips; -+/* SMU version information */ -+ u16 major; -+ u16 minor; -+ u16 rev; - struct device *dev; - struct mutex lock; /* generic mutex lock */ - #if IS_ENABLED(CONFIG_DEBUG_FS) -@@ -133,7 +141,7 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3 - struct smu_metrics { - u32 table_version; - u32 hint_count; -- u32 s0i3_cyclecount; -+ u32 s0i3_last_entry_status; - u32 timein_s0i2; - u64 timeentering_s0i3_lastcapture; - u64 timeentering_s0i3_totaltime; -@@ -162,9 +170,12 @@ static int smu_fw_info_show(struct seq_file *s, void *unused) - seq_puts(s, "\n=== SMU Statistics ===\n"); - seq_printf(s, "Table Version: %d\n", table.table_version); - seq_printf(s, "Hint Count: %d\n", table.hint_count); -- seq_printf(s, "S0i3 Cycle Count: %d\n", table.s0i3_cyclecount); -+ seq_printf(s, "Last S0i3 Status: %s\n", table.s0i3_last_entry_status ? "Success" : -+ "Unknown/Fail"); - seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture); - seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture); -+ seq_printf(s, "Time (in us) to resume from S0i3: %lld\n", -+ table.timeto_resume_to_os_lastcapture); - - seq_puts(s, "\n=== Active time (in us) ===\n"); - for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) { -@@ -201,6 +212,66 @@ static int s0ix_stats_show(struct seq_file *s, void *unused) - } - DEFINE_SHOW_ATTRIBUTE(s0ix_stats); - -+static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev) -+{ -+ int rc; -+ u32 val; -+ -+ rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, 1); -+ if (rc) -+ return rc; -+ -+ dev->major = (val >> 16) & GENMASK(15, 0); -+ dev->minor = (val >> 8) & GENMASK(7, 0); -+ dev->rev = (val >> 0) & GENMASK(7, 0); -+ -+ dev_dbg(dev->dev, "SMU version is %u.%u.%u\n", dev->major, dev->minor, dev->rev); -+ -+ return 0; -+} -+ -+static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev, -+ struct seq_file *s) -+{ -+ u32 val; -+ -+ switch (pdev->cpu_id) { -+ case AMD_CPU_ID_CZN: -+ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN); -+ break; -+ case AMD_CPU_ID_YC: -+ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (dev) -+ dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val); -+ -+ if (s) -+ seq_printf(s, "SMU idlemask : 0x%x\n", val); -+ -+ return 0; -+} -+ -+static int amd_pmc_idlemask_show(struct seq_file *s, void *unused) -+{ -+ struct amd_pmc_dev *dev = s->private; -+ int rc; -+ -+ if (dev->major > 56 || (dev->major >= 55 && dev->minor >= 37)) { -+ rc = amd_pmc_idlemask_read(dev, NULL, s); -+ if (rc) -+ return rc; -+ } else { -+ seq_puts(s, "Unsupported SMU version for Idlemask\n"); -+ } -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(amd_pmc_idlemask); -+ - static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev) - { - debugfs_remove_recursive(dev->dbgfs_dir); -@@ -213,6 +284,8 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev) - &smu_fw_info_fops); - debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev, - &s0ix_stats_fops); -+ debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev, -+ &amd_pmc_idlemask_fops); - } - #else - static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev) -@@ -270,6 +343,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg - u32 val; - - mutex_lock(&dev->lock); -+ amd_pmc_dump_registers(dev); - /* Wait until we get a valid response */ - rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE, - val, val != 0, PMC_MSG_DELAY_MIN_US, -@@ -349,6 +423,8 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev) - amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_RESET, 0); - amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_START, 0); - -+ /* Dump the IdleMask before we send hint to SMU */ -+ amd_pmc_idlemask_read(pdev, dev, NULL); - msg = amd_pmc_get_os_hint(pdev); - rc = amd_pmc_send_cmd(pdev, 1, NULL, msg, 0); - if (rc) -@@ -363,14 +439,17 @@ static int __maybe_unused amd_pmc_resume(struct device *dev) - int rc; - u8 msg; - -- /* Let SMU know that we are looking for stats */ -- amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0); -- - msg = amd_pmc_get_os_hint(pdev); - rc = amd_pmc_send_cmd(pdev, 0, NULL, msg, 0); - if (rc) - dev_err(pdev->dev, "resume failed\n"); - -+ /* Let SMU know that we are looking for stats */ -+ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0); -+ -+ /* Dump the IdleMask to see the blockers */ -+ amd_pmc_idlemask_read(pdev, dev, NULL); -+ - return 0; - } - -@@ -457,6 +536,7 @@ static int amd_pmc_probe(struct platform_device *pdev) - if (err) - dev_err(dev->dev, "SMU debugging info not supported on this platform\n"); - -+ amd_pmc_get_smu_version(dev); - platform_set_drvdata(pdev, dev); - amd_pmc_dbgfs_register(dev); - return 0; --- -2.33.0 - diff --git a/sys-kernel_arch-sources-g14_files-9004-HID-asus-Reduce-object-size-by-consolidating-calls.patch b/sys-kernel_arch-sources-g14_files-9004-HID-asus-Reduce-object-size-by-consolidating-calls.patch deleted file mode 100644 index 761b6bcae9ef..000000000000 --- a/sys-kernel_arch-sources-g14_files-9004-HID-asus-Reduce-object-size-by-consolidating-calls.patch +++ /dev/null @@ -1,190 +0,0 @@ -From patchwork Sat May 29 16:29:48 2021 -Message-ID: <56767df55117cc5834b0021ba2c056272e686804.camel@perches.com> -Subject: [PATCH] HID: asus: Reduce object size by consolidating calls -From: Joe Perches <joe@perches.com> -To: Jiri Kosina <jikos@kernel.org>, - Benjamin Tissoires <benjamin.tissoires@redhat.com> -Cc: linux-input <linux-input@vger.kernel.org>, - LKML <linux-kernel@vger.kernel.org> -Date: Sat, 29 May 2021 09:29:48 -0700 -List-ID: <linux-input.vger.kernel.org> -X-Mailing-List: linux-input@vger.kernel.org - -Add intermediating lookup functions to avoid repetitive calls. - -Reduces object size ~4kb (x86-64 defconfig w/ hid-asus) - -$ size drivers/hid/hid-asus.o* - text data bss dec hex filename - 10442 468 0 10910 2a9e drivers/hid/hid-asus.o.bew - 14523 468 0 14991 3a8f drivers/hid/hid-asus.o.old - -Miscellanea: - -o Remove now unused asus_map_kay_clear macro - -Signed-off-by: Joe Perches <joe@perches.com> ---- - -untested, no hardware - - drivers/hid/hid-asus.c | 128 ++++++++++++++++++++++++------------------------- - 1 file changed, 64 insertions(+), 64 deletions(-) - -diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c -index fca8fc78a78a3..5b78e6c3bb5d9 100644 ---- a/drivers/hid/hid-asus.c -+++ b/drivers/hid/hid-asus.c -@@ -811,8 +811,58 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) - return 0; - } - --#define asus_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, \ -- max, EV_KEY, (c)) -+static int asus_map_use_to_btn(int use) -+{ -+ switch (use) { -+ case 0x10: return KEY_BRIGHTNESSDOWN; -+ case 0x20: return KEY_BRIGHTNESSUP; -+ case 0x35: return KEY_DISPLAY_OFF; -+ case 0x6c: return KEY_SLEEP; -+ case 0x7c: return KEY_MICMUTE; -+ case 0x82: return KEY_CAMERA; -+ case 0x88: return KEY_RFKILL; -+ case 0xb5: return KEY_CALC; -+ case 0xc4: return KEY_KBDILLUMUP; -+ case 0xc5: return KEY_KBDILLUMDOWN; -+ case 0x6b: return KEY_F21; /* ASUS touchpad toggle */ -+ case 0x38: return KEY_PROG1; /* ROG key */ -+ case 0xba: return KEY_PROG2; /* Fn+C ASUS Splendid */ -+ case 0x5c: return KEY_PROG3; /* Fn+Space Power4Gear Hybrid */ -+ case 0x99: return KEY_PROG4; /* Fn+F5 "fan" symbol on FX503VD */ -+ /* for N-Key keyboard */ -+ case 0xae: return KEY_PROG4; /* Fn+F5 "fan" symbol */ -+ case 0x92: return KEY_CALC; /* Fn+Ret "Calc" symbol */ -+ case 0xb2: return KEY_PROG2; /* Fn+Left Aura mode previous */ -+ case 0xb3: return KEY_PROG3; /* Fn+Right Aura mode next */ -+ } -+ -+ return 0; -+} -+ -+static int ms_map_use_to_btn(int use) -+{ -+ switch (use) { -+ case 0xff01: return BTN_1; -+ case 0xff02: return BTN_2; -+ case 0xff03: return BTN_3; -+ case 0xff04: return BTN_4; -+ case 0xff05: return BTN_5; -+ case 0xff06: return BTN_6; -+ case 0xff07: return BTN_7; -+ case 0xff08: return BTN_8; -+ case 0xff09: return BTN_9; -+ case 0xff0a: return BTN_A; -+ case 0xff0b: return BTN_B; -+ case 0x00f1: return KEY_WLAN; -+ case 0x00f2: return KEY_BRIGHTNESSDOWN; -+ case 0x00f3: return KEY_BRIGHTNESSUP; -+ case 0x00f4: return KEY_DISPLAY_OFF; -+ case 0x00f7: return KEY_CAMERA; -+ case 0x00f8: return KEY_PROG1; -+ } -+ -+ return 0; -+} - static int asus_input_mapping(struct hid_device *hdev, - struct hid_input *hi, struct hid_field *field, - struct hid_usage *usage, unsigned long **bit, -@@ -842,50 +892,16 @@ static int asus_input_mapping(struct hid_device *hdev, - - /* ASUS-specific keyboard hotkeys and led backlight */ - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_ASUSVENDOR) { -- switch (usage->hid & HID_USAGE) { -- case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break; -- case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break; -- case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF); break; -- case 0x6c: asus_map_key_clear(KEY_SLEEP); break; -- case 0x7c: asus_map_key_clear(KEY_MICMUTE); break; -- case 0x82: asus_map_key_clear(KEY_CAMERA); break; -- case 0x88: asus_map_key_clear(KEY_RFKILL); break; -- case 0xb5: asus_map_key_clear(KEY_CALC); break; -- case 0xc4: asus_map_key_clear(KEY_KBDILLUMUP); break; -- case 0xc5: asus_map_key_clear(KEY_KBDILLUMDOWN); break; -- -- /* ASUS touchpad toggle */ -- case 0x6b: asus_map_key_clear(KEY_F21); break; -- -- /* ROG key */ -- case 0x38: asus_map_key_clear(KEY_PROG1); break; -- -- /* Fn+C ASUS Splendid */ -- case 0xba: asus_map_key_clear(KEY_PROG2); break; -+ int btn = asus_map_use_to_btn(usage->hid & HID_USAGE); - -- /* Fn+Space Power4Gear Hybrid */ -- case 0x5c: asus_map_key_clear(KEY_PROG3); break; -- -- /* Fn+F5 "fan" symbol on FX503VD */ -- case 0x99: asus_map_key_clear(KEY_PROG4); break; -- -- /* Fn+F5 "fan" symbol on N-Key keyboard */ -- case 0xae: asus_map_key_clear(KEY_PROG4); break; -- -- /* Fn+Ret "Calc" symbol on N-Key keyboard */ -- case 0x92: asus_map_key_clear(KEY_CALC); break; -- -- /* Fn+Left Aura mode previous on N-Key keyboard */ -- case 0xb2: asus_map_key_clear(KEY_PROG2); break; -- -- /* Fn+Right Aura mode next on N-Key keyboard */ -- case 0xb3: asus_map_key_clear(KEY_PROG3); break; -- -- default: -- /* ASUS lazily declares 256 usages, ignore the rest, -- * as some make the keyboard appear as a pointer device. */ -+ /* -+ * ASUS lazily declares 256 usages, ignore the rest, -+ * as some make the keyboard appear as a pointer device. -+ */ -+ if (!btn) - return -1; -- } -+ -+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, btn); - - /* - * Check and enable backlight only on devices with UsagePage == -@@ -901,28 +917,12 @@ static int asus_input_mapping(struct hid_device *hdev, - } - - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) { -- switch (usage->hid & HID_USAGE) { -- case 0xff01: asus_map_key_clear(BTN_1); break; -- case 0xff02: asus_map_key_clear(BTN_2); break; -- case 0xff03: asus_map_key_clear(BTN_3); break; -- case 0xff04: asus_map_key_clear(BTN_4); break; -- case 0xff05: asus_map_key_clear(BTN_5); break; -- case 0xff06: asus_map_key_clear(BTN_6); break; -- case 0xff07: asus_map_key_clear(BTN_7); break; -- case 0xff08: asus_map_key_clear(BTN_8); break; -- case 0xff09: asus_map_key_clear(BTN_9); break; -- case 0xff0a: asus_map_key_clear(BTN_A); break; -- case 0xff0b: asus_map_key_clear(BTN_B); break; -- case 0x00f1: asus_map_key_clear(KEY_WLAN); break; -- case 0x00f2: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break; -- case 0x00f3: asus_map_key_clear(KEY_BRIGHTNESSUP); break; -- case 0x00f4: asus_map_key_clear(KEY_DISPLAY_OFF); break; -- case 0x00f7: asus_map_key_clear(KEY_CAMERA); break; -- case 0x00f8: asus_map_key_clear(KEY_PROG1); break; -- default: -+ int btn = ms_map_use_to_btn(usage->hid & HID_USAGE); -+ -+ if (!btn) - return 0; -- } - -+ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, btn); - set_bit(EV_REP, hi->input->evbit); - return 1; - } diff --git a/sys-kernel_arch-sources-g14_files-9005-acpi-battery-Always-read-fresh-battery-state-on-update.patch b/sys-kernel_arch-sources-g14_files-9005-acpi-battery-Always-read-fresh-battery-state-on-update.patch deleted file mode 100644 index 04c52a5eab02..000000000000 --- a/sys-kernel_arch-sources-g14_files-9005-acpi-battery-Always-read-fresh-battery-state-on-update.patch +++ /dev/null @@ -1,38 +0,0 @@ -From patchwork Thu Jun 4 19:56:58 2020 -From: Mathew King <mathewk@chromium.org> -To: linux-kernel@vger.kernel.org -Cc: Mathew King <mathewk@chromium.org>, - "Rafael J. Wysocki" <rjw@rjwysocki.net>, - Len Brown <lenb@kernel.org>, linux-acpi@vger.kernel.org -Subject: [PATCH] acpi: battery: Always read fresh battery state on update -Date: Thu, 4 Jun 2020 13:56:58 -0600 -Message-Id: <20200604195658.66201-1-mathewk@chromium.org> -List-ID: <linux-acpi.vger.kernel.org> -X-Mailing-List: linux-acpi@vger.kernel.org - -When the ACPI battery receives a notification event it should always -read the battery state fresh from the ACPI device and not use the cached -state. Currently the cached state stays valid and the new state may not -be read when a notification occurs. This can lead to a udev event -showing that the battery has changed but the sysfs state will still have -the cached state values. This change invalidates the update time forcing -the state to be updated before notifying the power_supply subsystem of -the change. - -Signed-off-by: Mathew King <mathewk@chromium.org> ---- - drivers/acpi/battery.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c -index 366c389175d8..ab7fa4879fbe 100644 ---- a/drivers/acpi/battery.c -+++ b/drivers/acpi/battery.c -@@ -981,6 +981,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) - acpi_battery_init_alarm(battery); - } - -+ battery->update_time = 0; - result = acpi_battery_get_state(battery); - if (result) - return result; diff --git a/sys-kernel_arch-sources-g14_files-9006-amd-c3-entry.patch b/sys-kernel_arch-sources-g14_files-9006-amd-c3-entry.patch deleted file mode 100644 index 98000fd7211f..000000000000 --- a/sys-kernel_arch-sources-g14_files-9006-amd-c3-entry.patch +++ /dev/null @@ -1,38 +0,0 @@ -AMD CPU which support C3 shares cache. Its not necessary to flush the -caches in software before entering C3. This will cause performance drop -for the cores which share some caches. ARB_DIS is not used with current -AMD C state implementation. So set related flags correctly. - -Signed-off-by: Deepak Sharma <deepak.sharma@amd.com> ---- - arch/x86/kernel/acpi/cstate.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c -index 7de599eba7f0..62a5986d625a 100644 ---- a/arch/x86/kernel/acpi/cstate.c -+++ b/arch/x86/kernel/acpi/cstate.c -@@ -79,6 +79,21 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, - */ - flags->bm_control = 0; - } -+ if (c->x86_vendor == X86_VENDOR_AMD) { -+ /* -+ * For all AMD CPUs that support C3, caches should not be -+ * flushed by software while entering C3 type state. Set -+ * bm->check to 1 so that kernel doesn't need to execute -+ * cache flush operation. -+ */ -+ flags->bm_check = 1; -+ /* -+ * In current AMD C state implementation ARB_DIS is no longer -+ * used. So set bm_control to zero to indicate ARB_DIS is not -+ * required while entering C3 type state. -+ */ -+ flags->bm_control = 0; -+ } - } - EXPORT_SYMBOL(acpi_processor_power_init_bm_check); - --- -2.25.1
\ No newline at end of file diff --git a/sys-kernel_arch-sources-g14_files-9007-squashed-net-tcp_bbr-bbr2-for-5.14.y.patch b/sys-kernel_arch-sources-g14_files-9007-squashed-net-tcp_bbr-bbr2-for-5.14.y.patch deleted file mode 100644 index 4a242b28eda1..000000000000 --- a/sys-kernel_arch-sources-g14_files-9007-squashed-net-tcp_bbr-bbr2-for-5.14.y.patch +++ /dev/null @@ -1,3907 +0,0 @@ -From a0b13b7aa7bef3ed8ced3bcca60e3f7eac489f97 Mon Sep 17 00:00:00 2001 -From: Scott B <arglebargle@arglebargle.dev> -Date: Sat, 4 Sep 2021 11:58:54 -0700 -Subject: [PATCH] net-tcp_bbr: bbr2 for 5.14 - -Squashed commit of the following: - -commit c44f6342dddc77fe7949fa655f38dba626089e8e -Author: Adithya Abraham Philip <abrahamphilip@google.com> -Date: Fri Jun 11 21:56:10 2021 +0000 - - net-tcp_bbr: v2: Fix missing ECT markings on retransmits for BBRv2 - - Adds a new flag TCP_ECN_ECT_PERMANENT that is used by CCAs to - indicate that retransmitted packets and pure ACKs must have the - ECT bit set. This is a necessary fix for BBRv2, which when using - ECN expects ECT to be set even on retransmitted packets and ACKs. - Currently CCAs like BBRv2 which can use ECN but don't "need" it - do not have a way to indicate that ECT should be set on - retransmissions/ACKs. - - Signed-off-by: Adithya Abraham Philip <abrahamphilip@google.com> - Signed-off-by: Neal Cardwell <ncardwell@google.com> - -commit d7b290e75dfc3c6418efdd335a1426444f05a844 -Author: Neal Cardwell <ncardwell@google.com> -Date: Mon Dec 28 19:23:09 2020 -0500 - - net-tcp_bbr: v2: don't assume prior_cwnd was set entering CA_Loss - - Fix WARN_ON_ONCE() warnings that were firing and pointing to a - bbr->prior_cwnd of 0 when exiting CA_Loss and transitioning to - CA_Open. - - The issue was that tcp_simple_retransmit() calls: - - tcp_set_ca_state(sk, TCP_CA_Loss); - - without first calling icsk_ca_ops->ssthresh(sk) (because - tcp_simple_retransmit() is dealing with losses due to MTU issues and - not congestion). The lack of this callback means that BBR did not get - a chance to set bbr->prior_cwnd, and thus upon exiting CA_Loss in such - cases the WARN_ON_ONCE() would fire due to a zero bbr->prior_cwnd. - - This commit removes that warning, since a bbr->prior_cwnd of 0 is a - valid situation in this state transition. - - For setting inflight_lo upon entering CA_Loss, to avoid setting an - inflight_lo of 0 in this case, this commit switches to taking the max - of cwnd and prior_cwnd. We plan to remove that line of code when we - switch to cautious (PRR-style) recovery, so that awkwardness will go - away. - - Change-Id: I575dce871c2f20e91e3e9449e1706f42a07b8118 - -commit e9a0a3e20cd9ae66a7953f3acbd868888cb07109 -Author: Neal Cardwell <ncardwell@google.com> -Date: Mon Aug 17 19:10:21 2020 -0400 - - net-tcp_bbr: v2: remove cycle_rand parameter that is unused in BBRv2 - - Change-Id: Iee1df7e41e42de199068d7c89131ed3d228327c0 - -commit e452cc65ef66902908a8e20ad2ba1f01435ede08 -Author: Neal Cardwell <ncardwell@google.com> -Date: Mon Aug 17 19:08:41 2020 -0400 - - net-tcp_bbr: v2: remove field bw_rtts that is unused in BBRv2 - - Change-Id: I58e3346c707748a6f316f3ed060d2da84c32a79b - -commit 097063f0b21fc7e8010b17517f16bf6872ca7ce5 -Author: Neal Cardwell <ncardwell@google.com> -Date: Thu Nov 21 15:28:01 2019 -0500 - - net-tcp_bbr: v2: remove unnecessary rs.delivered_ce logic upon loss - - There is no reason to compute rs.delivered_ce upon loss. - - In fact, we specifically do not want to compute rs.delivered_ce upon loss. - - Two issues: - - (1) This would be the wrong thing to do, in behavior terms. With - RACK's dynamic reordering window, losses can be marked long after - the sequence hole appears in the ACK/SACK stream. We want to to - catch the ECN mark rate rising too high as quickly as possible, - which means we want to check for high ECN mark rates at ACK time - (as BBRv2 currently does) and not loss marking time. - - (2) This is dead code. The ECN mark rate cannot be detected as too - high because the check needs rs->delivered to be > 0 as well: - - if (rs->delivered_ce > 0 && rs->delivered > 0 && - - Since we are not setting rs->delivered upon loss, this check - cannot succeed, so setting delivered_ce is pointless. - - This dead and wrong line was discovered by Randall Stewart at Netflix - as he was reading the BBRv2 code. - - Change-Id: I37f83f418a259ec31d8f82de986db071b364b76a - -commit 487953c510db2097dd095027a9c7f9f904ecdb17 -Author: Neal Cardwell <ncardwell@google.com> -Date: Tue Jun 11 12:54:22 2019 -0400 - - net-tcp_bbr: v2: BBRv2 ("bbr2") congestion control for Linux TCP - - BBR v2 is an enhacement to the BBR v1 algorithm. It's designed to aim for lower - queues, lower loss, and better Reno/CUBIC coexistence than BBR v1. - - BBR v2 maintains the core of BBR v1: an explicit model of the network - path that is two-dimensional, adapting to estimate the (a) maximum - available bandwidth and (b) maximum safe volume of data a flow can - keep in-flight in the network. It maintains the estimated BDP as a - core guide for estimating an appropriate level of in-flight data. - - BBR v2 makes several key enhancements: - - o Its bandwidth-probing time scale is adapted, within bounds, to allow improved - coexistence with Reno and CUBIC. The bandwidth-probing time scale is (a) - extended dynamically based on estimated BDP to improve coexistence with - Reno/CUBIC; (b) bounded by an interactive wall-clock time-scale to be more - scalable and responsive than Reno and CUBIC. - - o Rather than being largely agnostic to loss and ECN marks, it explicitly uses - loss and (DCTCP-style) ECN signals to maintain its model. - - o It aims for lower losses than v1 by adjusting its model to attempt to stay - within loss rate and ECN mark rate bounds (loss_thresh and ecn_thresh, - respectively). - - o It adapts to loss/ECN signals even when the application is running out of - data ("application-limited"), in case the "application-limited" flow is also - "network-limited" (the bw and/or inflight available to this flow is lower than - previously estimated when the flow ran out of data). - - o It has a three-part model: the model explicit three tracks operating points, - where an operating point is a tuple: (bandwidth, inflight). The three operating - points are: - - o latest: the latest measurement from the current round trip - o upper bound: robust, optimistic, long-term upper bound - o lower bound: robust, conservative, short-term lower bound - - These are stored in the following state variables: - - o latest: bw_latest, inflight_latest - o lo: bw_lo, inflight_lo - o hi: bw_hi[2], inflight_hi - - To gain intuition about the meaning of the three operating points, it - may help to consider the analogs in CUBIC, which has a somewhat - analogous three-part model used by its probing state machine: - - BBR param CUBIC param - ----------- ------------- - latest ~ cwnd - lo ~ ssthresh - hi ~ last_max_cwnd - - The analogy is only a loose one, though, since the BBR operating - points are calculated differently, and are 2-dimensional (bw,inflight) - rather than CUBIC's one-dimensional notion of operating point - (inflight). - - o It uses the three-part model to adapt the magnitude of its bandwidth - to match the estimated space available in the buffer, rather than (as - in BBR v1) assuming that it was always acceptable to place 0.25*BDP in - the bottleneck buffer when probing (commodity datacenter switches - commonly do not have that much buffer for WAN flows). When BBR v2 - estimates it hit a buffer limit during probing, its bandwidth probing - then starts gently in case little space is still available in the - buffer, and the accelerates, slowly at first and then rapidly if it - can grow inflight without seeing congestion signals. In such cases, - probing is bounded by inflight_hi + inflight_probe, where - inflight_probe grows as: [0, 1, 2, 4, 8, 16,...]. This allows BBR to - keep losses low and bounded if a bottleneck remains congested, while - rapidly/scalably utilizing free bandwidth when it becomes available. - - o It has a slightly revised state machine, to achieve the goals above. - BBR_BW_PROBE_UP: pushes up inflight to probe for bw/vol - BBR_BW_PROBE_DOWN: drain excess inflight from the queue - BBR_BW_PROBE_CRUISE: use pipe, w/ headroom in queue/pipe - BBR_BW_PROBE_REFILL: try refill the pipe again to 100%, leaving queue empty - - o The estimated BDP: BBR v2 continues to maintain an estimate of the - path's two-way propagation delay, by tracking a windowed min_rtt, and - coordinating (on an as-ndeeded basis) to try to expose the two-way - propagation delay by draining the bottleneck queue. - - BBR v2 continues to use its min_rtt and (currently-applicable) bandwidth - estimate to estimate the current bandwidth-delay product. The estimated BDP - still provides one important guideline for bounding inflight data. However, - because any min-filtered RTT and max-filtered bw inherently tend to both - overestimate, the estimated BDP is often too high; in this case loss or ECN - marks can ensue, in which case BBR v2 adjusts inflight_hi and inflight_lo to - adapt its sending rate and inflight down to match the available capacity of the - path. - - o Space: Note that ICSK_CA_PRIV_SIZE increased. This is because BBR v2 - requires more space. Note that much of the space is due to support for - per-socket parameterization and debugging in this release for research - and debugging. With that state removed, the full "struct bbr" is 140 - bytes, or 144 with padding. This is an increase of 40 bytes over the - existing ca_priv space. - - o Code: BBR v2 reuses many pieces from BBR v1. But it omits the following - significant pieces: - - o "packet conservation" (bbr_set_cwnd_to_recover_or_restore(), - bbr_can_grow_inflight()) - o long-term bandwidth estimator ("policer mode") - - The code layout tries to keep BBR v2 code near the bottom of the - file, so that v1-applicable code in the top does not accidentally - refer to v2 code. - - o Docs: - See the following docs for more details and diagrams decsribing the BBR v2 - algorithm: - https://datatracker.ietf.org/meeting/104/materials/slides-104-iccrg-an-update-on-bbr-00 - https://datatracker.ietf.org/meeting/102/materials/slides-102-iccrg-an-update-on-bbr-work-at-google-00 - - o Internal notes: - For this upstream rebase, Neal started from: - git show fed518041ac6:net/ipv4/tcp_bbr.c > net/ipv4/tcp_bbr.c - then removed dev instrumentation (dynamic get/set for parameters) - and code that was only used by BBRv1 - - Effort: net-tcp_bbr - Origin-9xx-SHA1: 2c84098e60bed6d67dde23cd7538c51dee273102 - Change-Id: I125cf26ba2a7a686f2fa5e87f4c2afceb65f7a05 - -commit 9fafce18324c72fb566a3c079b818d3cee757ef9 -Author: Neal Cardwell <ncardwell@google.com> -Date: Sat Nov 16 13:16:25 2019 -0500 - - net-tcp: add fast_ack_mode=1: skip rwin check in tcp_fast_ack_mode__tcp_ack_snd_check() - - Add logic for an experimental TCP connection behavior, enabled with - tp->fast_ack_mode = 1, which disables checking the receive window - before sending an ack in __tcp_ack_snd_check(). If this behavior is - enabled, the data receiver sends an ACK if the amount of data is > - RCV.MSS. - - Change-Id: Iaa0a0fd7108221f883137a79d5bfa724f1b096d4 - -commit 65b716a609f5a6d4fd43d7185b2bd07d6525e904 -Author: Neal Cardwell <ncardwell@google.com> -Date: Fri Sep 27 17:10:26 2019 -0400 - - net-tcp: re-generalize TSO sizing in TCP CC module API - - Reorganize the API for CC modules so that the CC module once again - gets complete control of the TSO sizing decision. This is how the API - was set up around 2016 and the initial BBRv1 upstreaming. Later Eric - Dumazet simplified it. But with wider testing it now seems that to - avoid CPU regressions BBR needs to have a different TSO sizing - function. - - This is necessary to handle cases where there are many flows - bottlenecked on the sender host's NIC, in which case BBR's pacing rate - is much lower than CUBIC/Reno/DCTCP's. Why does this happen? Because - BBR's pacing rate adapts to the low bandwidth share each flow sees. By - contrast, CUBIC/Reno/DCTCP see no loss or ECN, so they grow a very - large cwnd, and thus large pacing rate and large TSO burst size. - - Change-Id: Ic8ccfdbe4010ee8d4bf6a6334c48a2fceb2171ea - -commit 857d19dbb3bbabb1d3da59405fc6ac57d17ebc14 -Author: Yousuk Seung <ysseung@google.com> -Date: Wed May 23 17:55:54 2018 -0700 - - net-tcp: add new ca opts flag TCP_CONG_WANTS_CE_EVENTS - - Add a a new ca opts flag TCP_CONG_WANTS_CE_EVENTS that allows a - congestion control module to receive CE events. - - Currently congestion control modules have to set the TCP_CONG_NEEDS_ECN - bit in opts flag to receive CE events but this may incur changes in ECN - behavior elsewhere. This patch adds a new bit TCP_CONG_WANTS_CE_EVENTS - that allows congestion control modules to receive CE events - independently of TCP_CONG_NEEDS_ECN. - - Effort: net-tcp - Origin-9xx-SHA1: 9f7e14716cde760bc6c67ef8ef7e1ee48501d95b - Change-Id: I2255506985242f376d910c6fd37daabaf4744f24 - -commit c1e3c81be5ef9832d7dc26dbe6c64dd7025f9503 -Author: Neal Cardwell <ncardwell@google.com> -Date: Tue May 7 22:37:19 2019 -0400 - - net-tcp_bbr: v2: set tx.in_flight for skbs in repair write queue - - Syzkaller was able to use TCP_REPAIR to reproduce the new warning - added in tcp_fragment(): - - WARNING: CPU: 0 PID: 118174 at net/ipv4/tcp_output.c:1487 - tcp_fragment+0xdcc/0x10a0 net/ipv4/tcp_output.c:1487() - inconsistent: tx.in_flight: 0 old_factor: 53 - - The warning happens because skbs inserted into the tcp_rtx_queue - during the repair process go through a sort of "fake send" process, - and that process was seting pcount but not tx.in_flight, and thus the - warnings (where old_factor is the old pcount). - - The fix of setting tx.in_flight in the TCP_REPAIR code path seems - simple enough, and indeed makes the repro code from syzkaller stop - producing warnings. Running through kokonut tests, and will send out - for review when all tests pass. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: 330f825a08a6fe92cef74d799cc468864c479f63 - Change-Id: I0bc4a790f040fd4239620e1eedd5dc64666c6f05 - -commit 03c4ece7790dba1a88aebb68e960919ec9c587d2 -Author: Neal Cardwell <ncardwell@google.com> -Date: Wed May 1 20:16:25 2019 -0400 - - net-tcp_bbr: v2: adjust skb tx.in_flight upon split in tcp_fragment() - - When we fragment an skb that has already been sent, we need to update - the tx.in_flight for the first skb in the resulting pair ("buff"). - - Because we were not updating the tx.in_flight, the tx.in_flight value - was inconsistent with the pcount of the "buff" skb (tx.in_flight would - be too high). That meant that if the "buff" skb was lost, then - bbr2_inflight_hi_from_lost_skb() would calculate an inflight_hi value - that is too high. This could result in longer queues and higher packet - loss. - - Packetdrill testing verified that without this commit, when the second - half of an skb is SACKed and then later the first half of that skb is - marked lost, the calculated inflight_hi was incorrect. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: 385f1ddc610798fab2837f9f372857438b25f874 - Change-Id: I617f8cab4e9be7a0b8e8d30b047bf8645393354d - -commit 1f57067a046edee861a5ab7daba10e9089ef7103 -Author: Neal Cardwell <ncardwell@google.com> -Date: Wed May 1 20:16:33 2019 -0400 - - net-tcp_bbr: v2: adjust skb tx.in_flight upon merge in tcp_shifted_skb() - - When tcp_shifted_skb() updates state as adjacent SACKed skbs are - coalesced, previously the tx.in_flight was not adjusted, so we could - get contradictory state where the skb's recorded pcount was bigger - than the tx.in_flight (the number of segments that were in_flight - after sending the skb). - - Normally have a SACKed skb with contradictory pcount/tx.in_flight - would not matter. However, with SACK reneging, the SACKed bit is - removed, and an skb once again becomes eligible for retransmitting, - fragmenting, SACKing, etc. Packetdrill testing verified the following - sequence is possible in a kernel that does not have this commit: - - - skb N is SACKed - - skb N+1 is SACKed and combined with skb N using tcp_shifted_skb() - - tcp_shifted_skb() will increase the pcount of prev, - but leave tx.in_flight as-is - - so prev skb can have pcount > tx.in_flight - - RTO, tcp_timeout_mark_lost(), detect reneg, - remove "SACKed" bit, mark skb N as lost - - find pcount of skb N is greater than its tx.in_flight - - I suspect this issue iw what caused the bbr2_inflight_hi_from_lost_skb(): - WARN_ON_ONCE(inflight_prev < 0) - to fire in production machines using bbr2. - - Tested: See last commit in series for sponge link. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: 1a3e997e613d2dcf32b947992882854ebe873715 - Change-Id: I1b0b75c27519953430c7db51c6f358f104c7af55 - -commit dfaf2f3907da754b58996bdd6d22139d8ae7fbd7 -Author: Neal Cardwell <ncardwell@google.com> -Date: Tue May 7 22:36:36 2019 -0400 - - net-tcp_bbr: v2: factor out tx.in_flight setting into tcp_set_tx_in_flight() - - Factor out the code to set an skb's tx.in_flight field into its own - function, so that this code can be used for the TCP_REPAIR "fake send" - code path that inserts skbs into the rtx queue without sending - them. This is in preparation for the following patch, which fixes an - issue with TCP_REPAIR and tx.in_flight. - - Tested: See last patch in series for sponge link. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: e880fc907d06ea7354333f60f712748ebce9497b - Change-Id: I4fbd4a6e18a51ab06d50ab1c9ad820ce5bea89af - -commit bf1996458d8348f65ec52b651ea386e47ba1db33 -Author: Neal Cardwell <ncardwell@google.com> -Date: Tue Aug 7 21:52:06 2018 -0400 - - net-tcp_bbr: v2: introduce ca_ops->skb_marked_lost() CC module callback API - - For connections experiencing reordering, RACK can mark packets lost - long after we receive the SACKs/ACKs hinting that the packets were - actually lost. - - This means that CC modules cannot easily learn the volume of inflight - data at which packet loss happens by looking at the current inflight - or even the packets in flight when the most recently SACKed packet was - sent. To learn this, CC modules need to know how many packets were in - flight at the time lost packets were sent. This new callback, combined - with TCP_SKB_CB(skb)->tx.in_flight, allows them to learn this. - - This also provides a consistent callback that is invoked whether - packets are marked lost upon ACK processing, using the RACK reordering - timer, or at RTO time. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: afcbebe3374e4632ac6714d39e4dc8a8455956f4 - Change-Id: I54826ab53df636be537e5d3c618a46145d12d51a - -commit 8efc97365ed81bc15bb665fe036835ed511530e1 -Author: Neal Cardwell <ncardwell@google.com> -Date: Mon Nov 19 13:48:36 2018 -0500 - - net-tcp_bbr: v2: export FLAG_ECE in rate_sample.is_ece - - For understanding the relationship between inflight and ECN signals, - to try to find the highest inflight value that has acceptable levels - ECN marking. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: 3eba998f2898541406c2666781182200934965a8 - Change-Id: I3a964e04cee83e11649a54507043d2dfe769a3b3 - -commit 81eada6998cb810e67a056b99175ef7ca82d180a -Author: Neal Cardwell <ncardwell@google.com> -Date: Thu Oct 12 23:44:27 2017 -0400 - - net-tcp_bbr: v2: count packets lost over TCP rate sampling interval - - For understanding the relationship between inflight and packet loss - signals, to try to find the highest inflight value that has acceptable - levels of packet losses. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: 4527e26b2bd7756a88b5b9ef1ada3da33dd609ab - Change-Id: I594c2500868d9c530770e7ddd68ffc87c57f4fd5 - -commit ed57cac80e24315a6502fbff52218a95040ccba3 -Author: Neal Cardwell <ncardwell@google.com> -Date: Sat Aug 5 11:49:50 2017 -0400 - - net-tcp_bbr: v2: snapshot packets in flight at transmit time and pass in rate_sample - - For understanding the relationship between inflight and losses or ECN - signals, to try to find the highest inflight value that has acceptable - levels of loss/ECN marking. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: b3eb4f2d20efab4ca001f32c9294739036c493ea - Change-Id: I7314047d0ff14dd261a04b1969a46dc658c8836a - -commit a33083242c9efc580e397b587d3c660e9d371098 -Author: Neal Cardwell <ncardwell@google.com> -Date: Sun Jun 24 21:55:59 2018 -0400 - - net-tcp_bbr: v2: shrink delivered_mstamp, first_tx_mstamp to u32 to free up 8 bytes - - Free up some space for tracking inflight and losses for each - bw sample, in upcoming commits. - - These timestamps are in microseconds, and are now stored in 32 - bits. So they can only hold time intervals up to roughly 2^12 = 4096 - seconds. But Linux TCP RTT and RTO tracking has the same 32-bit - microsecond implementation approach and resulting deployment - limitations. So this is not introducing a new limit. And these should - not be a limitation for the foreseeable future. - - Effort: net-tcp_bbr - Origin-9xx-SHA1: 238a7e6b5d51625fef1ce7769826a7b21b02ae55 - Change-Id: I3b779603797263b52a61ad57c565eb91fe42680c - -commit d3a59b8de6fc7493ed2db7d9d386e2c74f4e8938 -Author: Yuchung Cheng <ycheng@google.com> -Date: Tue Mar 27 18:01:46 2018 -0700 - - net-tcp_rate: account for CE marks in rate sample - - This patch counts number of packets delivered have CE mark in the - rate sample, using similar approach of delivery accounting. - - Effort: net-tcp_rate - Origin-9xx-SHA1: 710644db434c3da335a7c8b72207a671ccbb5cf8 - Change-Id: I0968fb33fe19b5c774e8c3afd2685558a6ec8710 - -commit 21e06050c8ef2995a4c99bb9727452c6b0c005e3 -Author: Yuchung Cheng <ycheng@google.com> -Date: Tue Mar 27 18:33:29 2018 -0700 - - net-tcp_rate: consolidate inflight tracking approaches in TCP - - In order to track CE marks per rate sample (one round trip), we'll - need to snap the starting tcp delivered_ce acount in the packet - meta header (tcp_skb_cb). But there's not enough space. - - Good news is that the "last_in_flight" in the header, used by - NV congestion control, is almost equivalent as "delivered". In - fact "delivered" is better by accounting out-of-order packets - additionally. Therefore we can remove it to make room for the - CE tracking. - - This would make delayed ACK detection slightly less accurate but the - impact is negligible since it's not used for any critical control. - - Effort: net-tcp_rate - Origin-9xx-SHA1: ddcd46ec85d5f1c4454258af0c54b3254c0d64a7 - Change-Id: I1a184aad6d101c981ac7f2f275aa9417ff856910 - -commit a0f76e629209066ed4f0aa227ab61882952ba0d4 -Author: Neal Cardwell <ncardwell@google.com> -Date: Tue Jun 11 12:26:55 2019 -0400 - - net-tcp_bbr: broaden app-limited rate sample detection - - This commit is a bug fix for the Linux TCP app-limited - (application-limited) logic that is used for collecting rate - (bandwidth) samples. - - Previously the app-limited logic only looked for "bubbles" of - silence in between application writes, by checking at the start - of each sendmsg. But "bubbles" of silence can also happen before - retransmits: e.g. bubbles can happen between an application write - and a retransmit, or between two retransmits. - - Retransmits are triggered by ACKs or timers. So this commit checks - for bubbles of app-limited silence upon ACKs or timers. - - Why does this commit check for app-limited state at the start of - ACKs and timer handling? Because at that point we know whether - inflight was fully using the cwnd. During processing the ACK or - timer event we often change the cwnd; after changing the cwnd we - can't know whether inflight was fully using the old cwnd. - - Origin-9xx-SHA1: 3fe9b53291e018407780fb8c356adb5666722cbc - Change-Id: I37221506f5166877c2b110753d39bb0757985e68 ---- - include/linux/tcp.h | 3 +- - include/net/inet_connection_sock.h | 5 +- - include/net/tcp.h | 50 +- - include/uapi/linux/inet_diag.h | 33 + - net/ipv4/Kconfig | 22 + - net/ipv4/Makefile | 1 + - net/ipv4/bpf_tcp_ca.c | 2 +- - net/ipv4/tcp.c | 1 + - net/ipv4/tcp_bbr.c | 38 +- - net/ipv4/tcp_bbr2.c | 2674 ++++++++++++++++++++++++++++ - net/ipv4/tcp_cong.c | 1 + - net/ipv4/tcp_input.c | 38 +- - net/ipv4/tcp_output.c | 28 +- - net/ipv4/tcp_rate.c | 36 +- - net/ipv4/tcp_timer.c | 1 + - 15 files changed, 2886 insertions(+), 47 deletions(-) - create mode 100644 net/ipv4/tcp_bbr2.c - -diff --git a/include/linux/tcp.h b/include/linux/tcp.h -index 48d8a363319e..1bd559c69e83 100644 ---- a/include/linux/tcp.h -+++ b/include/linux/tcp.h -@@ -225,7 +225,8 @@ struct tcp_sock { - u8 compressed_ack; - u8 dup_ack_counter:2, - tlp_retrans:1, /* TLP is a retransmission */ -- unused:5; -+ fast_ack_mode:2, /* which fast ack mode ? */ -+ unused:3; - u32 chrono_start; /* Start time in jiffies of a TCP chrono */ - u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */ - u8 chrono_type:2, /* current chronograph type */ -diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h -index b06c2d02ec84..2cdc5a0709fe 100644 ---- a/include/net/inet_connection_sock.h -+++ b/include/net/inet_connection_sock.h -@@ -134,8 +134,9 @@ struct inet_connection_sock { - u32 icsk_probes_tstamp; - u32 icsk_user_timeout; - -- u64 icsk_ca_priv[104 / sizeof(u64)]; --#define ICSK_CA_PRIV_SIZE sizeof_field(struct inet_connection_sock, icsk_ca_priv) -+/* XXX inflated by temporary internal debugging info */ -+#define ICSK_CA_PRIV_SIZE (216) -+ u64 icsk_ca_priv[ICSK_CA_PRIV_SIZE / sizeof(u64)]; - }; - - #define ICSK_TIME_RETRANS 1 /* Retransmit timer */ -diff --git a/include/net/tcp.h b/include/net/tcp.h -index 784d5c3ef1c5..daa878118bd3 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -371,6 +371,7 @@ static inline void tcp_dec_quickack_mode(struct sock *sk, - #define TCP_ECN_QUEUE_CWR 2 - #define TCP_ECN_DEMAND_CWR 4 - #define TCP_ECN_SEEN 8 -+#define TCP_ECN_ECT_PERMANENT 16 - - enum tcp_tw_status { - TCP_TW_SUCCESS = 0, -@@ -807,6 +808,11 @@ static inline u32 tcp_stamp_us_delta(u64 t1, u64 t0) - return max_t(s64, t1 - t0, 0); - } - -+static inline u32 tcp_stamp32_us_delta(u32 t1, u32 t0) -+{ -+ return max_t(s32, t1 - t0, 0); -+} -+ - static inline u32 tcp_skb_timestamp(const struct sk_buff *skb) - { - return tcp_ns_to_ts(skb->skb_mstamp_ns); -@@ -874,16 +880,22 @@ struct tcp_skb_cb { - __u32 ack_seq; /* Sequence number ACK'd */ - union { - struct { -+#define TCPCB_DELIVERED_CE_MASK ((1U<<20) - 1) - /* There is space for up to 24 bytes */ -- __u32 in_flight:30,/* Bytes in flight at transmit */ -- is_app_limited:1, /* cwnd not fully used? */ -- unused:1; -+ __u32 is_app_limited:1, /* cwnd not fully used? */ -+ delivered_ce:20, -+ unused:11; - /* pkts S/ACKed so far upon tx of skb, incl retrans: */ - __u32 delivered; - /* start of send pipeline phase */ -- u64 first_tx_mstamp; -+ u32 first_tx_mstamp; - /* when we reached the "delivered" count */ -- u64 delivered_mstamp; -+ u32 delivered_mstamp; -+#define TCPCB_IN_FLIGHT_BITS 20 -+#define TCPCB_IN_FLIGHT_MAX ((1U << TCPCB_IN_FLIGHT_BITS) - 1) -+ u32 in_flight:20, /* packets in flight at transmit */ -+ unused2:12; -+ u32 lost; /* packets lost so far upon tx of skb */ - } tx; /* only used for outgoing skbs */ - union { - struct inet_skb_parm h4; -@@ -1008,7 +1020,11 @@ enum tcp_ca_ack_event_flags { - #define TCP_CONG_NON_RESTRICTED 0x1 - /* Requires ECN/ECT set on all packets */ - #define TCP_CONG_NEEDS_ECN 0x2 --#define TCP_CONG_MASK (TCP_CONG_NON_RESTRICTED | TCP_CONG_NEEDS_ECN) -+/* Wants notification of CE events (CA_EVENT_ECN_IS_CE, CA_EVENT_ECN_NO_CE). */ -+#define TCP_CONG_WANTS_CE_EVENTS 0x4 -+#define TCP_CONG_MASK (TCP_CONG_NON_RESTRICTED | \ -+ TCP_CONG_NEEDS_ECN | \ -+ TCP_CONG_WANTS_CE_EVENTS) - - union tcp_cc_info; - -@@ -1028,8 +1044,13 @@ struct ack_sample { - */ - struct rate_sample { - u64 prior_mstamp; /* starting timestamp for interval */ -+ u32 prior_lost; /* tp->lost at "prior_mstamp" */ - u32 prior_delivered; /* tp->delivered at "prior_mstamp" */ -+ u32 prior_delivered_ce;/* tp->delivered_ce at "prior_mstamp" */ -+ u32 tx_in_flight; /* packets in flight at starting timestamp */ -+ s32 lost; /* number of packets lost over interval */ - s32 delivered; /* number of packets delivered over interval */ -+ s32 delivered_ce; /* packets delivered w/ CE mark over interval */ - long interval_us; /* time for tp->delivered to incr "delivered" */ - u32 snd_interval_us; /* snd interval for delivered packets */ - u32 rcv_interval_us; /* rcv interval for delivered packets */ -@@ -1040,6 +1061,7 @@ struct rate_sample { - bool is_app_limited; /* is sample from packet with bubble in pipe? */ - bool is_retrans; /* is sample from retransmission? */ - bool is_ack_delayed; /* is this (likely) a delayed ACK? */ -+ bool is_ece; /* did this ACK have ECN marked? */ - }; - - struct tcp_congestion_ops { -@@ -1063,8 +1085,11 @@ struct tcp_congestion_ops { - /* hook for packet ack accounting (optional) */ - void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample); - -- /* override sysctl_tcp_min_tso_segs */ -- u32 (*min_tso_segs)(struct sock *sk); -+ /* pick target number of segments per TSO/GSO skb (optional): */ -+ u32 (*tso_segs)(struct sock *sk, unsigned int mss_now); -+ -+ /* react to a specific lost skb (optional) */ -+ void (*skb_marked_lost)(struct sock *sk, const struct sk_buff *skb); - - /* call when packets are delivered to update cwnd and pacing rate, - * after all the ca_state processing. (optional) -@@ -1127,6 +1152,14 @@ static inline char *tcp_ca_get_name_by_key(u32 key, char *buffer) - } - #endif - -+static inline bool tcp_ca_wants_ce_events(const struct sock *sk) -+{ -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ return icsk->icsk_ca_ops->flags & (TCP_CONG_NEEDS_ECN | -+ TCP_CONG_WANTS_CE_EVENTS); -+} -+ - static inline bool tcp_ca_needs_ecn(const struct sock *sk) - { - const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -1152,6 +1185,7 @@ static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event) - } - - /* From tcp_rate.c */ -+void tcp_set_tx_in_flight(struct sock *sk, struct sk_buff *skb); - void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb); - void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb, - struct rate_sample *rs); -diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h -index 20ee93f0f876..96d52dd9c48a 100644 ---- a/include/uapi/linux/inet_diag.h -+++ b/include/uapi/linux/inet_diag.h -@@ -231,9 +231,42 @@ struct tcp_bbr_info { - __u32 bbr_cwnd_gain; /* cwnd gain shifted left 8 bits */ - }; - -+/* Phase as reported in netlink/ss stats. */ -+enum tcp_bbr2_phase { -+ BBR2_PHASE_INVALID = 0, -+ BBR2_PHASE_STARTUP = 1, -+ BBR2_PHASE_DRAIN = 2, -+ BBR2_PHASE_PROBE_RTT = 3, -+ BBR2_PHASE_PROBE_BW_UP = 4, -+ BBR2_PHASE_PROBE_BW_DOWN = 5, -+ BBR2_PHASE_PROBE_BW_CRUISE = 6, -+ BBR2_PHASE_PROBE_BW_REFILL = 7 -+}; -+ -+struct tcp_bbr2_info { -+ /* u64 bw: bandwidth (app throughput) estimate in Byte per sec: */ -+ __u32 bbr_bw_lsb; /* lower 32 bits of bw */ -+ __u32 bbr_bw_msb; /* upper 32 bits of bw */ -+ __u32 bbr_min_rtt; /* min-filtered RTT in uSec */ -+ __u32 bbr_pacing_gain; /* pacing gain shifted left 8 bits */ -+ __u32 bbr_cwnd_gain; /* cwnd gain shifted left 8 bits */ -+ __u32 bbr_bw_hi_lsb; /* lower 32 bits of bw_hi */ -+ __u32 bbr_bw_hi_msb; /* upper 32 bits of bw_hi */ -+ __u32 bbr_bw_lo_lsb; /* lower 32 bits of bw_lo */ -+ __u32 bbr_bw_lo_msb; /* upper 32 bits of bw_lo */ -+ __u8 bbr_mode; /* current bbr_mode in state machine */ -+ __u8 bbr_phase; /* current state machine phase */ -+ __u8 unused1; /* alignment padding; not used yet */ -+ __u8 bbr_version; /* MUST be at this offset in struct */ -+ __u32 bbr_inflight_lo; /* lower/short-term data volume bound */ -+ __u32 bbr_inflight_hi; /* higher/long-term data volume bound */ -+ __u32 bbr_extra_acked; /* max excess packets ACKed in epoch */ -+}; -+ - union tcp_cc_info { - struct tcpvegas_info vegas; - struct tcp_dctcp_info dctcp; - struct tcp_bbr_info bbr; -+ struct tcp_bbr2_info bbr2; - }; - #endif /* _UAPI_INET_DIAG_H_ */ -diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig -index 87983e70f03f..a833a7a67ce7 100644 ---- a/net/ipv4/Kconfig -+++ b/net/ipv4/Kconfig -@@ -669,6 +669,24 @@ config TCP_CONG_BBR - AQM schemes that do not provide a delay signal. It requires the fq - ("Fair Queue") pacing packet scheduler. - -+config TCP_CONG_BBR2 -+ tristate "BBR2 TCP" -+ default m -+ help -+ -+ BBR2 TCP congestion control is a model-based congestion control -+ algorithm that aims to maximize network utilization, keep queues and -+ retransmit rates low, and to be able to coexist with Reno/CUBIC in -+ common scenarios. It builds an explicit model of the network path. It -+ tolerates a targeted degree of random packet loss and delay that are -+ unrelated to congestion. It can operate over LAN, WAN, cellular, wifi, -+ or cable modem links, and can use DCTCP-L4S-style ECN signals. It can -+ coexist with flows that use loss-based congestion control, and can -+ operate with shallow buffers, deep buffers, bufferbloat, policers, or -+ AQM schemes that do not provide a delay signal. It requires pacing, -+ using either TCP internal pacing or the fq ("Fair Queue") pacing packet -+ scheduler. -+ - choice - prompt "Default TCP congestion control" - default DEFAULT_CUBIC -@@ -706,6 +724,9 @@ choice - config DEFAULT_BBR - bool "BBR" if TCP_CONG_BBR=y - -+ config DEFAULT_BBR2 -+ bool "BBR2" if TCP_CONG_BBR2=y -+ - config DEFAULT_RENO - bool "Reno" - endchoice -@@ -730,6 +751,7 @@ config DEFAULT_TCP_CONG - default "dctcp" if DEFAULT_DCTCP - default "cdg" if DEFAULT_CDG - default "bbr" if DEFAULT_BBR -+ default "bbr2" if DEFAULT_BBR2 - default "cubic" - - config TCP_MD5SIG -diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile -index bbdd9c44f14e..8dee1547d820 100644 ---- a/net/ipv4/Makefile -+++ b/net/ipv4/Makefile -@@ -46,6 +46,7 @@ obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o - obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o - obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o - obj-$(CONFIG_TCP_CONG_BBR) += tcp_bbr.o -+obj-$(CONFIG_TCP_CONG_BBR2) += tcp_bbr2.o - obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o - obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o - obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o -diff --git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c -index 9e41eff4a685..f26b0fcbb9f5 100644 ---- a/net/ipv4/bpf_tcp_ca.c -+++ b/net/ipv4/bpf_tcp_ca.c -@@ -17,7 +17,7 @@ static u32 optional_ops[] = { - offsetof(struct tcp_congestion_ops, cwnd_event), - offsetof(struct tcp_congestion_ops, in_ack_event), - offsetof(struct tcp_congestion_ops, pkts_acked), -- offsetof(struct tcp_congestion_ops, min_tso_segs), -+ offsetof(struct tcp_congestion_ops, tso_segs), - offsetof(struct tcp_congestion_ops, sndbuf_expand), - offsetof(struct tcp_congestion_ops, cong_control), - }; -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 8cb44040ec68..68c8eee7f831 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -3047,6 +3047,7 @@ int tcp_disconnect(struct sock *sk, int flags) - tp->rx_opt.dsack = 0; - tp->rx_opt.num_sacks = 0; - tp->rcv_ooopack = 0; -+ tp->fast_ack_mode = 0; - - - /* Clean up fastopen related fields */ -diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c -index 6274462b86b4..c0d5a4211fc1 100644 ---- a/net/ipv4/tcp_bbr.c -+++ b/net/ipv4/tcp_bbr.c -@@ -292,26 +292,40 @@ static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain) - sk->sk_pacing_rate = rate; - } - --/* override sysctl_tcp_min_tso_segs */ - static u32 bbr_min_tso_segs(struct sock *sk) - { - return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2; - } - -+/* Return the number of segments BBR would like in a TSO/GSO skb, given -+ * a particular max gso size as a constraint. -+ */ -+static u32 bbr_tso_segs_generic(struct sock *sk, unsigned int mss_now, -+ u32 gso_max_size) -+{ -+ u32 segs; -+ u64 bytes; -+ -+ /* Budget a TSO/GSO burst size allowance based on bw (pacing_rate). */ -+ bytes = sk->sk_pacing_rate >> sk->sk_pacing_shift; -+ -+ bytes = min_t(u32, bytes, gso_max_size - 1 - MAX_TCP_HEADER); -+ segs = max_t(u32, bytes / mss_now, bbr_min_tso_segs(sk)); -+ return segs; -+} -+ -+/* Custom tcp_tso_autosize() for BBR, used at transmit time to cap skb size. */ -+static u32 bbr_tso_segs(struct sock *sk, unsigned int mss_now) -+{ -+ return bbr_tso_segs_generic(sk, mss_now, sk->sk_gso_max_size); -+} -+ -+/* Like bbr_tso_segs(), using mss_cache, ignoring driver's sk_gso_max_size. */ - static u32 bbr_tso_segs_goal(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); -- u32 segs, bytes; - -- /* Sort of tcp_tso_autosize() but ignoring -- * driver provided sk_gso_max_size. -- */ -- bytes = min_t(unsigned long, -- sk->sk_pacing_rate >> READ_ONCE(sk->sk_pacing_shift), -- GSO_MAX_SIZE - 1 - MAX_TCP_HEADER); -- segs = max_t(u32, bytes / tp->mss_cache, bbr_min_tso_segs(sk)); -- -- return min(segs, 0x7FU); -+ return bbr_tso_segs_generic(sk, tp->mss_cache, GSO_MAX_SIZE); - } - - /* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */ -@@ -1147,7 +1161,7 @@ static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = { - .undo_cwnd = bbr_undo_cwnd, - .cwnd_event = bbr_cwnd_event, - .ssthresh = bbr_ssthresh, -- .min_tso_segs = bbr_min_tso_segs, -+ .tso_segs = bbr_tso_segs, - .get_info = bbr_get_info, - .set_state = bbr_set_state, - }; -diff --git a/net/ipv4/tcp_bbr2.c b/net/ipv4/tcp_bbr2.c -new file mode 100644 -index 000000000000..fa49e17c47ca ---- /dev/null -+++ b/net/ipv4/tcp_bbr2.c -@@ -0,0 +1,2674 @@ -+/* BBR (Bottleneck Bandwidth and RTT) congestion control, v2 -+ * -+ * BBRv2 is a model-based congestion control algorithm that aims for low -+ * queues, low loss, and (bounded) Reno/CUBIC coexistence. To maintain a model -+ * of the network path, it uses measurements of bandwidth and RTT, as well as -+ * (if they occur) packet loss and/or DCTCP/L4S-style ECN signals. Note that -+ * although it can use ECN or loss signals explicitly, it does not require -+ * either; it can bound its in-flight data based on its estimate of the BDP. -+ * -+ * The model has both higher and lower bounds for the operating range: -+ * lo: bw_lo, inflight_lo: conservative short-term lower bound -+ * hi: bw_hi, inflight_hi: robust long-term upper bound -+ * The bandwidth-probing time scale is (a) extended dynamically based on -+ * estimated BDP to improve coexistence with Reno/CUBIC; (b) bounded by -+ * an interactive wall-clock time-scale to be more scalable and responsive -+ * than Reno and CUBIC. -+ * -+ * Here is a state transition diagram for BBR: -+ * -+ * | -+ * V -+ * +---> STARTUP ----+ -+ * | | | -+ * | V | -+ * | DRAIN ----+ -+ * | | | -+ * | V | -+ * +---> PROBE_BW ----+ -+ * | ^ | | -+ * | | | | -+ * | +----+ | -+ * | | -+ * +---- PROBE_RTT <--+ -+ * -+ * A BBR flow starts in STARTUP, and ramps up its sending rate quickly. -+ * When it estimates the pipe is full, it enters DRAIN to drain the queue. -+ * In steady state a BBR flow only uses PROBE_BW and PROBE_RTT. -+ * A long-lived BBR flow spends the vast majority of its time remaining -+ * (repeatedly) in PROBE_BW, fully probing and utilizing the pipe's bandwidth -+ * in a fair manner, with a small, bounded queue. *If* a flow has been -+ * continuously sending for the entire min_rtt window, and hasn't seen an RTT -+ * sample that matches or decreases its min_rtt estimate for 10 seconds, then -+ * it briefly enters PROBE_RTT to cut inflight to a minimum value to re-probe -+ * the path's two-way propagation delay (min_rtt). When exiting PROBE_RTT, if -+ * we estimated that we reached the full bw of the pipe then we enter PROBE_BW; -+ * otherwise we enter STARTUP to try to fill the pipe. -+ * -+ * BBR is described in detail in: -+ * "BBR: Congestion-Based Congestion Control", -+ * Neal Cardwell, Yuchung Cheng, C. Stephen Gunn, Soheil Hassas Yeganeh, -+ * Van Jacobson. ACM Queue, Vol. 14 No. 5, September-October 2016. -+ * -+ * There is a public e-mail list for discussing BBR development and testing: -+ * https://groups.google.com/forum/#!forum/bbr-dev -+ * -+ * NOTE: BBR might be used with the fq qdisc ("man tc-fq") with pacing enabled, -+ * otherwise TCP stack falls back to an internal pacing using one high -+ * resolution timer per TCP socket and may use more resources. -+ */ -+#include <linux/module.h> -+#include <net/tcp.h> -+#include <linux/inet_diag.h> -+#include <linux/inet.h> -+#include <linux/random.h> -+ -+#include "tcp_dctcp.h" -+ -+/* Scale factor for rate in pkt/uSec unit to avoid truncation in bandwidth -+ * estimation. The rate unit ~= (1500 bytes / 1 usec / 2^24) ~= 715 bps. -+ * This handles bandwidths from 0.06pps (715bps) to 256Mpps (3Tbps) in a u32. -+ * Since the minimum window is >=4 packets, the lower bound isn't -+ * an issue. The upper bound isn't an issue with existing technologies. -+ */ -+#define BW_SCALE 24 -+#define BW_UNIT (1 << BW_SCALE) -+ -+#define BBR_SCALE 8 /* scaling factor for fractions in BBR (e.g. gains) */ -+#define BBR_UNIT (1 << BBR_SCALE) -+ -+#define FLAG_DEBUG_VERBOSE 0x1 /* Verbose debugging messages */ -+#define FLAG_DEBUG_LOOPBACK 0x2 /* Do NOT skip loopback addr */ -+ -+#define CYCLE_LEN 8 /* number of phases in a pacing gain cycle */ -+ -+/* BBR has the following modes for deciding how fast to send: */ -+enum bbr_mode { -+ BBR_STARTUP, /* ramp up sending rate rapidly to fill pipe */ -+ BBR_DRAIN, /* drain any queue created during startup */ -+ BBR_PROBE_BW, /* discover, share bw: pace around estimated bw */ -+ BBR_PROBE_RTT, /* cut inflight to min to probe min_rtt */ -+}; -+ -+/* How does the incoming ACK stream relate to our bandwidth probing? */ -+enum bbr_ack_phase { -+ BBR_ACKS_INIT, /* not probing; not getting probe feedback */ -+ BBR_ACKS_REFILLING, /* sending at est. bw to fill pipe */ -+ BBR_ACKS_PROBE_STARTING, /* inflight rising to probe bw */ -+ BBR_ACKS_PROBE_FEEDBACK, /* getting feedback from bw probing */ -+ BBR_ACKS_PROBE_STOPPING, /* stopped probing; still getting feedback */ -+}; -+ -+/* BBR congestion control block */ -+struct bbr { -+ u32 min_rtt_us; /* min RTT in min_rtt_win_sec window */ -+ u32 min_rtt_stamp; /* timestamp of min_rtt_us */ -+ u32 probe_rtt_done_stamp; /* end time for BBR_PROBE_RTT mode */ -+ u32 probe_rtt_min_us; /* min RTT in bbr_probe_rtt_win_ms window */ -+ u32 probe_rtt_min_stamp; /* timestamp of probe_rtt_min_us*/ -+ u32 next_rtt_delivered; /* scb->tx.delivered at end of round */ -+ u32 prior_rcv_nxt; /* tp->rcv_nxt when CE state last changed */ -+ u64 cycle_mstamp; /* time of this cycle phase start */ -+ u32 mode:3, /* current bbr_mode in state machine */ -+ prev_ca_state:3, /* CA state on previous ACK */ -+ packet_conservation:1, /* use packet conservation? */ -+ round_start:1, /* start of packet-timed tx->ack round? */ -+ ce_state:1, /* If most recent data has CE bit set */ -+ bw_probe_up_rounds:5, /* cwnd-limited rounds in PROBE_UP */ -+ try_fast_path:1, /* can we take fast path? */ -+ unused2:11, -+ idle_restart:1, /* restarting after idle? */ -+ probe_rtt_round_done:1, /* a BBR_PROBE_RTT round at 4 pkts? */ -+ cycle_idx:3, /* current index in pacing_gain cycle array */ -+ has_seen_rtt:1; /* have we seen an RTT sample yet? */ -+ u32 pacing_gain:11, /* current gain for setting pacing rate */ -+ cwnd_gain:11, /* current gain for setting cwnd */ -+ full_bw_reached:1, /* reached full bw in Startup? */ -+ full_bw_cnt:2, /* number of rounds without large bw gains */ -+ init_cwnd:7; /* initial cwnd */ -+ u32 prior_cwnd; /* prior cwnd upon entering loss recovery */ -+ u32 full_bw; /* recent bw, to estimate if pipe is full */ -+ -+ /* For tracking ACK aggregation: */ -+ u64 ack_epoch_mstamp; /* start of ACK sampling epoch */ -+ u16 extra_acked[2]; /* max excess data ACKed in epoch */ -+ u32 ack_epoch_acked:20, /* packets (S)ACKed in sampling epoch */ -+ extra_acked_win_rtts:5, /* age of extra_acked, in round trips */ -+ extra_acked_win_idx:1, /* current index in extra_acked array */ -+ /* BBR v2 state: */ -+ unused1:2, -+ startup_ecn_rounds:2, /* consecutive hi ECN STARTUP rounds */ -+ loss_in_cycle:1, /* packet loss in this cycle? */ -+ ecn_in_cycle:1; /* ECN in this cycle? */ -+ u32 loss_round_delivered; /* scb->tx.delivered ending loss round */ -+ u32 undo_bw_lo; /* bw_lo before latest losses */ -+ u32 undo_inflight_lo; /* inflight_lo before latest losses */ -+ u32 undo_inflight_hi; /* inflight_hi before latest losses */ -+ u32 bw_latest; /* max delivered bw in last round trip */ -+ u32 bw_lo; /* lower bound on sending bandwidth */ -+ u32 bw_hi[2]; /* upper bound of sending bandwidth range*/ -+ u32 inflight_latest; /* max delivered data in last round trip */ -+ u32 inflight_lo; /* lower bound of inflight data range */ -+ u32 inflight_hi; /* upper bound of inflight data range */ -+ u32 bw_probe_up_cnt; /* packets delivered per inflight_hi incr */ -+ u32 bw_probe_up_acks; /* packets (S)ACKed since inflight_hi incr */ -+ u32 probe_wait_us; /* PROBE_DOWN until next clock-driven probe */ -+ u32 ecn_eligible:1, /* sender can use ECN (RTT, handshake)? */ -+ ecn_alpha:9, /* EWMA delivered_ce/delivered; 0..256 */ -+ bw_probe_samples:1, /* rate samples reflect bw probing? */ -+ prev_probe_too_high:1, /* did last PROBE_UP go too high? */ -+ stopped_risky_probe:1, /* last PROBE_UP stopped due to risk? */ -+ rounds_since_probe:8, /* packet-timed rounds since probed bw */ -+ loss_round_start:1, /* loss_round_delivered round trip? */ -+ loss_in_round:1, /* loss marked in this round trip? */ -+ ecn_in_round:1, /* ECN marked in this round trip? */ -+ ack_phase:3, /* bbr_ack_phase: meaning of ACKs */ -+ loss_events_in_round:4,/* losses in STARTUP round */ -+ initialized:1; /* has bbr_init() been called? */ -+ u32 alpha_last_delivered; /* tp->delivered at alpha update */ -+ u32 alpha_last_delivered_ce; /* tp->delivered_ce at alpha update */ -+ -+ /* Params configurable using setsockopt. Refer to correspoding -+ * module param for detailed description of params. -+ */ -+ struct bbr_params { -+ u32 high_gain:11, /* max allowed value: 2047 */ -+ drain_gain:10, /* max allowed value: 1023 */ -+ cwnd_gain:11; /* max allowed value: 2047 */ -+ u32 cwnd_min_target:4, /* max allowed value: 15 */ -+ min_rtt_win_sec:5, /* max allowed value: 31 */ -+ probe_rtt_mode_ms:9, /* max allowed value: 511 */ -+ full_bw_cnt:3, /* max allowed value: 7 */ -+ cwnd_tso_budget:1, /* allowed values: {0, 1} */ -+ unused3:6, -+ drain_to_target:1, /* boolean */ -+ precise_ece_ack:1, /* boolean */ -+ extra_acked_in_startup:1, /* allowed values: {0, 1} */ -+ fast_path:1; /* boolean */ -+ u32 full_bw_thresh:10, /* max allowed value: 1023 */ -+ startup_cwnd_gain:11, /* max allowed value: 2047 */ -+ bw_probe_pif_gain:9, /* max allowed value: 511 */ -+ usage_based_cwnd:1, /* boolean */ -+ unused2:1; -+ u16 probe_rtt_win_ms:14, /* max allowed value: 16383 */ -+ refill_add_inc:2; /* max allowed value: 3 */ -+ u16 extra_acked_gain:11, /* max allowed value: 2047 */ -+ extra_acked_win_rtts:5; /* max allowed value: 31*/ -+ u16 pacing_gain[CYCLE_LEN]; /* max allowed value: 1023 */ -+ /* Mostly BBR v2 parameters below here: */ -+ u32 ecn_alpha_gain:8, /* max allowed value: 255 */ -+ ecn_factor:8, /* max allowed value: 255 */ -+ ecn_thresh:8, /* max allowed value: 255 */ -+ beta:8; /* max allowed value: 255 */ -+ u32 ecn_max_rtt_us:19, /* max allowed value: 524287 */ -+ bw_probe_reno_gain:9, /* max allowed value: 511 */ -+ full_loss_cnt:4; /* max allowed value: 15 */ -+ u32 probe_rtt_cwnd_gain:8, /* max allowed value: 255 */ -+ inflight_headroom:8, /* max allowed value: 255 */ -+ loss_thresh:8, /* max allowed value: 255 */ -+ bw_probe_max_rounds:8; /* max allowed value: 255 */ -+ u32 bw_probe_rand_rounds:4, /* max allowed value: 15 */ -+ bw_probe_base_us:26, /* usecs: 0..2^26-1 (67 secs) */ -+ full_ecn_cnt:2; /* max allowed value: 3 */ -+ u32 bw_probe_rand_us:26, /* usecs: 0..2^26-1 (67 secs) */ -+ undo:1, /* boolean */ -+ tso_rtt_shift:4, /* max allowed value: 15 */ -+ unused5:1; -+ u32 ecn_reprobe_gain:9, /* max allowed value: 511 */ -+ unused1:14, -+ ecn_alpha_init:9; /* max allowed value: 256 */ -+ } params; -+ -+ struct { -+ u32 snd_isn; /* Initial sequence number */ -+ u32 rs_bw; /* last valid rate sample bw */ -+ u32 target_cwnd; /* target cwnd, based on BDP */ -+ u8 undo:1, /* Undo even happened but not yet logged */ -+ unused:7; -+ char event; /* single-letter event debug codes */ -+ u16 unused2; -+ } debug; -+}; -+ -+struct bbr_context { -+ u32 sample_bw; -+ u32 target_cwnd; -+ u32 log:1; -+}; -+ -+/* Window length of min_rtt filter (in sec). Max allowed value is 31 (0x1F) */ -+static u32 bbr_min_rtt_win_sec = 10; -+/* Minimum time (in ms) spent at bbr_cwnd_min_target in BBR_PROBE_RTT mode. -+ * Max allowed value is 511 (0x1FF). -+ */ -+static u32 bbr_probe_rtt_mode_ms = 200; -+/* Window length of probe_rtt_min_us filter (in ms), and consequently the -+ * typical interval between PROBE_RTT mode entries. -+ * Note that bbr_probe_rtt_win_ms must be <= bbr_min_rtt_win_sec * MSEC_PER_SEC -+ */ -+static u32 bbr_probe_rtt_win_ms = 5000; -+/* Skip TSO below the following bandwidth (bits/sec): */ -+static int bbr_min_tso_rate = 1200000; -+ -+/* Use min_rtt to help adapt TSO burst size, with smaller min_rtt resulting -+ * in bigger TSO bursts. By default we cut the RTT-based allowance in half -+ * for every 2^9 usec (aka 512 us) of RTT, so that the RTT-based allowance -+ * is below 1500 bytes after 6 * ~500 usec = 3ms. -+ */ -+static u32 bbr_tso_rtt_shift = 9; /* halve allowance per 2^9 usecs, 512us */ -+ -+/* Select cwnd TSO budget approach: -+ * 0: padding -+ * 1: flooring -+ */ -+static uint bbr_cwnd_tso_budget = 1; -+ -+/* Pace at ~1% below estimated bw, on average, to reduce queue at bottleneck. -+ * In order to help drive the network toward lower queues and low latency while -+ * maintaining high utilization, the average pacing rate aims to be slightly -+ * lower than the estimated bandwidth. This is an important aspect of the -+ * design. -+ */ -+static const int bbr_pacing_margin_percent = 1; -+ -+/* We use a high_gain value of 2/ln(2) because it's the smallest pacing gain -+ * that will allow a smoothly increasing pacing rate that will double each RTT -+ * and send the same number of packets per RTT that an un-paced, slow-starting -+ * Reno or CUBIC flow would. Max allowed value is 2047 (0x7FF). -+ */ -+static int bbr_high_gain = BBR_UNIT * 2885 / 1000 + 1; -+/* The gain for deriving startup cwnd. Max allowed value is 2047 (0x7FF). */ -+static int bbr_startup_cwnd_gain = BBR_UNIT * 2885 / 1000 + 1; -+/* The pacing gain of 1/high_gain in BBR_DRAIN is calculated to typically drain -+ * the queue created in BBR_STARTUP in a single round. Max allowed value -+ * is 1023 (0x3FF). -+ */ -+static int bbr_drain_gain = BBR_UNIT * 1000 / 2885; -+/* The gain for deriving steady-state cwnd tolerates delayed/stretched ACKs. -+ * Max allowed value is 2047 (0x7FF). -+ */ -+static int bbr_cwnd_gain = BBR_UNIT * 2; -+/* The pacing_gain values for the PROBE_BW gain cycle, to discover/share bw. -+ * Max allowed value for each element is 1023 (0x3FF). -+ */ -+enum bbr_pacing_gain_phase { -+ BBR_BW_PROBE_UP = 0, /* push up inflight to probe for bw/vol */ -+ BBR_BW_PROBE_DOWN = 1, /* drain excess inflight from the queue */ -+ BBR_BW_PROBE_CRUISE = 2, /* use pipe, w/ headroom in queue/pipe */ -+ BBR_BW_PROBE_REFILL = 3, /* v2: refill the pipe again to 100% */ -+}; -+static int bbr_pacing_gain[] = { -+ BBR_UNIT * 5 / 4, /* probe for more available bw */ -+ BBR_UNIT * 3 / 4, /* drain queue and/or yield bw to other flows */ -+ BBR_UNIT, BBR_UNIT, BBR_UNIT, /* cruise at 1.0*bw to utilize pipe, */ -+ BBR_UNIT, BBR_UNIT, BBR_UNIT /* without creating excess queue... */ -+}; -+ -+/* Try to keep at least this many packets in flight, if things go smoothly. For -+ * smooth functioning, a sliding window protocol ACKing every other packet -+ * needs at least 4 packets in flight. Max allowed value is 15 (0xF). -+ */ -+static u32 bbr_cwnd_min_target = 4; -+ -+/* Cwnd to BDP proportion in PROBE_RTT mode scaled by BBR_UNIT. Default: 50%. -+ * Use 0 to disable. Max allowed value is 255. -+ */ -+static u32 bbr_probe_rtt_cwnd_gain = BBR_UNIT * 1 / 2; -+ -+/* To estimate if BBR_STARTUP mode (i.e. high_gain) has filled pipe... */ -+/* If bw has increased significantly (1.25x), there may be more bw available. -+ * Max allowed value is 1023 (0x3FF). -+ */ -+static u32 bbr_full_bw_thresh = BBR_UNIT * 5 / 4; -+/* But after 3 rounds w/o significant bw growth, estimate pipe is full. -+ * Max allowed value is 7 (0x7). -+ */ -+static u32 bbr_full_bw_cnt = 3; -+ -+static u32 bbr_flags; /* Debugging related stuff */ -+ -+/* Whether to debug using printk. -+ */ -+static bool bbr_debug_with_printk; -+ -+/* Whether to debug using ftrace event tcp:tcp_bbr_event. -+ * Ignored when bbr_debug_with_printk is set. -+ */ -+static bool bbr_debug_ftrace; -+ -+/* Experiment: each cycle, try to hold sub-unity gain until inflight <= BDP. */ -+static bool bbr_drain_to_target = true; /* default: enabled */ -+ -+/* Experiment: Flags to control BBR with ECN behavior. -+ */ -+static bool bbr_precise_ece_ack = true; /* default: enabled */ -+ -+/* The max rwin scaling shift factor is 14 (RFC 1323), so the max sane rwin is -+ * (2^(16+14) B)/(1024 B/packet) = 1M packets. -+ */ -+static u32 bbr_cwnd_warn_val = 1U << 20; -+ -+static u16 bbr_debug_port_mask; -+ -+/* BBR module parameters. These are module parameters only in Google prod. -+ * Upstream these are intentionally not module parameters. -+ */ -+static int bbr_pacing_gain_size = CYCLE_LEN; -+ -+/* Gain factor for adding extra_acked to target cwnd: */ -+static int bbr_extra_acked_gain = 256; -+ -+/* Window length of extra_acked window. Max allowed val is 31. */ -+static u32 bbr_extra_acked_win_rtts = 5; -+ -+/* Max allowed val for ack_epoch_acked, after which sampling epoch is reset */ -+static u32 bbr_ack_epoch_acked_reset_thresh = 1U << 20; -+ -+/* Time period for clamping cwnd increment due to ack aggregation */ -+static u32 bbr_extra_acked_max_us = 100 * 1000; -+ -+/* Use extra acked in startup ? -+ * 0: disabled -+ * 1: use latest extra_acked value from 1-2 rtt in startup -+ */ -+static int bbr_extra_acked_in_startup = 1; /* default: enabled */ -+ -+/* Experiment: don't grow cwnd beyond twice of what we just probed. */ -+static bool bbr_usage_based_cwnd; /* default: disabled */ -+ -+/* For lab testing, researchers can enable BBRv2 ECN support with this flag, -+ * when they know that any ECN marks that the connections experience will be -+ * DCTCP/L4S-style ECN marks, rather than RFC3168 ECN marks. -+ * TODO(ncardwell): Production use of the BBRv2 ECN functionality depends on -+ * negotiation or configuration that is outside the scope of the BBRv2 -+ * alpha release. -+ */ -+static bool bbr_ecn_enable = false; -+ -+module_param_named(min_tso_rate, bbr_min_tso_rate, int, 0644); -+module_param_named(tso_rtt_shift, bbr_tso_rtt_shift, int, 0644); -+module_param_named(high_gain, bbr_high_gain, int, 0644); -+module_param_named(drain_gain, bbr_drain_gain, int, 0644); -+module_param_named(startup_cwnd_gain, bbr_startup_cwnd_gain, int, 0644); -+module_param_named(cwnd_gain, bbr_cwnd_gain, int, 0644); -+module_param_array_named(pacing_gain, bbr_pacing_gain, int, -+ &bbr_pacing_gain_size, 0644); -+module_param_named(cwnd_min_target, bbr_cwnd_min_target, uint, 0644); -+module_param_named(probe_rtt_cwnd_gain, -+ bbr_probe_rtt_cwnd_gain, uint, 0664); -+module_param_named(cwnd_warn_val, bbr_cwnd_warn_val, uint, 0664); -+module_param_named(debug_port_mask, bbr_debug_port_mask, ushort, 0644); -+module_param_named(flags, bbr_flags, uint, 0644); -+module_param_named(debug_ftrace, bbr_debug_ftrace, bool, 0644); -+module_param_named(debug_with_printk, bbr_debug_with_printk, bool, 0644); -+module_param_named(min_rtt_win_sec, bbr_min_rtt_win_sec, uint, 0644); -+module_param_named(probe_rtt_mode_ms, bbr_probe_rtt_mode_ms, uint, 0644); -+module_param_named(probe_rtt_win_ms, bbr_probe_rtt_win_ms, uint, 0644); -+module_param_named(full_bw_thresh, bbr_full_bw_thresh, uint, 0644); -+module_param_named(full_bw_cnt, bbr_full_bw_cnt, uint, 0644); -+module_param_named(cwnd_tso_bduget, bbr_cwnd_tso_budget, uint, 0664); -+module_param_named(extra_acked_gain, bbr_extra_acked_gain, int, 0664); -+module_param_named(extra_acked_win_rtts, -+ bbr_extra_acked_win_rtts, uint, 0664); -+module_param_named(extra_acked_max_us, -+ bbr_extra_acked_max_us, uint, 0664); -+module_param_named(ack_epoch_acked_reset_thresh, -+ bbr_ack_epoch_acked_reset_thresh, uint, 0664); -+module_param_named(drain_to_target, bbr_drain_to_target, bool, 0664); -+module_param_named(precise_ece_ack, bbr_precise_ece_ack, bool, 0664); -+module_param_named(extra_acked_in_startup, -+ bbr_extra_acked_in_startup, int, 0664); -+module_param_named(usage_based_cwnd, bbr_usage_based_cwnd, bool, 0664); -+module_param_named(ecn_enable, bbr_ecn_enable, bool, 0664); -+ -+static void bbr2_exit_probe_rtt(struct sock *sk); -+static void bbr2_reset_congestion_signals(struct sock *sk); -+ -+static void bbr_check_probe_rtt_done(struct sock *sk); -+ -+/* Do we estimate that STARTUP filled the pipe? */ -+static bool bbr_full_bw_reached(const struct sock *sk) -+{ -+ const struct bbr *bbr = inet_csk_ca(sk); -+ -+ return bbr->full_bw_reached; -+} -+ -+/* Return the windowed max recent bandwidth sample, in pkts/uS << BW_SCALE. */ -+static u32 bbr_max_bw(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return max(bbr->bw_hi[0], bbr->bw_hi[1]); -+} -+ -+/* Return the estimated bandwidth of the path, in pkts/uS << BW_SCALE. */ -+static u32 bbr_bw(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return min(bbr_max_bw(sk), bbr->bw_lo); -+} -+ -+/* Return maximum extra acked in past k-2k round trips, -+ * where k = bbr_extra_acked_win_rtts. -+ */ -+static u16 bbr_extra_acked(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return max(bbr->extra_acked[0], bbr->extra_acked[1]); -+} -+ -+/* Return rate in bytes per second, optionally with a gain. -+ * The order here is chosen carefully to avoid overflow of u64. This should -+ * work for input rates of up to 2.9Tbit/sec and gain of 2.89x. -+ */ -+static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain, -+ int margin) -+{ -+ unsigned int mss = tcp_sk(sk)->mss_cache; -+ -+ rate *= mss; -+ rate *= gain; -+ rate >>= BBR_SCALE; -+ rate *= USEC_PER_SEC / 100 * (100 - margin); -+ rate >>= BW_SCALE; -+ rate = max(rate, 1ULL); -+ return rate; -+} -+ -+static u64 bbr_bw_bytes_per_sec(struct sock *sk, u64 rate) -+{ -+ return bbr_rate_bytes_per_sec(sk, rate, BBR_UNIT, 0); -+} -+ -+static u64 bbr_rate_kbps(struct sock *sk, u64 rate) -+{ -+ rate = bbr_bw_bytes_per_sec(sk, rate); -+ rate *= 8; -+ do_div(rate, 1000); -+ return rate; -+} -+ -+static u32 bbr_tso_segs_goal(struct sock *sk); -+static void bbr_debug(struct sock *sk, u32 acked, -+ const struct rate_sample *rs, struct bbr_context *ctx) -+{ -+ static const char ca_states[] = { -+ [TCP_CA_Open] = 'O', -+ [TCP_CA_Disorder] = 'D', -+ [TCP_CA_CWR] = 'C', -+ [TCP_CA_Recovery] = 'R', -+ [TCP_CA_Loss] = 'L', -+ }; -+ static const char mode[] = { -+ 'G', /* Growing - BBR_STARTUP */ -+ 'D', /* Drain - BBR_DRAIN */ -+ 'W', /* Window - BBR_PROBE_BW */ -+ 'M', /* Min RTT - BBR_PROBE_RTT */ -+ }; -+ static const char ack_phase[] = { /* bbr_ack_phase strings */ -+ 'I', /* BBR_ACKS_INIT - 'Init' */ -+ 'R', /* BBR_ACKS_REFILLING - 'Refilling' */ -+ 'B', /* BBR_ACKS_PROBE_STARTING - 'Before' */ -+ 'F', /* BBR_ACKS_PROBE_FEEDBACK - 'Feedback' */ -+ 'A', /* BBR_ACKS_PROBE_STOPPING - 'After' */ -+ }; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ const u32 una = tp->snd_una - bbr->debug.snd_isn; -+ const u32 fack = tcp_highest_sack_seq(tp); -+ const u16 dport = ntohs(inet_sk(sk)->inet_dport); -+ bool is_port_match = (bbr_debug_port_mask && -+ ((dport & bbr_debug_port_mask) == 0)); -+ char debugmsg[320]; -+ -+ if (sk->sk_state == TCP_SYN_SENT) -+ return; /* no bbr_init() yet if SYN retransmit -> CA_Loss */ -+ -+ if (!tp->snd_cwnd || tp->snd_cwnd > bbr_cwnd_warn_val) { -+ char addr[INET6_ADDRSTRLEN + 10] = { 0 }; -+ -+ if (sk->sk_family == AF_INET) -+ snprintf(addr, sizeof(addr), "%pI4:%u", -+ &inet_sk(sk)->inet_daddr, dport); -+ else if (sk->sk_family == AF_INET6) -+ snprintf(addr, sizeof(addr), "%pI6:%u", -+ &sk->sk_v6_daddr, dport); -+ -+ WARN_ONCE(1, -+ "BBR %s cwnd alert: %u " -+ "snd_una: %u ca: %d pacing_gain: %u cwnd_gain: %u " -+ "bw: %u rtt: %u min_rtt: %u " -+ "acked: %u tso_segs: %u " -+ "bw: %d %ld %d pif: %u\n", -+ addr, tp->snd_cwnd, -+ una, inet_csk(sk)->icsk_ca_state, -+ bbr->pacing_gain, bbr->cwnd_gain, -+ bbr_max_bw(sk), (tp->srtt_us >> 3), bbr->min_rtt_us, -+ acked, bbr_tso_segs_goal(sk), -+ rs->delivered, rs->interval_us, rs->is_retrans, -+ tcp_packets_in_flight(tp)); -+ } -+ -+ if (likely(!bbr_debug_with_printk && !bbr_debug_ftrace)) -+ return; -+ -+ if (!sock_flag(sk, SOCK_DBG) && !is_port_match) -+ return; -+ -+ if (!ctx->log && !tp->app_limited && !(bbr_flags & FLAG_DEBUG_VERBOSE)) -+ return; -+ -+ if (ipv4_is_loopback(inet_sk(sk)->inet_daddr) && -+ !(bbr_flags & FLAG_DEBUG_LOOPBACK)) -+ return; -+ -+ snprintf(debugmsg, sizeof(debugmsg) - 1, -+ "BBR %pI4:%-5u %5u,%03u:%-7u %c " -+ "%c %2u br %2u cr %2d rtt %5ld d %2d i %5ld mrtt %d %cbw %llu " -+ "bw %llu lb %llu ib %llu qb %llu " -+ "a %u if %2u %c %c dl %u l %u al %u # %u t %u %c %c " -+ "lr %d er %d ea %d bwl %lld il %d ih %d c %d " -+ "v %d %c %u %c %s\n", -+ &inet_sk(sk)->inet_daddr, dport, -+ una / 1000, una % 1000, fack - tp->snd_una, -+ ca_states[inet_csk(sk)->icsk_ca_state], -+ bbr->debug.undo ? '@' : mode[bbr->mode], -+ tp->snd_cwnd, -+ bbr_extra_acked(sk), /* br (legacy): extra_acked */ -+ rs->tx_in_flight, /* cr (legacy): tx_inflight */ -+ rs->rtt_us, -+ rs->delivered, -+ rs->interval_us, -+ bbr->min_rtt_us, -+ rs->is_app_limited ? '_' : 'l', -+ bbr_rate_kbps(sk, ctx->sample_bw), /* lbw: latest sample bw */ -+ bbr_rate_kbps(sk, bbr_max_bw(sk)), /* bw: max bw */ -+ 0ULL, /* lb: [obsolete] */ -+ 0ULL, /* ib: [obsolete] */ -+ (u64)sk->sk_pacing_rate * 8 / 1000, -+ acked, -+ tcp_packets_in_flight(tp), -+ rs->is_ack_delayed ? 'd' : '.', -+ bbr->round_start ? '*' : '.', -+ tp->delivered, tp->lost, -+ tp->app_limited, -+ 0, /* #: [obsolete] */ -+ ctx->target_cwnd, -+ tp->reord_seen ? 'r' : '.', /* r: reordering seen? */ -+ ca_states[bbr->prev_ca_state], -+ (rs->lost + rs->delivered) > 0 ? -+ (1000 * rs->lost / -+ (rs->lost + rs->delivered)) : 0, /* lr: loss rate x1000 */ -+ (rs->delivered) > 0 ? -+ (1000 * rs->delivered_ce / -+ (rs->delivered)) : 0, /* er: ECN rate x1000 */ -+ 1000 * bbr->ecn_alpha >> BBR_SCALE, /* ea: ECN alpha x1000 */ -+ bbr->bw_lo == ~0U ? -+ -1 : (s64)bbr_rate_kbps(sk, bbr->bw_lo), /* bwl */ -+ bbr->inflight_lo, /* il */ -+ bbr->inflight_hi, /* ih */ -+ bbr->bw_probe_up_cnt, /* c */ -+ 2, /* v: version */ -+ bbr->debug.event, -+ bbr->cycle_idx, -+ ack_phase[bbr->ack_phase], -+ bbr->bw_probe_samples ? "Y" : "N"); -+ debugmsg[sizeof(debugmsg) - 1] = 0; -+ -+ /* printk takes a higher precedence. */ -+ if (bbr_debug_with_printk) -+ printk(KERN_DEBUG "%s", debugmsg); -+ -+ if (unlikely(bbr->debug.undo)) -+ bbr->debug.undo = 0; -+} -+ -+/* Convert a BBR bw and gain factor to a pacing rate in bytes per second. */ -+static unsigned long bbr_bw_to_pacing_rate(struct sock *sk, u32 bw, int gain) -+{ -+ u64 rate = bw; -+ -+ rate = bbr_rate_bytes_per_sec(sk, rate, gain, -+ bbr_pacing_margin_percent); -+ rate = min_t(u64, rate, sk->sk_max_pacing_rate); -+ return rate; -+} -+ -+/* Initialize pacing rate to: high_gain * init_cwnd / RTT. */ -+static void bbr_init_pacing_rate_from_rtt(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw; -+ u32 rtt_us; -+ -+ if (tp->srtt_us) { /* any RTT sample yet? */ -+ rtt_us = max(tp->srtt_us >> 3, 1U); -+ bbr->has_seen_rtt = 1; -+ } else { /* no RTT sample yet */ -+ rtt_us = USEC_PER_MSEC; /* use nominal default RTT */ -+ } -+ bw = (u64)tp->snd_cwnd * BW_UNIT; -+ do_div(bw, rtt_us); -+ sk->sk_pacing_rate = bbr_bw_to_pacing_rate(sk, bw, bbr->params.high_gain); -+} -+ -+/* Pace using current bw estimate and a gain factor. */ -+static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ unsigned long rate = bbr_bw_to_pacing_rate(sk, bw, gain); -+ -+ if (unlikely(!bbr->has_seen_rtt && tp->srtt_us)) -+ bbr_init_pacing_rate_from_rtt(sk); -+ if (bbr_full_bw_reached(sk) || rate > sk->sk_pacing_rate) -+ sk->sk_pacing_rate = rate; -+} -+ -+static u32 bbr_min_tso_segs(struct sock *sk) -+{ -+ return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2; -+} -+ -+/* Return the number of segments BBR would like in a TSO/GSO skb, given -+ * a particular max gso size as a constraint. -+ */ -+static u32 bbr_tso_segs_generic(struct sock *sk, unsigned int mss_now, -+ u32 gso_max_size) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 segs, r; -+ u64 bytes; -+ -+ /* Budget a TSO/GSO burst size allowance based on bw (pacing_rate). */ -+ bytes = sk->sk_pacing_rate >> sk->sk_pacing_shift; -+ -+ /* Budget a TSO/GSO burst size allowance based on min_rtt. For every -+ * K = 2^tso_rtt_shift microseconds of min_rtt, halve the burst. -+ * The min_rtt-based burst allowance is: 64 KBytes / 2^(min_rtt/K) -+ */ -+ if (bbr->params.tso_rtt_shift) { -+ r = bbr->min_rtt_us >> bbr->params.tso_rtt_shift; -+ if (r < BITS_PER_TYPE(u32)) /* prevent undefined behavior */ -+ bytes += GSO_MAX_SIZE >> r; -+ } -+ -+ bytes = min_t(u32, bytes, gso_max_size - 1 - MAX_TCP_HEADER); -+ segs = max_t(u32, bytes / mss_now, bbr_min_tso_segs(sk)); -+ return segs; -+} -+ -+/* Custom tcp_tso_autosize() for BBR, used at transmit time to cap skb size. */ -+static u32 bbr_tso_segs(struct sock *sk, unsigned int mss_now) -+{ -+ return bbr_tso_segs_generic(sk, mss_now, sk->sk_gso_max_size); -+} -+ -+/* Like bbr_tso_segs(), using mss_cache, ignoring driver's sk_gso_max_size. */ -+static u32 bbr_tso_segs_goal(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ return bbr_tso_segs_generic(sk, tp->mss_cache, GSO_MAX_SIZE); -+} -+ -+/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */ -+static void bbr_save_cwnd(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->prev_ca_state < TCP_CA_Recovery && bbr->mode != BBR_PROBE_RTT) -+ bbr->prior_cwnd = tp->snd_cwnd; /* this cwnd is good enough */ -+ else /* loss recovery or BBR_PROBE_RTT have temporarily cut cwnd */ -+ bbr->prior_cwnd = max(bbr->prior_cwnd, tp->snd_cwnd); -+} -+ -+static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (event == CA_EVENT_TX_START && tp->app_limited) { -+ bbr->idle_restart = 1; -+ bbr->ack_epoch_mstamp = tp->tcp_mstamp; -+ bbr->ack_epoch_acked = 0; -+ /* Avoid pointless buffer overflows: pace at est. bw if we don't -+ * need more speed (we're restarting from idle and app-limited). -+ */ -+ if (bbr->mode == BBR_PROBE_BW) -+ bbr_set_pacing_rate(sk, bbr_bw(sk), BBR_UNIT); -+ else if (bbr->mode == BBR_PROBE_RTT) -+ bbr_check_probe_rtt_done(sk); -+ } else if ((event == CA_EVENT_ECN_IS_CE || -+ event == CA_EVENT_ECN_NO_CE) && -+ bbr_ecn_enable && -+ bbr->params.precise_ece_ack) { -+ u32 state = bbr->ce_state; -+ dctcp_ece_ack_update(sk, event, &bbr->prior_rcv_nxt, &state); -+ bbr->ce_state = state; -+ if (tp->fast_ack_mode == 2 && event == CA_EVENT_ECN_IS_CE) -+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); -+ } -+} -+ -+/* Calculate bdp based on min RTT and the estimated bottleneck bandwidth: -+ * -+ * bdp = ceil(bw * min_rtt * gain) -+ * -+ * The key factor, gain, controls the amount of queue. While a small gain -+ * builds a smaller queue, it becomes more vulnerable to noise in RTT -+ * measurements (e.g., delayed ACKs or other ACK compression effects). This -+ * noise may cause BBR to under-estimate the rate. -+ */ -+static u32 bbr_bdp(struct sock *sk, u32 bw, int gain) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 bdp; -+ u64 w; -+ -+ /* If we've never had a valid RTT sample, cap cwnd at the initial -+ * default. This should only happen when the connection is not using TCP -+ * timestamps and has retransmitted all of the SYN/SYNACK/data packets -+ * ACKed so far. In this case, an RTO can cut cwnd to 1, in which -+ * case we need to slow-start up toward something safe: initial cwnd. -+ */ -+ if (unlikely(bbr->min_rtt_us == ~0U)) /* no valid RTT samples yet? */ -+ return bbr->init_cwnd; /* be safe: cap at initial cwnd */ -+ -+ w = (u64)bw * bbr->min_rtt_us; -+ -+ /* Apply a gain to the given value, remove the BW_SCALE shift, and -+ * round the value up to avoid a negative feedback loop. -+ */ -+ bdp = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT; -+ -+ return bdp; -+} -+ -+/* To achieve full performance in high-speed paths, we budget enough cwnd to -+ * fit full-sized skbs in-flight on both end hosts to fully utilize the path: -+ * - one skb in sending host Qdisc, -+ * - one skb in sending host TSO/GSO engine -+ * - one skb being received by receiver host LRO/GRO/delayed-ACK engine -+ * Don't worry, at low rates (bbr_min_tso_rate) this won't bloat cwnd because -+ * in such cases tso_segs_goal is 1. The minimum cwnd is 4 packets, -+ * which allows 2 outstanding 2-packet sequences, to try to keep pipe -+ * full even with ACK-every-other-packet delayed ACKs. -+ */ -+static u32 bbr_quantization_budget(struct sock *sk, u32 cwnd) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 tso_segs_goal; -+ -+ tso_segs_goal = 3 * bbr_tso_segs_goal(sk); -+ -+ /* Allow enough full-sized skbs in flight to utilize end systems. */ -+ if (bbr->params.cwnd_tso_budget == 1) { -+ cwnd = max_t(u32, cwnd, tso_segs_goal); -+ cwnd = max_t(u32, cwnd, bbr->params.cwnd_min_target); -+ } else { -+ cwnd += tso_segs_goal; -+ cwnd = (cwnd + 1) & ~1U; -+ } -+ /* Ensure gain cycling gets inflight above BDP even for small BDPs. */ -+ if (bbr->mode == BBR_PROBE_BW && bbr->cycle_idx == BBR_BW_PROBE_UP) -+ cwnd += 2; -+ -+ return cwnd; -+} -+ -+/* Find inflight based on min RTT and the estimated bottleneck bandwidth. */ -+static u32 bbr_inflight(struct sock *sk, u32 bw, int gain) -+{ -+ u32 inflight; -+ -+ inflight = bbr_bdp(sk, bw, gain); -+ inflight = bbr_quantization_budget(sk, inflight); -+ -+ return inflight; -+} -+ -+/* With pacing at lower layers, there's often less data "in the network" than -+ * "in flight". With TSQ and departure time pacing at lower layers (e.g. fq), -+ * we often have several skbs queued in the pacing layer with a pre-scheduled -+ * earliest departure time (EDT). BBR adapts its pacing rate based on the -+ * inflight level that it estimates has already been "baked in" by previous -+ * departure time decisions. We calculate a rough estimate of the number of our -+ * packets that might be in the network at the earliest departure time for the -+ * next skb scheduled: -+ * in_network_at_edt = inflight_at_edt - (EDT - now) * bw -+ * If we're increasing inflight, then we want to know if the transmit of the -+ * EDT skb will push inflight above the target, so inflight_at_edt includes -+ * bbr_tso_segs_goal() from the skb departing at EDT. If decreasing inflight, -+ * then estimate if inflight will sink too low just before the EDT transmit. -+ */ -+static u32 bbr_packets_in_net_at_edt(struct sock *sk, u32 inflight_now) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 now_ns, edt_ns, interval_us; -+ u32 interval_delivered, inflight_at_edt; -+ -+ now_ns = tp->tcp_clock_cache; -+ edt_ns = max(tp->tcp_wstamp_ns, now_ns); -+ interval_us = div_u64(edt_ns - now_ns, NSEC_PER_USEC); -+ interval_delivered = (u64)bbr_bw(sk) * interval_us >> BW_SCALE; -+ inflight_at_edt = inflight_now; -+ if (bbr->pacing_gain > BBR_UNIT) /* increasing inflight */ -+ inflight_at_edt += bbr_tso_segs_goal(sk); /* include EDT skb */ -+ if (interval_delivered >= inflight_at_edt) -+ return 0; -+ return inflight_at_edt - interval_delivered; -+} -+ -+/* Find the cwnd increment based on estimate of ack aggregation */ -+static u32 bbr_ack_aggregation_cwnd(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 max_aggr_cwnd, aggr_cwnd = 0; -+ -+ if (bbr->params.extra_acked_gain && -+ (bbr_full_bw_reached(sk) || bbr->params.extra_acked_in_startup)) { -+ max_aggr_cwnd = ((u64)bbr_bw(sk) * bbr_extra_acked_max_us) -+ / BW_UNIT; -+ aggr_cwnd = (bbr->params.extra_acked_gain * bbr_extra_acked(sk)) -+ >> BBR_SCALE; -+ aggr_cwnd = min(aggr_cwnd, max_aggr_cwnd); -+ } -+ -+ return aggr_cwnd; -+} -+ -+/* Returns the cwnd for PROBE_RTT mode. */ -+static u32 bbr_probe_rtt_cwnd(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->params.probe_rtt_cwnd_gain == 0) -+ return bbr->params.cwnd_min_target; -+ return max_t(u32, bbr->params.cwnd_min_target, -+ bbr_bdp(sk, bbr_bw(sk), bbr->params.probe_rtt_cwnd_gain)); -+} -+ -+/* Slow-start up toward target cwnd (if bw estimate is growing, or packet loss -+ * has drawn us down below target), or snap down to target if we're above it. -+ */ -+static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs, -+ u32 acked, u32 bw, int gain, u32 cwnd, -+ struct bbr_context *ctx) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 target_cwnd = 0, prev_cwnd = tp->snd_cwnd, max_probe; -+ -+ if (!acked) -+ goto done; /* no packet fully ACKed; just apply caps */ -+ -+ target_cwnd = bbr_bdp(sk, bw, gain); -+ -+ /* Increment the cwnd to account for excess ACKed data that seems -+ * due to aggregation (of data and/or ACKs) visible in the ACK stream. -+ */ -+ target_cwnd += bbr_ack_aggregation_cwnd(sk); -+ target_cwnd = bbr_quantization_budget(sk, target_cwnd); -+ -+ /* If we're below target cwnd, slow start cwnd toward target cwnd. */ -+ bbr->debug.target_cwnd = target_cwnd; -+ -+ /* Update cwnd and enable fast path if cwnd reaches target_cwnd. */ -+ bbr->try_fast_path = 0; -+ if (bbr_full_bw_reached(sk)) { /* only cut cwnd if we filled the pipe */ -+ cwnd += acked; -+ if (cwnd >= target_cwnd) { -+ cwnd = target_cwnd; -+ bbr->try_fast_path = 1; -+ } -+ } else if (cwnd < target_cwnd || cwnd < 2 * bbr->init_cwnd) { -+ cwnd += acked; -+ } else { -+ bbr->try_fast_path = 1; -+ } -+ -+ /* When growing cwnd, don't grow beyond twice what we just probed. */ -+ if (bbr->params.usage_based_cwnd) { -+ max_probe = max(2 * tp->max_packets_out, tp->snd_cwnd); -+ cwnd = min(cwnd, max_probe); -+ } -+ -+ cwnd = max_t(u32, cwnd, bbr->params.cwnd_min_target); -+done: -+ tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp); /* apply global cap */ -+ if (bbr->mode == BBR_PROBE_RTT) /* drain queue, refresh min_rtt */ -+ tp->snd_cwnd = min_t(u32, tp->snd_cwnd, bbr_probe_rtt_cwnd(sk)); -+ -+ ctx->target_cwnd = target_cwnd; -+ ctx->log = (tp->snd_cwnd != prev_cwnd); -+} -+ -+/* See if we have reached next round trip */ -+static void bbr_update_round_start(struct sock *sk, -+ const struct rate_sample *rs, struct bbr_context *ctx) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->round_start = 0; -+ -+ /* See if we've reached the next RTT */ -+ if (rs->interval_us > 0 && -+ !before(rs->prior_delivered, bbr->next_rtt_delivered)) { -+ bbr->next_rtt_delivered = tp->delivered; -+ bbr->round_start = 1; -+ } -+} -+ -+/* Calculate the bandwidth based on how fast packets are delivered */ -+static void bbr_calculate_bw_sample(struct sock *sk, -+ const struct rate_sample *rs, struct bbr_context *ctx) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw = 0; -+ -+ /* Divide delivered by the interval to find a (lower bound) bottleneck -+ * bandwidth sample. Delivered is in packets and interval_us in uS and -+ * ratio will be <<1 for most connections. So delivered is first scaled. -+ * Round up to allow growth at low rates, even with integer division. -+ */ -+ if (rs->interval_us > 0) { -+ if (WARN_ONCE(rs->delivered < 0, -+ "negative delivered: %d interval_us: %ld\n", -+ rs->delivered, rs->interval_us)) -+ return; -+ -+ bw = DIV_ROUND_UP_ULL((u64)rs->delivered * BW_UNIT, rs->interval_us); -+ } -+ -+ ctx->sample_bw = bw; -+ bbr->debug.rs_bw = bw; -+} -+ -+/* Estimates the windowed max degree of ack aggregation. -+ * This is used to provision extra in-flight data to keep sending during -+ * inter-ACK silences. -+ * -+ * Degree of ack aggregation is estimated as extra data acked beyond expected. -+ * -+ * max_extra_acked = "maximum recent excess data ACKed beyond max_bw * interval" -+ * cwnd += max_extra_acked -+ * -+ * Max extra_acked is clamped by cwnd and bw * bbr_extra_acked_max_us (100 ms). -+ * Max filter is an approximate sliding window of 5-10 (packet timed) round -+ * trips for non-startup phase, and 1-2 round trips for startup. -+ */ -+static void bbr_update_ack_aggregation(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ u32 epoch_us, expected_acked, extra_acked; -+ struct bbr *bbr = inet_csk_ca(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 extra_acked_win_rtts_thresh = bbr->params.extra_acked_win_rtts; -+ -+ if (!bbr->params.extra_acked_gain || rs->acked_sacked <= 0 || -+ rs->delivered < 0 || rs->interval_us <= 0) -+ return; -+ -+ if (bbr->round_start) { -+ bbr->extra_acked_win_rtts = min(0x1F, -+ bbr->extra_acked_win_rtts + 1); -+ if (bbr->params.extra_acked_in_startup && -+ !bbr_full_bw_reached(sk)) -+ extra_acked_win_rtts_thresh = 1; -+ if (bbr->extra_acked_win_rtts >= -+ extra_acked_win_rtts_thresh) { -+ bbr->extra_acked_win_rtts = 0; -+ bbr->extra_acked_win_idx = bbr->extra_acked_win_idx ? -+ 0 : 1; -+ bbr->extra_acked[bbr->extra_acked_win_idx] = 0; -+ } -+ } -+ -+ /* Compute how many packets we expected to be delivered over epoch. */ -+ epoch_us = tcp_stamp_us_delta(tp->delivered_mstamp, -+ bbr->ack_epoch_mstamp); -+ expected_acked = ((u64)bbr_bw(sk) * epoch_us) / BW_UNIT; -+ -+ /* Reset the aggregation epoch if ACK rate is below expected rate or -+ * significantly large no. of ack received since epoch (potentially -+ * quite old epoch). -+ */ -+ if (bbr->ack_epoch_acked <= expected_acked || -+ (bbr->ack_epoch_acked + rs->acked_sacked >= -+ bbr_ack_epoch_acked_reset_thresh)) { -+ bbr->ack_epoch_acked = 0; -+ bbr->ack_epoch_mstamp = tp->delivered_mstamp; -+ expected_acked = 0; -+ } -+ -+ /* Compute excess data delivered, beyond what was expected. */ -+ bbr->ack_epoch_acked = min_t(u32, 0xFFFFF, -+ bbr->ack_epoch_acked + rs->acked_sacked); -+ extra_acked = bbr->ack_epoch_acked - expected_acked; -+ extra_acked = min(extra_acked, tp->snd_cwnd); -+ if (extra_acked > bbr->extra_acked[bbr->extra_acked_win_idx]) -+ bbr->extra_acked[bbr->extra_acked_win_idx] = extra_acked; -+} -+ -+/* Estimate when the pipe is full, using the change in delivery rate: BBR -+ * estimates that STARTUP filled the pipe if the estimated bw hasn't changed by -+ * at least bbr_full_bw_thresh (25%) after bbr_full_bw_cnt (3) non-app-limited -+ * rounds. Why 3 rounds: 1: rwin autotuning grows the rwin, 2: we fill the -+ * higher rwin, 3: we get higher delivery rate samples. Or transient -+ * cross-traffic or radio noise can go away. CUBIC Hystart shares a similar -+ * design goal, but uses delay and inter-ACK spacing instead of bandwidth. -+ */ -+static void bbr_check_full_bw_reached(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 bw_thresh; -+ -+ if (bbr_full_bw_reached(sk) || !bbr->round_start || rs->is_app_limited) -+ return; -+ -+ bw_thresh = (u64)bbr->full_bw * bbr->params.full_bw_thresh >> BBR_SCALE; -+ if (bbr_max_bw(sk) >= bw_thresh) { -+ bbr->full_bw = bbr_max_bw(sk); -+ bbr->full_bw_cnt = 0; -+ return; -+ } -+ ++bbr->full_bw_cnt; -+ bbr->full_bw_reached = bbr->full_bw_cnt >= bbr->params.full_bw_cnt; -+} -+ -+/* If pipe is probably full, drain the queue and then enter steady-state. */ -+static bool bbr_check_drain(struct sock *sk, const struct rate_sample *rs, -+ struct bbr_context *ctx) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->mode == BBR_STARTUP && bbr_full_bw_reached(sk)) { -+ bbr->mode = BBR_DRAIN; /* drain queue we created */ -+ tcp_sk(sk)->snd_ssthresh = -+ bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT); -+ bbr2_reset_congestion_signals(sk); -+ } /* fall through to check if in-flight is already small: */ -+ if (bbr->mode == BBR_DRAIN && -+ bbr_packets_in_net_at_edt(sk, tcp_packets_in_flight(tcp_sk(sk))) <= -+ bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT)) -+ return true; /* exiting DRAIN now */ -+ return false; -+} -+ -+static void bbr_check_probe_rtt_done(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (!(bbr->probe_rtt_done_stamp && -+ after(tcp_jiffies32, bbr->probe_rtt_done_stamp))) -+ return; -+ -+ bbr->probe_rtt_min_stamp = tcp_jiffies32; /* schedule next PROBE_RTT */ -+ tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd); -+ bbr2_exit_probe_rtt(sk); -+} -+ -+/* The goal of PROBE_RTT mode is to have BBR flows cooperatively and -+ * periodically drain the bottleneck queue, to converge to measure the true -+ * min_rtt (unloaded propagation delay). This allows the flows to keep queues -+ * small (reducing queuing delay and packet loss) and achieve fairness among -+ * BBR flows. -+ * -+ * The min_rtt filter window is 10 seconds. When the min_rtt estimate expires, -+ * we enter PROBE_RTT mode and cap the cwnd at bbr_cwnd_min_target=4 packets. -+ * After at least bbr_probe_rtt_mode_ms=200ms and at least one packet-timed -+ * round trip elapsed with that flight size <= 4, we leave PROBE_RTT mode and -+ * re-enter the previous mode. BBR uses 200ms to approximately bound the -+ * performance penalty of PROBE_RTT's cwnd capping to roughly 2% (200ms/10s). -+ * -+ * Note that flows need only pay 2% if they are busy sending over the last 10 -+ * seconds. Interactive applications (e.g., Web, RPCs, video chunks) often have -+ * natural silences or low-rate periods within 10 seconds where the rate is low -+ * enough for long enough to drain its queue in the bottleneck. We pick up -+ * these min RTT measurements opportunistically with our min_rtt filter. :-) -+ */ -+static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ bool probe_rtt_expired, min_rtt_expired; -+ u32 expire; -+ -+ /* Track min RTT in probe_rtt_win_ms to time next PROBE_RTT state. */ -+ expire = bbr->probe_rtt_min_stamp + -+ msecs_to_jiffies(bbr->params.probe_rtt_win_ms); -+ probe_rtt_expired = after(tcp_jiffies32, expire); -+ if (rs->rtt_us >= 0 && -+ (rs->rtt_us <= bbr->probe_rtt_min_us || -+ (probe_rtt_expired && !rs->is_ack_delayed))) { -+ bbr->probe_rtt_min_us = rs->rtt_us; -+ bbr->probe_rtt_min_stamp = tcp_jiffies32; -+ } -+ /* Track min RTT seen in the min_rtt_win_sec filter window: */ -+ expire = bbr->min_rtt_stamp + bbr->params.min_rtt_win_sec * HZ; -+ min_rtt_expired = after(tcp_jiffies32, expire); -+ if (bbr->probe_rtt_min_us <= bbr->min_rtt_us || -+ min_rtt_expired) { -+ bbr->min_rtt_us = bbr->probe_rtt_min_us; -+ bbr->min_rtt_stamp = bbr->probe_rtt_min_stamp; -+ } -+ -+ if (bbr->params.probe_rtt_mode_ms > 0 && probe_rtt_expired && -+ !bbr->idle_restart && bbr->mode != BBR_PROBE_RTT) { -+ bbr->mode = BBR_PROBE_RTT; /* dip, drain queue */ -+ bbr_save_cwnd(sk); /* note cwnd so we can restore it */ -+ bbr->probe_rtt_done_stamp = 0; -+ bbr->ack_phase = BBR_ACKS_PROBE_STOPPING; -+ bbr->next_rtt_delivered = tp->delivered; -+ } -+ -+ if (bbr->mode == BBR_PROBE_RTT) { -+ /* Ignore low rate samples during this mode. */ -+ tp->app_limited = -+ (tp->delivered + tcp_packets_in_flight(tp)) ? : 1; -+ /* Maintain min packets in flight for max(200 ms, 1 round). */ -+ if (!bbr->probe_rtt_done_stamp && -+ tcp_packets_in_flight(tp) <= bbr_probe_rtt_cwnd(sk)) { -+ bbr->probe_rtt_done_stamp = tcp_jiffies32 + -+ msecs_to_jiffies(bbr->params.probe_rtt_mode_ms); -+ bbr->probe_rtt_round_done = 0; -+ bbr->next_rtt_delivered = tp->delivered; -+ } else if (bbr->probe_rtt_done_stamp) { -+ if (bbr->round_start) -+ bbr->probe_rtt_round_done = 1; -+ if (bbr->probe_rtt_round_done) -+ bbr_check_probe_rtt_done(sk); -+ } -+ } -+ /* Restart after idle ends only once we process a new S/ACK for data */ -+ if (rs->delivered > 0) -+ bbr->idle_restart = 0; -+} -+ -+static void bbr_update_gains(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ switch (bbr->mode) { -+ case BBR_STARTUP: -+ bbr->pacing_gain = bbr->params.high_gain; -+ bbr->cwnd_gain = bbr->params.startup_cwnd_gain; -+ break; -+ case BBR_DRAIN: -+ bbr->pacing_gain = bbr->params.drain_gain; /* slow, to drain */ -+ bbr->cwnd_gain = bbr->params.startup_cwnd_gain; /* keep cwnd */ -+ break; -+ case BBR_PROBE_BW: -+ bbr->pacing_gain = bbr->params.pacing_gain[bbr->cycle_idx]; -+ bbr->cwnd_gain = bbr->params.cwnd_gain; -+ break; -+ case BBR_PROBE_RTT: -+ bbr->pacing_gain = BBR_UNIT; -+ bbr->cwnd_gain = BBR_UNIT; -+ break; -+ default: -+ WARN_ONCE(1, "BBR bad mode: %u\n", bbr->mode); -+ break; -+ } -+} -+ -+static void bbr_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ int i; -+ -+ WARN_ON_ONCE(tp->snd_cwnd >= bbr_cwnd_warn_val); -+ -+ bbr->initialized = 1; -+ bbr->params.high_gain = min(0x7FF, bbr_high_gain); -+ bbr->params.drain_gain = min(0x3FF, bbr_drain_gain); -+ bbr->params.startup_cwnd_gain = min(0x7FF, bbr_startup_cwnd_gain); -+ bbr->params.cwnd_gain = min(0x7FF, bbr_cwnd_gain); -+ bbr->params.cwnd_tso_budget = min(0x1U, bbr_cwnd_tso_budget); -+ bbr->params.cwnd_min_target = min(0xFU, bbr_cwnd_min_target); -+ bbr->params.min_rtt_win_sec = min(0x1FU, bbr_min_rtt_win_sec); -+ bbr->params.probe_rtt_mode_ms = min(0x1FFU, bbr_probe_rtt_mode_ms); -+ bbr->params.full_bw_cnt = min(0x7U, bbr_full_bw_cnt); -+ bbr->params.full_bw_thresh = min(0x3FFU, bbr_full_bw_thresh); -+ bbr->params.extra_acked_gain = min(0x7FF, bbr_extra_acked_gain); -+ bbr->params.extra_acked_win_rtts = min(0x1FU, bbr_extra_acked_win_rtts); -+ bbr->params.drain_to_target = bbr_drain_to_target ? 1 : 0; -+ bbr->params.precise_ece_ack = bbr_precise_ece_ack ? 1 : 0; -+ bbr->params.extra_acked_in_startup = bbr_extra_acked_in_startup ? 1 : 0; -+ bbr->params.probe_rtt_cwnd_gain = min(0xFFU, bbr_probe_rtt_cwnd_gain); -+ bbr->params.probe_rtt_win_ms = -+ min(0x3FFFU, -+ min_t(u32, bbr_probe_rtt_win_ms, -+ bbr->params.min_rtt_win_sec * MSEC_PER_SEC)); -+ for (i = 0; i < CYCLE_LEN; i++) -+ bbr->params.pacing_gain[i] = min(0x3FF, bbr_pacing_gain[i]); -+ bbr->params.usage_based_cwnd = bbr_usage_based_cwnd ? 1 : 0; -+ bbr->params.tso_rtt_shift = min(0xFU, bbr_tso_rtt_shift); -+ -+ bbr->debug.snd_isn = tp->snd_una; -+ bbr->debug.target_cwnd = 0; -+ bbr->debug.undo = 0; -+ -+ bbr->init_cwnd = min(0x7FU, tp->snd_cwnd); -+ bbr->prior_cwnd = tp->prior_cwnd; -+ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; -+ bbr->next_rtt_delivered = 0; -+ bbr->prev_ca_state = TCP_CA_Open; -+ bbr->packet_conservation = 0; -+ -+ bbr->probe_rtt_done_stamp = 0; -+ bbr->probe_rtt_round_done = 0; -+ bbr->probe_rtt_min_us = tcp_min_rtt(tp); -+ bbr->probe_rtt_min_stamp = tcp_jiffies32; -+ bbr->min_rtt_us = tcp_min_rtt(tp); -+ bbr->min_rtt_stamp = tcp_jiffies32; -+ -+ bbr->has_seen_rtt = 0; -+ bbr_init_pacing_rate_from_rtt(sk); -+ -+ bbr->round_start = 0; -+ bbr->idle_restart = 0; -+ bbr->full_bw_reached = 0; -+ bbr->full_bw = 0; -+ bbr->full_bw_cnt = 0; -+ bbr->cycle_mstamp = 0; -+ bbr->cycle_idx = 0; -+ bbr->mode = BBR_STARTUP; -+ bbr->debug.rs_bw = 0; -+ -+ bbr->ack_epoch_mstamp = tp->tcp_mstamp; -+ bbr->ack_epoch_acked = 0; -+ bbr->extra_acked_win_rtts = 0; -+ bbr->extra_acked_win_idx = 0; -+ bbr->extra_acked[0] = 0; -+ bbr->extra_acked[1] = 0; -+ -+ bbr->ce_state = 0; -+ bbr->prior_rcv_nxt = tp->rcv_nxt; -+ bbr->try_fast_path = 0; -+ -+ cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED); -+} -+ -+static u32 bbr_sndbuf_expand(struct sock *sk) -+{ -+ /* Provision 3 * cwnd since BBR may slow-start even during recovery. */ -+ return 3; -+} -+ -+/* __________________________________________________________________________ -+ * -+ * Functions new to BBR v2 ("bbr") congestion control are below here. -+ * __________________________________________________________________________ -+ */ -+ -+/* Incorporate a new bw sample into the current window of our max filter. */ -+static void bbr2_take_bw_hi_sample(struct sock *sk, u32 bw) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->bw_hi[1] = max(bw, bbr->bw_hi[1]); -+} -+ -+/* Keep max of last 1-2 cycles. Each PROBE_BW cycle, flip filter window. */ -+static void bbr2_advance_bw_hi_filter(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (!bbr->bw_hi[1]) -+ return; /* no samples in this window; remember old window */ -+ bbr->bw_hi[0] = bbr->bw_hi[1]; -+ bbr->bw_hi[1] = 0; -+} -+ -+/* How much do we want in flight? Our BDP, unless congestion cut cwnd. */ -+static u32 bbr2_target_inflight(struct sock *sk) -+{ -+ u32 bdp = bbr_inflight(sk, bbr_bw(sk), BBR_UNIT); -+ -+ return min(bdp, tcp_sk(sk)->snd_cwnd); -+} -+ -+static bool bbr2_is_probing_bandwidth(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return (bbr->mode == BBR_STARTUP) || -+ (bbr->mode == BBR_PROBE_BW && -+ (bbr->cycle_idx == BBR_BW_PROBE_REFILL || -+ bbr->cycle_idx == BBR_BW_PROBE_UP)); -+} -+ -+/* Has the given amount of time elapsed since we marked the phase start? */ -+static bool bbr2_has_elapsed_in_phase(const struct sock *sk, u32 interval_us) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const struct bbr *bbr = inet_csk_ca(sk); -+ -+ return tcp_stamp_us_delta(tp->tcp_mstamp, -+ bbr->cycle_mstamp + interval_us) > 0; -+} -+ -+static void bbr2_handle_queue_too_high_in_startup(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->full_bw_reached = 1; -+ bbr->inflight_hi = bbr_inflight(sk, bbr_max_bw(sk), BBR_UNIT); -+} -+ -+/* Exit STARTUP upon N consecutive rounds with ECN mark rate > ecn_thresh. */ -+static void bbr2_check_ecn_too_high_in_startup(struct sock *sk, u32 ce_ratio) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr_full_bw_reached(sk) || !bbr->ecn_eligible || -+ !bbr->params.full_ecn_cnt || !bbr->params.ecn_thresh) -+ return; -+ -+ if (ce_ratio >= bbr->params.ecn_thresh) -+ bbr->startup_ecn_rounds++; -+ else -+ bbr->startup_ecn_rounds = 0; -+ -+ if (bbr->startup_ecn_rounds >= bbr->params.full_ecn_cnt) { -+ bbr->debug.event = 'E'; /* ECN caused STARTUP exit */ -+ bbr2_handle_queue_too_high_in_startup(sk); -+ return; -+ } -+} -+ -+static void bbr2_update_ecn_alpha(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ s32 delivered, delivered_ce; -+ u64 alpha, ce_ratio; -+ u32 gain; -+ -+ if (bbr->params.ecn_factor == 0) -+ return; -+ -+ delivered = tp->delivered - bbr->alpha_last_delivered; -+ delivered_ce = tp->delivered_ce - bbr->alpha_last_delivered_ce; -+ -+ if (delivered == 0 || /* avoid divide by zero */ -+ WARN_ON_ONCE(delivered < 0 || delivered_ce < 0)) /* backwards? */ -+ return; -+ -+ /* See if we should use ECN sender logic for this connection. */ -+ if (!bbr->ecn_eligible && bbr_ecn_enable && -+ (bbr->min_rtt_us <= bbr->params.ecn_max_rtt_us || -+ !bbr->params.ecn_max_rtt_us)) -+ bbr->ecn_eligible = 1; -+ -+ ce_ratio = (u64)delivered_ce << BBR_SCALE; -+ do_div(ce_ratio, delivered); -+ gain = bbr->params.ecn_alpha_gain; -+ alpha = ((BBR_UNIT - gain) * bbr->ecn_alpha) >> BBR_SCALE; -+ alpha += (gain * ce_ratio) >> BBR_SCALE; -+ bbr->ecn_alpha = min_t(u32, alpha, BBR_UNIT); -+ -+ bbr->alpha_last_delivered = tp->delivered; -+ bbr->alpha_last_delivered_ce = tp->delivered_ce; -+ -+ bbr2_check_ecn_too_high_in_startup(sk, ce_ratio); -+} -+ -+/* Each round trip of BBR_BW_PROBE_UP, double volume of probing data. */ -+static void bbr2_raise_inflight_hi_slope(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 growth_this_round, cnt; -+ -+ /* Calculate "slope": packets S/Acked per inflight_hi increment. */ -+ growth_this_round = 1 << bbr->bw_probe_up_rounds; -+ bbr->bw_probe_up_rounds = min(bbr->bw_probe_up_rounds + 1, 30); -+ cnt = tp->snd_cwnd / growth_this_round; -+ cnt = max(cnt, 1U); -+ bbr->bw_probe_up_cnt = cnt; -+ bbr->debug.event = 'G'; /* Grow inflight_hi slope */ -+} -+ -+/* In BBR_BW_PROBE_UP, not seeing high loss/ECN/queue, so raise inflight_hi. */ -+static void bbr2_probe_inflight_hi_upward(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 delta; -+ -+ if (!tp->is_cwnd_limited || tp->snd_cwnd < bbr->inflight_hi) { -+ bbr->bw_probe_up_acks = 0; /* don't accmulate unused credits */ -+ return; /* not fully using inflight_hi, so don't grow it */ -+ } -+ -+ /* For each bw_probe_up_cnt packets ACKed, increase inflight_hi by 1. */ -+ bbr->bw_probe_up_acks += rs->acked_sacked; -+ if (bbr->bw_probe_up_acks >= bbr->bw_probe_up_cnt) { -+ delta = bbr->bw_probe_up_acks / bbr->bw_probe_up_cnt; -+ bbr->bw_probe_up_acks -= delta * bbr->bw_probe_up_cnt; -+ bbr->inflight_hi += delta; -+ bbr->debug.event = 'I'; /* Increment inflight_hi */ -+ } -+ -+ if (bbr->round_start) -+ bbr2_raise_inflight_hi_slope(sk); -+} -+ -+/* Does loss/ECN rate for this sample say inflight is "too high"? -+ * This is used by both the bbr_check_loss_too_high_in_startup() function, -+ * which can be used in either v1 or v2, and the PROBE_UP phase of v2, which -+ * uses it to notice when loss/ECN rates suggest inflight is too high. -+ */ -+static bool bbr2_is_inflight_too_high(const struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ const struct bbr *bbr = inet_csk_ca(sk); -+ u32 loss_thresh, ecn_thresh; -+ -+ if (rs->lost > 0 && rs->tx_in_flight) { -+ loss_thresh = (u64)rs->tx_in_flight * bbr->params.loss_thresh >> -+ BBR_SCALE; -+ if (rs->lost > loss_thresh) -+ return true; -+ } -+ -+ if (rs->delivered_ce > 0 && rs->delivered > 0 && -+ bbr->ecn_eligible && bbr->params.ecn_thresh) { -+ ecn_thresh = (u64)rs->delivered * bbr->params.ecn_thresh >> -+ BBR_SCALE; -+ if (rs->delivered_ce >= ecn_thresh) -+ return true; -+ } -+ -+ return false; -+} -+ -+/* Calculate the tx_in_flight level that corresponded to excessive loss. -+ * We find "lost_prefix" segs of the skb where loss rate went too high, -+ * by solving for "lost_prefix" in the following equation: -+ * lost / inflight >= loss_thresh -+ * (lost_prev + lost_prefix) / (inflight_prev + lost_prefix) >= loss_thresh -+ * Then we take that equation, convert it to fixed point, and -+ * round up to the nearest packet. -+ */ -+static u32 bbr2_inflight_hi_from_lost_skb(const struct sock *sk, -+ const struct rate_sample *rs, -+ const struct sk_buff *skb) -+{ -+ const struct bbr *bbr = inet_csk_ca(sk); -+ u32 loss_thresh = bbr->params.loss_thresh; -+ u32 pcount, divisor, inflight_hi; -+ s32 inflight_prev, lost_prev; -+ u64 loss_budget, lost_prefix; -+ -+ pcount = tcp_skb_pcount(skb); -+ -+ /* How much data was in flight before this skb? */ -+ inflight_prev = rs->tx_in_flight - pcount; -+ if (WARN_ONCE(inflight_prev < 0, -+ "tx_in_flight: %u pcount: %u reneg: %u", -+ rs->tx_in_flight, pcount, tcp_sk(sk)->is_sack_reneg)) -+ return ~0U; -+ -+ /* How much inflight data was marked lost before this skb? */ -+ lost_prev = rs->lost - pcount; -+ if (WARN_ON_ONCE(lost_prev < 0)) -+ return ~0U; -+ -+ /* At what prefix of this lost skb did losss rate exceed loss_thresh? */ -+ loss_budget = (u64)inflight_prev * loss_thresh + BBR_UNIT - 1; -+ loss_budget >>= BBR_SCALE; -+ if (lost_prev >= loss_budget) { -+ lost_prefix = 0; /* previous losses crossed loss_thresh */ -+ } else { -+ lost_prefix = loss_budget - lost_prev; -+ lost_prefix <<= BBR_SCALE; -+ divisor = BBR_UNIT - loss_thresh; -+ if (WARN_ON_ONCE(!divisor)) /* loss_thresh is 8 bits */ -+ return ~0U; -+ do_div(lost_prefix, divisor); -+ } -+ -+ inflight_hi = inflight_prev + lost_prefix; -+ return inflight_hi; -+} -+ -+/* If loss/ECN rates during probing indicated we may have overfilled a -+ * buffer, return an operating point that tries to leave unutilized headroom in -+ * the path for other flows, for fairness convergence and lower RTTs and loss. -+ */ -+static u32 bbr2_inflight_with_headroom(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 headroom, headroom_fraction; -+ -+ if (bbr->inflight_hi == ~0U) -+ return ~0U; -+ -+ headroom_fraction = bbr->params.inflight_headroom; -+ headroom = ((u64)bbr->inflight_hi * headroom_fraction) >> BBR_SCALE; -+ headroom = max(headroom, 1U); -+ return max_t(s32, bbr->inflight_hi - headroom, -+ bbr->params.cwnd_min_target); -+} -+ -+/* Bound cwnd to a sensible level, based on our current probing state -+ * machine phase and model of a good inflight level (inflight_lo, inflight_hi). -+ */ -+static void bbr2_bound_cwnd_for_inflight_model(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 cap; -+ -+ /* tcp_rcv_synsent_state_process() currently calls tcp_ack() -+ * and thus cong_control() without first initializing us(!). -+ */ -+ if (!bbr->initialized) -+ return; -+ -+ cap = ~0U; -+ if (bbr->mode == BBR_PROBE_BW && -+ bbr->cycle_idx != BBR_BW_PROBE_CRUISE) { -+ /* Probe to see if more packets fit in the path. */ -+ cap = bbr->inflight_hi; -+ } else { -+ if (bbr->mode == BBR_PROBE_RTT || -+ (bbr->mode == BBR_PROBE_BW && -+ bbr->cycle_idx == BBR_BW_PROBE_CRUISE)) -+ cap = bbr2_inflight_with_headroom(sk); -+ } -+ /* Adapt to any loss/ECN since our last bw probe. */ -+ cap = min(cap, bbr->inflight_lo); -+ -+ cap = max_t(u32, cap, bbr->params.cwnd_min_target); -+ tp->snd_cwnd = min(cap, tp->snd_cwnd); -+} -+ -+/* Estimate a short-term lower bound on the capacity available now, based -+ * on measurements of the current delivery process and recent history. When we -+ * are seeing loss/ECN at times when we are not probing bw, then conservatively -+ * move toward flow balance by multiplicatively cutting our short-term -+ * estimated safe rate and volume of data (bw_lo and inflight_lo). We use a -+ * multiplicative decrease in order to converge to a lower capacity in time -+ * logarithmic in the magnitude of the decrease. -+ * -+ * However, we do not cut our short-term estimates lower than the current rate -+ * and volume of delivered data from this round trip, since from the current -+ * delivery process we can estimate the measured capacity available now. -+ * -+ * Anything faster than that approach would knowingly risk high loss, which can -+ * cause low bw for Reno/CUBIC and high loss recovery latency for -+ * request/response flows using any congestion control. -+ */ -+static void bbr2_adapt_lower_bounds(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 ecn_cut, ecn_inflight_lo, beta; -+ -+ /* We only use lower-bound estimates when not probing bw. -+ * When probing we need to push inflight higher to probe bw. -+ */ -+ if (bbr2_is_probing_bandwidth(sk)) -+ return; -+ -+ /* ECN response. */ -+ if (bbr->ecn_in_round && bbr->ecn_eligible && bbr->params.ecn_factor) { -+ /* Reduce inflight to (1 - alpha*ecn_factor). */ -+ ecn_cut = (BBR_UNIT - -+ ((bbr->ecn_alpha * bbr->params.ecn_factor) >> -+ BBR_SCALE)); -+ if (bbr->inflight_lo == ~0U) -+ bbr->inflight_lo = tp->snd_cwnd; -+ ecn_inflight_lo = (u64)bbr->inflight_lo * ecn_cut >> BBR_SCALE; -+ } else { -+ ecn_inflight_lo = ~0U; -+ } -+ -+ /* Loss response. */ -+ if (bbr->loss_in_round) { -+ /* Reduce bw and inflight to (1 - beta). */ -+ if (bbr->bw_lo == ~0U) -+ bbr->bw_lo = bbr_max_bw(sk); -+ if (bbr->inflight_lo == ~0U) -+ bbr->inflight_lo = tp->snd_cwnd; -+ beta = bbr->params.beta; -+ bbr->bw_lo = -+ max_t(u32, bbr->bw_latest, -+ (u64)bbr->bw_lo * -+ (BBR_UNIT - beta) >> BBR_SCALE); -+ bbr->inflight_lo = -+ max_t(u32, bbr->inflight_latest, -+ (u64)bbr->inflight_lo * -+ (BBR_UNIT - beta) >> BBR_SCALE); -+ } -+ -+ /* Adjust to the lower of the levels implied by loss or ECN. */ -+ bbr->inflight_lo = min(bbr->inflight_lo, ecn_inflight_lo); -+} -+ -+/* Reset any short-term lower-bound adaptation to congestion, so that we can -+ * push our inflight up. -+ */ -+static void bbr2_reset_lower_bounds(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->bw_lo = ~0U; -+ bbr->inflight_lo = ~0U; -+} -+ -+/* After bw probing (STARTUP/PROBE_UP), reset signals before entering a state -+ * machine phase where we adapt our lower bound based on congestion signals. -+ */ -+static void bbr2_reset_congestion_signals(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->loss_in_round = 0; -+ bbr->ecn_in_round = 0; -+ bbr->loss_in_cycle = 0; -+ bbr->ecn_in_cycle = 0; -+ bbr->bw_latest = 0; -+ bbr->inflight_latest = 0; -+} -+ -+/* Update (most of) our congestion signals: track the recent rate and volume of -+ * delivered data, presence of loss, and EWMA degree of ECN marking. -+ */ -+static void bbr2_update_congestion_signals( -+ struct sock *sk, const struct rate_sample *rs, struct bbr_context *ctx) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw; -+ -+ bbr->loss_round_start = 0; -+ if (rs->interval_us <= 0 || !rs->acked_sacked) -+ return; /* Not a valid observation */ -+ bw = ctx->sample_bw; -+ -+ if (!rs->is_app_limited || bw >= bbr_max_bw(sk)) -+ bbr2_take_bw_hi_sample(sk, bw); -+ -+ bbr->loss_in_round |= (rs->losses > 0); -+ -+ /* Update rate and volume of delivered data from latest round trip: */ -+ bbr->bw_latest = max_t(u32, bbr->bw_latest, ctx->sample_bw); -+ bbr->inflight_latest = max_t(u32, bbr->inflight_latest, rs->delivered); -+ -+ if (before(rs->prior_delivered, bbr->loss_round_delivered)) -+ return; /* skip the per-round-trip updates */ -+ /* Now do per-round-trip updates. */ -+ bbr->loss_round_delivered = tp->delivered; /* mark round trip */ -+ bbr->loss_round_start = 1; -+ bbr2_adapt_lower_bounds(sk); -+ -+ /* Update windowed "latest" (single-round-trip) filters. */ -+ bbr->loss_in_round = 0; -+ bbr->ecn_in_round = 0; -+ bbr->bw_latest = ctx->sample_bw; -+ bbr->inflight_latest = rs->delivered; -+} -+ -+/* Bandwidth probing can cause loss. To help coexistence with loss-based -+ * congestion control we spread out our probing in a Reno-conscious way. Due to -+ * the shape of the Reno sawtooth, the time required between loss epochs for an -+ * idealized Reno flow is a number of round trips that is the BDP of that -+ * flow. We count packet-timed round trips directly, since measured RTT can -+ * vary widely, and Reno is driven by packet-timed round trips. -+ */ -+static bool bbr2_is_reno_coexistence_probe_time(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 inflight, rounds, reno_gain, reno_rounds; -+ -+ /* Random loss can shave some small percentage off of our inflight -+ * in each round. To survive this, flows need robust periodic probes. -+ */ -+ rounds = bbr->params.bw_probe_max_rounds; -+ -+ reno_gain = bbr->params.bw_probe_reno_gain; -+ if (reno_gain) { -+ inflight = bbr2_target_inflight(sk); -+ reno_rounds = ((u64)inflight * reno_gain) >> BBR_SCALE; -+ rounds = min(rounds, reno_rounds); -+ } -+ return bbr->rounds_since_probe >= rounds; -+} -+ -+/* How long do we want to wait before probing for bandwidth (and risking -+ * loss)? We randomize the wait, for better mixing and fairness convergence. -+ * -+ * We bound the Reno-coexistence inter-bw-probe time to be 62-63 round trips. -+ * This is calculated to allow fairness with a 25Mbps, 30ms Reno flow, -+ * (eg 4K video to a broadband user): -+ * BDP = 25Mbps * .030sec /(1514bytes) = 61.9 packets -+ * -+ * We bound the BBR-native inter-bw-probe wall clock time to be: -+ * (a) higher than 2 sec: to try to avoid causing loss for a long enough time -+ * to allow Reno at 30ms to get 4K video bw, the inter-bw-probe time must -+ * be at least: 25Mbps * .030sec / (1514bytes) * 0.030sec = 1.9secs -+ * (b) lower than 3 sec: to ensure flows can start probing in a reasonable -+ * amount of time to discover unutilized bw on human-scale interactive -+ * time-scales (e.g. perhaps traffic from a web page download that we -+ * were competing with is now complete). -+ */ -+static void bbr2_pick_probe_wait(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ /* Decide the random round-trip bound for wait until probe: */ -+ bbr->rounds_since_probe = -+ prandom_u32_max(bbr->params.bw_probe_rand_rounds); -+ /* Decide the random wall clock bound for wait until probe: */ -+ bbr->probe_wait_us = bbr->params.bw_probe_base_us + -+ prandom_u32_max(bbr->params.bw_probe_rand_us); -+} -+ -+static void bbr2_set_cycle_idx(struct sock *sk, int cycle_idx) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->cycle_idx = cycle_idx; -+ /* New phase, so need to update cwnd and pacing rate. */ -+ bbr->try_fast_path = 0; -+} -+ -+/* Send at estimated bw to fill the pipe, but not queue. We need this phase -+ * before PROBE_UP, because as soon as we send faster than the available bw -+ * we will start building a queue, and if the buffer is shallow we can cause -+ * loss. If we do not fill the pipe before we cause this loss, our bw_hi and -+ * inflight_hi estimates will underestimate. -+ */ -+static void bbr2_start_bw_probe_refill(struct sock *sk, u32 bw_probe_up_rounds) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr2_reset_lower_bounds(sk); -+ if (bbr->inflight_hi != ~0U) -+ bbr->inflight_hi += bbr->params.refill_add_inc; -+ bbr->bw_probe_up_rounds = bw_probe_up_rounds; -+ bbr->bw_probe_up_acks = 0; -+ bbr->stopped_risky_probe = 0; -+ bbr->ack_phase = BBR_ACKS_REFILLING; -+ bbr->next_rtt_delivered = tp->delivered; -+ bbr2_set_cycle_idx(sk, BBR_BW_PROBE_REFILL); -+} -+ -+/* Now probe max deliverable data rate and volume. */ -+static void bbr2_start_bw_probe_up(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->ack_phase = BBR_ACKS_PROBE_STARTING; -+ bbr->next_rtt_delivered = tp->delivered; -+ bbr->cycle_mstamp = tp->tcp_mstamp; -+ bbr2_set_cycle_idx(sk, BBR_BW_PROBE_UP); -+ bbr2_raise_inflight_hi_slope(sk); -+} -+ -+/* Start a new PROBE_BW probing cycle of some wall clock length. Pick a wall -+ * clock time at which to probe beyond an inflight that we think to be -+ * safe. This will knowingly risk packet loss, so we want to do this rarely, to -+ * keep packet loss rates low. Also start a round-trip counter, to probe faster -+ * if we estimate a Reno flow at our BDP would probe faster. -+ */ -+static void bbr2_start_bw_probe_down(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr2_reset_congestion_signals(sk); -+ bbr->bw_probe_up_cnt = ~0U; /* not growing inflight_hi any more */ -+ bbr2_pick_probe_wait(sk); -+ bbr->cycle_mstamp = tp->tcp_mstamp; /* start wall clock */ -+ bbr->ack_phase = BBR_ACKS_PROBE_STOPPING; -+ bbr->next_rtt_delivered = tp->delivered; -+ bbr2_set_cycle_idx(sk, BBR_BW_PROBE_DOWN); -+} -+ -+/* Cruise: maintain what we estimate to be a neutral, conservative -+ * operating point, without attempting to probe up for bandwidth or down for -+ * RTT, and only reducing inflight in response to loss/ECN signals. -+ */ -+static void bbr2_start_bw_probe_cruise(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->inflight_lo != ~0U) -+ bbr->inflight_lo = min(bbr->inflight_lo, bbr->inflight_hi); -+ -+ bbr2_set_cycle_idx(sk, BBR_BW_PROBE_CRUISE); -+} -+ -+/* Loss and/or ECN rate is too high while probing. -+ * Adapt (once per bw probe) by cutting inflight_hi and then restarting cycle. -+ */ -+static void bbr2_handle_inflight_too_high(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ const u32 beta = bbr->params.beta; -+ -+ bbr->prev_probe_too_high = 1; -+ bbr->bw_probe_samples = 0; /* only react once per probe */ -+ bbr->debug.event = 'L'; /* Loss/ECN too high */ -+ /* If we are app-limited then we are not robustly -+ * probing the max volume of inflight data we think -+ * might be safe (analogous to how app-limited bw -+ * samples are not known to be robustly probing bw). -+ */ -+ if (!rs->is_app_limited) -+ bbr->inflight_hi = max_t(u32, rs->tx_in_flight, -+ (u64)bbr2_target_inflight(sk) * -+ (BBR_UNIT - beta) >> BBR_SCALE); -+ if (bbr->mode == BBR_PROBE_BW && bbr->cycle_idx == BBR_BW_PROBE_UP) -+ bbr2_start_bw_probe_down(sk); -+} -+ -+/* If we're seeing bw and loss samples reflecting our bw probing, adapt -+ * using the signals we see. If loss or ECN mark rate gets too high, then adapt -+ * inflight_hi downward. If we're able to push inflight higher without such -+ * signals, push higher: adapt inflight_hi upward. -+ */ -+static bool bbr2_adapt_upper_bounds(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ /* Track when we'll see bw/loss samples resulting from our bw probes. */ -+ if (bbr->ack_phase == BBR_ACKS_PROBE_STARTING && bbr->round_start) -+ bbr->ack_phase = BBR_ACKS_PROBE_FEEDBACK; -+ if (bbr->ack_phase == BBR_ACKS_PROBE_STOPPING && bbr->round_start) { -+ /* End of samples from bw probing phase. */ -+ bbr->bw_probe_samples = 0; -+ bbr->ack_phase = BBR_ACKS_INIT; -+ /* At this point in the cycle, our current bw sample is also -+ * our best recent chance at finding the highest available bw -+ * for this flow. So now is the best time to forget the bw -+ * samples from the previous cycle, by advancing the window. -+ */ -+ if (bbr->mode == BBR_PROBE_BW && !rs->is_app_limited) -+ bbr2_advance_bw_hi_filter(sk); -+ /* If we had an inflight_hi, then probed and pushed inflight all -+ * the way up to hit that inflight_hi without seeing any -+ * high loss/ECN in all the resulting ACKs from that probing, -+ * then probe up again, this time letting inflight persist at -+ * inflight_hi for a round trip, then accelerating beyond. -+ */ -+ if (bbr->mode == BBR_PROBE_BW && -+ bbr->stopped_risky_probe && !bbr->prev_probe_too_high) { -+ bbr->debug.event = 'R'; /* reprobe */ -+ bbr2_start_bw_probe_refill(sk, 0); -+ return true; /* yes, decided state transition */ -+ } -+ } -+ -+ if (bbr2_is_inflight_too_high(sk, rs)) { -+ if (bbr->bw_probe_samples) /* sample is from bw probing? */ -+ bbr2_handle_inflight_too_high(sk, rs); -+ } else { -+ /* Loss/ECN rate is declared safe. Adjust upper bound upward. */ -+ if (bbr->inflight_hi == ~0U) /* no excess queue signals yet? */ -+ return false; -+ -+ /* To be resilient to random loss, we must raise inflight_hi -+ * if we observe in any phase that a higher level is safe. -+ */ -+ if (rs->tx_in_flight > bbr->inflight_hi) { -+ bbr->inflight_hi = rs->tx_in_flight; -+ bbr->debug.event = 'U'; /* raise up inflight_hi */ -+ } -+ -+ if (bbr->mode == BBR_PROBE_BW && -+ bbr->cycle_idx == BBR_BW_PROBE_UP) -+ bbr2_probe_inflight_hi_upward(sk, rs); -+ } -+ -+ return false; -+} -+ -+/* Check if it's time to probe for bandwidth now, and if so, kick it off. */ -+static bool bbr2_check_time_to_probe_bw(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 n; -+ -+ /* If we seem to be at an operating point where we are not seeing loss -+ * but we are seeing ECN marks, then when the ECN marks cease we reprobe -+ * quickly (in case a burst of cross-traffic has ceased and freed up bw, -+ * or in case we are sharing with multiplicatively probing traffic). -+ */ -+ if (bbr->params.ecn_reprobe_gain && bbr->ecn_eligible && -+ bbr->ecn_in_cycle && !bbr->loss_in_cycle && -+ inet_csk(sk)->icsk_ca_state == TCP_CA_Open) { -+ bbr->debug.event = 'A'; /* *A*ll clear to probe *A*gain */ -+ /* Calculate n so that when bbr2_raise_inflight_hi_slope() -+ * computes growth_this_round as 2^n it will be roughly the -+ * desired volume of data (inflight_hi*ecn_reprobe_gain). -+ */ -+ n = ilog2((((u64)bbr->inflight_hi * -+ bbr->params.ecn_reprobe_gain) >> BBR_SCALE)); -+ bbr2_start_bw_probe_refill(sk, n); -+ return true; -+ } -+ -+ if (bbr2_has_elapsed_in_phase(sk, bbr->probe_wait_us) || -+ bbr2_is_reno_coexistence_probe_time(sk)) { -+ bbr2_start_bw_probe_refill(sk, 0); -+ return true; -+ } -+ return false; -+} -+ -+/* Is it time to transition from PROBE_DOWN to PROBE_CRUISE? */ -+static bool bbr2_check_time_to_cruise(struct sock *sk, u32 inflight, u32 bw) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ bool is_under_bdp, is_long_enough; -+ -+ /* Always need to pull inflight down to leave headroom in queue. */ -+ if (inflight > bbr2_inflight_with_headroom(sk)) -+ return false; -+ -+ is_under_bdp = inflight <= bbr_inflight(sk, bw, BBR_UNIT); -+ if (bbr->params.drain_to_target) -+ return is_under_bdp; -+ -+ is_long_enough = bbr2_has_elapsed_in_phase(sk, bbr->min_rtt_us); -+ return is_under_bdp || is_long_enough; -+} -+ -+/* PROBE_BW state machine: cruise, refill, probe for bw, or drain? */ -+static void bbr2_update_cycle_phase(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ bool is_risky = false, is_queuing = false; -+ u32 inflight, bw; -+ -+ if (!bbr_full_bw_reached(sk)) -+ return; -+ -+ /* In DRAIN, PROBE_BW, or PROBE_RTT, adjust upper bounds. */ -+ if (bbr2_adapt_upper_bounds(sk, rs)) -+ return; /* already decided state transition */ -+ -+ if (bbr->mode != BBR_PROBE_BW) -+ return; -+ -+ inflight = bbr_packets_in_net_at_edt(sk, rs->prior_in_flight); -+ bw = bbr_max_bw(sk); -+ -+ switch (bbr->cycle_idx) { -+ /* First we spend most of our time cruising with a pacing_gain of 1.0, -+ * which paces at the estimated bw, to try to fully use the pipe -+ * without building queue. If we encounter loss/ECN marks, we adapt -+ * by slowing down. -+ */ -+ case BBR_BW_PROBE_CRUISE: -+ if (bbr2_check_time_to_probe_bw(sk)) -+ return; /* already decided state transition */ -+ break; -+ -+ /* After cruising, when it's time to probe, we first "refill": we send -+ * at the estimated bw to fill the pipe, before probing higher and -+ * knowingly risking overflowing the bottleneck buffer (causing loss). -+ */ -+ case BBR_BW_PROBE_REFILL: -+ if (bbr->round_start) { -+ /* After one full round trip of sending in REFILL, we -+ * start to see bw samples reflecting our REFILL, which -+ * may be putting too much data in flight. -+ */ -+ bbr->bw_probe_samples = 1; -+ bbr2_start_bw_probe_up(sk); -+ } -+ break; -+ -+ /* After we refill the pipe, we probe by using a pacing_gain > 1.0, to -+ * probe for bw. If we have not seen loss/ECN, we try to raise inflight -+ * to at least pacing_gain*BDP; note that this may take more than -+ * min_rtt if min_rtt is small (e.g. on a LAN). -+ * -+ * We terminate PROBE_UP bandwidth probing upon any of the following: -+ * -+ * (1) We've pushed inflight up to hit the inflight_hi target set in the -+ * most recent previous bw probe phase. Thus we want to start -+ * draining the queue immediately because it's very likely the most -+ * recently sent packets will fill the queue and cause drops. -+ * (checked here) -+ * (2) We have probed for at least 1*min_rtt_us, and the -+ * estimated queue is high enough (inflight > 1.25 * estimated_bdp). -+ * (checked here) -+ * (3) Loss filter says loss rate is "too high". -+ * (checked in bbr_is_inflight_too_high()) -+ * (4) ECN filter says ECN mark rate is "too high". -+ * (checked in bbr_is_inflight_too_high()) -+ */ -+ case BBR_BW_PROBE_UP: -+ if (bbr->prev_probe_too_high && -+ inflight >= bbr->inflight_hi) { -+ bbr->stopped_risky_probe = 1; -+ is_risky = true; -+ bbr->debug.event = 'D'; /* D for danger */ -+ } else if (bbr2_has_elapsed_in_phase(sk, bbr->min_rtt_us) && -+ inflight >= -+ bbr_inflight(sk, bw, -+ bbr->params.bw_probe_pif_gain)) { -+ is_queuing = true; -+ bbr->debug.event = 'Q'; /* building Queue */ -+ } -+ if (is_risky || is_queuing) { -+ bbr->prev_probe_too_high = 0; /* no loss/ECN (yet) */ -+ bbr2_start_bw_probe_down(sk); /* restart w/ down */ -+ } -+ break; -+ -+ /* After probing in PROBE_UP, we have usually accumulated some data in -+ * the bottleneck buffer (if bw probing didn't find more bw). We next -+ * enter PROBE_DOWN to try to drain any excess data from the queue. To -+ * do this, we use a pacing_gain < 1.0. We hold this pacing gain until -+ * our inflight is less then that target cruising point, which is the -+ * minimum of (a) the amount needed to leave headroom, and (b) the -+ * estimated BDP. Once inflight falls to match the target, we estimate -+ * the queue is drained; persisting would underutilize the pipe. -+ */ -+ case BBR_BW_PROBE_DOWN: -+ if (bbr2_check_time_to_probe_bw(sk)) -+ return; /* already decided state transition */ -+ if (bbr2_check_time_to_cruise(sk, inflight, bw)) -+ bbr2_start_bw_probe_cruise(sk); -+ break; -+ -+ default: -+ WARN_ONCE(1, "BBR invalid cycle index %u\n", bbr->cycle_idx); -+ } -+} -+ -+/* Exiting PROBE_RTT, so return to bandwidth probing in STARTUP or PROBE_BW. */ -+static void bbr2_exit_probe_rtt(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr2_reset_lower_bounds(sk); -+ if (bbr_full_bw_reached(sk)) { -+ bbr->mode = BBR_PROBE_BW; -+ /* Raising inflight after PROBE_RTT may cause loss, so reset -+ * the PROBE_BW clock and schedule the next bandwidth probe for -+ * a friendly and randomized future point in time. -+ */ -+ bbr2_start_bw_probe_down(sk); -+ /* Since we are exiting PROBE_RTT, we know inflight is -+ * below our estimated BDP, so it is reasonable to cruise. -+ */ -+ bbr2_start_bw_probe_cruise(sk); -+ } else { -+ bbr->mode = BBR_STARTUP; -+ } -+} -+ -+/* Exit STARTUP based on loss rate > 1% and loss gaps in round >= N. Wait until -+ * the end of the round in recovery to get a good estimate of how many packets -+ * have been lost, and how many we need to drain with a low pacing rate. -+ */ -+static void bbr2_check_loss_too_high_in_startup(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr_full_bw_reached(sk)) -+ return; -+ -+ /* For STARTUP exit, check the loss rate at the end of each round trip -+ * of Recovery episodes in STARTUP. We check the loss rate at the end -+ * of the round trip to filter out noisy/low loss and have a better -+ * sense of inflight (extent of loss), so we can drain more accurately. -+ */ -+ if (rs->losses && bbr->loss_events_in_round < 0xf) -+ bbr->loss_events_in_round++; /* update saturating counter */ -+ if (bbr->params.full_loss_cnt && bbr->loss_round_start && -+ inet_csk(sk)->icsk_ca_state == TCP_CA_Recovery && -+ bbr->loss_events_in_round >= bbr->params.full_loss_cnt && -+ bbr2_is_inflight_too_high(sk, rs)) { -+ bbr->debug.event = 'P'; /* Packet loss caused STARTUP exit */ -+ bbr2_handle_queue_too_high_in_startup(sk); -+ return; -+ } -+ if (bbr->loss_round_start) -+ bbr->loss_events_in_round = 0; -+} -+ -+/* If we are done draining, advance into steady state operation in PROBE_BW. */ -+static void bbr2_check_drain(struct sock *sk, const struct rate_sample *rs, -+ struct bbr_context *ctx) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr_check_drain(sk, rs, ctx)) { -+ bbr->mode = BBR_PROBE_BW; -+ bbr2_start_bw_probe_down(sk); -+ } -+} -+ -+static void bbr2_update_model(struct sock *sk, const struct rate_sample *rs, -+ struct bbr_context *ctx) -+{ -+ bbr2_update_congestion_signals(sk, rs, ctx); -+ bbr_update_ack_aggregation(sk, rs); -+ bbr2_check_loss_too_high_in_startup(sk, rs); -+ bbr_check_full_bw_reached(sk, rs); -+ bbr2_check_drain(sk, rs, ctx); -+ bbr2_update_cycle_phase(sk, rs); -+ bbr_update_min_rtt(sk, rs); -+} -+ -+/* Fast path for app-limited case. -+ * -+ * On each ack, we execute bbr state machine, which primarily consists of: -+ * 1) update model based on new rate sample, and -+ * 2) update control based on updated model or state change. -+ * -+ * There are certain workload/scenarios, e.g. app-limited case, where -+ * either we can skip updating model or we can skip update of both model -+ * as well as control. This provides signifcant softirq cpu savings for -+ * processing incoming acks. -+ * -+ * In case of app-limited, if there is no congestion (loss/ecn) and -+ * if observed bw sample is less than current estimated bw, then we can -+ * skip some of the computation in bbr state processing: -+ * -+ * - if there is no rtt/mode/phase change: In this case, since all the -+ * parameters of the network model are constant, we can skip model -+ * as well control update. -+ * -+ * - else we can skip rest of the model update. But we still need to -+ * update the control to account for the new rtt/mode/phase. -+ * -+ * Returns whether we can take fast path or not. -+ */ -+static bool bbr2_fast_path(struct sock *sk, bool *update_model, -+ const struct rate_sample *rs, struct bbr_context *ctx) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 prev_min_rtt_us, prev_mode; -+ -+ if (bbr->params.fast_path && bbr->try_fast_path && -+ rs->is_app_limited && ctx->sample_bw < bbr_max_bw(sk) && -+ !bbr->loss_in_round && !bbr->ecn_in_round) { -+ prev_mode = bbr->mode; -+ prev_min_rtt_us = bbr->min_rtt_us; -+ bbr2_check_drain(sk, rs, ctx); -+ bbr2_update_cycle_phase(sk, rs); -+ bbr_update_min_rtt(sk, rs); -+ -+ if (bbr->mode == prev_mode && -+ bbr->min_rtt_us == prev_min_rtt_us && -+ bbr->try_fast_path) -+ return true; -+ -+ /* Skip model update, but control still needs to be updated */ -+ *update_model = false; -+ } -+ return false; -+} -+ -+static void bbr2_main(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ struct bbr_context ctx = { 0 }; -+ bool update_model = true; -+ u32 bw; -+ -+ bbr->debug.event = '.'; /* init to default NOP (no event yet) */ -+ -+ bbr_update_round_start(sk, rs, &ctx); -+ if (bbr->round_start) { -+ bbr->rounds_since_probe = -+ min_t(s32, bbr->rounds_since_probe + 1, 0xFF); -+ bbr2_update_ecn_alpha(sk); -+ } -+ -+ bbr->ecn_in_round |= rs->is_ece; -+ bbr_calculate_bw_sample(sk, rs, &ctx); -+ -+ if (bbr2_fast_path(sk, &update_model, rs, &ctx)) -+ goto out; -+ -+ if (update_model) -+ bbr2_update_model(sk, rs, &ctx); -+ -+ bbr_update_gains(sk); -+ bw = bbr_bw(sk); -+ bbr_set_pacing_rate(sk, bw, bbr->pacing_gain); -+ bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain, -+ tp->snd_cwnd, &ctx); -+ bbr2_bound_cwnd_for_inflight_model(sk); -+ -+out: -+ bbr->prev_ca_state = inet_csk(sk)->icsk_ca_state; -+ bbr->loss_in_cycle |= rs->lost > 0; -+ bbr->ecn_in_cycle |= rs->delivered_ce > 0; -+ -+ bbr_debug(sk, rs->acked_sacked, rs, &ctx); -+} -+ -+/* Module parameters that are settable by TCP_CONGESTION_PARAMS are declared -+ * down here, so that the algorithm functions that use the parameters must use -+ * the per-socket parameters; if they accidentally use the global version -+ * then there will be a compile error. -+ * TODO(ncardwell): move all per-socket parameters down to this section. -+ */ -+ -+/* On losses, scale down inflight and pacing rate by beta scaled by BBR_SCALE. -+ * No loss response when 0. Max allwed value is 255. -+ */ -+static u32 bbr_beta = BBR_UNIT * 30 / 100; -+ -+/* Gain factor for ECN mark ratio samples, scaled by BBR_SCALE. -+ * Max allowed value is 255. -+ */ -+static u32 bbr_ecn_alpha_gain = BBR_UNIT * 1 / 16; /* 1/16 = 6.25% */ -+ -+/* The initial value for the ecn_alpha state variable. Default and max -+ * BBR_UNIT (256), representing 1.0. This allows a flow to respond quickly -+ * to congestion if the bottleneck is congested when the flow starts up. -+ */ -+static u32 bbr_ecn_alpha_init = BBR_UNIT; /* 1.0, to respond quickly */ -+ -+/* On ECN, cut inflight_lo to (1 - ecn_factor * ecn_alpha) scaled by BBR_SCALE. -+ * No ECN based bounding when 0. Max allwed value is 255. -+ */ -+static u32 bbr_ecn_factor = BBR_UNIT * 1 / 3; /* 1/3 = 33% */ -+ -+/* Estimate bw probing has gone too far if CE ratio exceeds this threshold. -+ * Scaled by BBR_SCALE. Disabled when 0. Max allowed is 255. -+ */ -+static u32 bbr_ecn_thresh = BBR_UNIT * 1 / 2; /* 1/2 = 50% */ -+ -+/* Max RTT (in usec) at which to use sender-side ECN logic. -+ * Disabled when 0 (ECN allowed at any RTT). -+ * Max allowed for the parameter is 524287 (0x7ffff) us, ~524 ms. -+ */ -+static u32 bbr_ecn_max_rtt_us = 5000; -+ -+/* If non-zero, if in a cycle with no losses but some ECN marks, after ECN -+ * clears then use a multiplicative increase to quickly reprobe bw by -+ * starting inflight probing at the given multiple of inflight_hi. -+ * Default for this experimental knob is 0 (disabled). -+ * Planned value for experiments: BBR_UNIT * 1 / 2 = 128, representing 0.5. -+ */ -+static u32 bbr_ecn_reprobe_gain; -+ -+/* Estimate bw probing has gone too far if loss rate exceeds this level. */ -+static u32 bbr_loss_thresh = BBR_UNIT * 2 / 100; /* 2% loss */ -+ -+/* Exit STARTUP if number of loss marking events in a Recovery round is >= N, -+ * and loss rate is higher than bbr_loss_thresh. -+ * Disabled if 0. Max allowed value is 15 (0xF). -+ */ -+static u32 bbr_full_loss_cnt = 8; -+ -+/* Exit STARTUP if number of round trips with ECN mark rate above ecn_thresh -+ * meets this count. Max allowed value is 3. -+ */ -+static u32 bbr_full_ecn_cnt = 2; -+ -+/* Fraction of unutilized headroom to try to leave in path upon high loss. */ -+static u32 bbr_inflight_headroom = BBR_UNIT * 15 / 100; -+ -+/* Multiplier to get target inflight (as multiple of BDP) for PROBE_UP phase. -+ * Default is 1.25x, as in BBR v1. Max allowed is 511. -+ */ -+static u32 bbr_bw_probe_pif_gain = BBR_UNIT * 5 / 4; -+ -+/* Multiplier to get Reno-style probe epoch duration as: k * BDP round trips. -+ * If zero, disables this BBR v2 Reno-style BDP-scaled coexistence mechanism. -+ * Max allowed is 511. -+ */ -+static u32 bbr_bw_probe_reno_gain = BBR_UNIT; -+ -+/* Max number of packet-timed rounds to wait before probing for bandwidth. If -+ * we want to tolerate 1% random loss per round, and not have this cut our -+ * inflight too much, we must probe for bw periodically on roughly this scale. -+ * If low, limits Reno/CUBIC coexistence; if high, limits loss tolerance. -+ * We aim to be fair with Reno/CUBIC up to a BDP of at least: -+ * BDP = 25Mbps * .030sec /(1514bytes) = 61.9 packets -+ */ -+static u32 bbr_bw_probe_max_rounds = 63; -+ -+/* Max amount of randomness to inject in round counting for Reno-coexistence. -+ * Max value is 15. -+ */ -+static u32 bbr_bw_probe_rand_rounds = 2; -+ -+/* Use BBR-native probe time scale starting at this many usec. -+ * We aim to be fair with Reno/CUBIC up to an inter-loss time epoch of at least: -+ * BDP*RTT = 25Mbps * .030sec /(1514bytes) * 0.030sec = 1.9 secs -+ */ -+static u32 bbr_bw_probe_base_us = 2 * USEC_PER_SEC; /* 2 secs */ -+ -+/* Use BBR-native probes spread over this many usec: */ -+static u32 bbr_bw_probe_rand_us = 1 * USEC_PER_SEC; /* 1 secs */ -+ -+/* Undo the model changes made in loss recovery if recovery was spurious? */ -+static bool bbr_undo = true; -+ -+/* Use fast path if app-limited, no loss/ECN, and target cwnd was reached? */ -+static bool bbr_fast_path = true; /* default: enabled */ -+ -+/* Use fast ack mode ? */ -+static int bbr_fast_ack_mode = 1; /* default: rwnd check off */ -+ -+/* How much to additively increase inflight_hi when entering REFILL? */ -+static u32 bbr_refill_add_inc; /* default: disabled */ -+ -+module_param_named(beta, bbr_beta, uint, 0644); -+module_param_named(ecn_alpha_gain, bbr_ecn_alpha_gain, uint, 0644); -+module_param_named(ecn_alpha_init, bbr_ecn_alpha_init, uint, 0644); -+module_param_named(ecn_factor, bbr_ecn_factor, uint, 0644); -+module_param_named(ecn_thresh, bbr_ecn_thresh, uint, 0644); -+module_param_named(ecn_max_rtt_us, bbr_ecn_max_rtt_us, uint, 0644); -+module_param_named(ecn_reprobe_gain, bbr_ecn_reprobe_gain, uint, 0644); -+module_param_named(loss_thresh, bbr_loss_thresh, uint, 0664); -+module_param_named(full_loss_cnt, bbr_full_loss_cnt, uint, 0664); -+module_param_named(full_ecn_cnt, bbr_full_ecn_cnt, uint, 0664); -+module_param_named(inflight_headroom, bbr_inflight_headroom, uint, 0664); -+module_param_named(bw_probe_pif_gain, bbr_bw_probe_pif_gain, uint, 0664); -+module_param_named(bw_probe_reno_gain, bbr_bw_probe_reno_gain, uint, 0664); -+module_param_named(bw_probe_max_rounds, bbr_bw_probe_max_rounds, uint, 0664); -+module_param_named(bw_probe_rand_rounds, bbr_bw_probe_rand_rounds, uint, 0664); -+module_param_named(bw_probe_base_us, bbr_bw_probe_base_us, uint, 0664); -+module_param_named(bw_probe_rand_us, bbr_bw_probe_rand_us, uint, 0664); -+module_param_named(undo, bbr_undo, bool, 0664); -+module_param_named(fast_path, bbr_fast_path, bool, 0664); -+module_param_named(fast_ack_mode, bbr_fast_ack_mode, uint, 0664); -+module_param_named(refill_add_inc, bbr_refill_add_inc, uint, 0664); -+ -+static void bbr2_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr_init(sk); /* run shared init code for v1 and v2 */ -+ -+ /* BBR v2 parameters: */ -+ bbr->params.beta = min_t(u32, 0xFFU, bbr_beta); -+ bbr->params.ecn_alpha_gain = min_t(u32, 0xFFU, bbr_ecn_alpha_gain); -+ bbr->params.ecn_alpha_init = min_t(u32, BBR_UNIT, bbr_ecn_alpha_init); -+ bbr->params.ecn_factor = min_t(u32, 0xFFU, bbr_ecn_factor); -+ bbr->params.ecn_thresh = min_t(u32, 0xFFU, bbr_ecn_thresh); -+ bbr->params.ecn_max_rtt_us = min_t(u32, 0x7ffffU, bbr_ecn_max_rtt_us); -+ bbr->params.ecn_reprobe_gain = min_t(u32, 0x1FF, bbr_ecn_reprobe_gain); -+ bbr->params.loss_thresh = min_t(u32, 0xFFU, bbr_loss_thresh); -+ bbr->params.full_loss_cnt = min_t(u32, 0xFU, bbr_full_loss_cnt); -+ bbr->params.full_ecn_cnt = min_t(u32, 0x3U, bbr_full_ecn_cnt); -+ bbr->params.inflight_headroom = -+ min_t(u32, 0xFFU, bbr_inflight_headroom); -+ bbr->params.bw_probe_pif_gain = -+ min_t(u32, 0x1FFU, bbr_bw_probe_pif_gain); -+ bbr->params.bw_probe_reno_gain = -+ min_t(u32, 0x1FFU, bbr_bw_probe_reno_gain); -+ bbr->params.bw_probe_max_rounds = -+ min_t(u32, 0xFFU, bbr_bw_probe_max_rounds); -+ bbr->params.bw_probe_rand_rounds = -+ min_t(u32, 0xFU, bbr_bw_probe_rand_rounds); -+ bbr->params.bw_probe_base_us = -+ min_t(u32, (1 << 26) - 1, bbr_bw_probe_base_us); -+ bbr->params.bw_probe_rand_us = -+ min_t(u32, (1 << 26) - 1, bbr_bw_probe_rand_us); -+ bbr->params.undo = bbr_undo; -+ bbr->params.fast_path = bbr_fast_path ? 1 : 0; -+ bbr->params.refill_add_inc = min_t(u32, 0x3U, bbr_refill_add_inc); -+ -+ /* BBR v2 state: */ -+ bbr->initialized = 1; -+ /* Start sampling ECN mark rate after first full flight is ACKed: */ -+ bbr->loss_round_delivered = tp->delivered + 1; -+ bbr->loss_round_start = 0; -+ bbr->undo_bw_lo = 0; -+ bbr->undo_inflight_lo = 0; -+ bbr->undo_inflight_hi = 0; -+ bbr->loss_events_in_round = 0; -+ bbr->startup_ecn_rounds = 0; -+ bbr2_reset_congestion_signals(sk); -+ bbr->bw_lo = ~0U; -+ bbr->bw_hi[0] = 0; -+ bbr->bw_hi[1] = 0; -+ bbr->inflight_lo = ~0U; -+ bbr->inflight_hi = ~0U; -+ bbr->bw_probe_up_cnt = ~0U; -+ bbr->bw_probe_up_acks = 0; -+ bbr->bw_probe_up_rounds = 0; -+ bbr->probe_wait_us = 0; -+ bbr->stopped_risky_probe = 0; -+ bbr->ack_phase = BBR_ACKS_INIT; -+ bbr->rounds_since_probe = 0; -+ bbr->bw_probe_samples = 0; -+ bbr->prev_probe_too_high = 0; -+ bbr->ecn_eligible = 0; -+ bbr->ecn_alpha = bbr->params.ecn_alpha_init; -+ bbr->alpha_last_delivered = 0; -+ bbr->alpha_last_delivered_ce = 0; -+ -+ tp->fast_ack_mode = min_t(u32, 0x2U, bbr_fast_ack_mode); -+ -+ if ((tp->ecn_flags & TCP_ECN_OK) && bbr_ecn_enable) -+ tp->ecn_flags |= TCP_ECN_ECT_PERMANENT; -+} -+ -+/* Core TCP stack informs us that the given skb was just marked lost. */ -+static void bbr2_skb_marked_lost(struct sock *sk, const struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ struct tcp_skb_cb *scb = TCP_SKB_CB(skb); -+ struct rate_sample rs; -+ -+ /* Capture "current" data over the full round trip of loss, -+ * to have a better chance to see the full capacity of the path. -+ */ -+ if (!bbr->loss_in_round) /* first loss in this round trip? */ -+ bbr->loss_round_delivered = tp->delivered; /* set round trip */ -+ bbr->loss_in_round = 1; -+ bbr->loss_in_cycle = 1; -+ -+ if (!bbr->bw_probe_samples) -+ return; /* not an skb sent while probing for bandwidth */ -+ if (unlikely(!scb->tx.delivered_mstamp)) -+ return; /* skb was SACKed, reneged, marked lost; ignore it */ -+ /* We are probing for bandwidth. Construct a rate sample that -+ * estimates what happened in the flight leading up to this lost skb, -+ * then see if the loss rate went too high, and if so at which packet. -+ */ -+ memset(&rs, 0, sizeof(rs)); -+ rs.tx_in_flight = scb->tx.in_flight; -+ rs.lost = tp->lost - scb->tx.lost; -+ rs.is_app_limited = scb->tx.is_app_limited; -+ if (bbr2_is_inflight_too_high(sk, &rs)) { -+ rs.tx_in_flight = bbr2_inflight_hi_from_lost_skb(sk, &rs, skb); -+ bbr2_handle_inflight_too_high(sk, &rs); -+ } -+} -+ -+/* Revert short-term model if current loss recovery event was spurious. */ -+static u32 bbr2_undo_cwnd(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->debug.undo = 1; -+ bbr->full_bw = 0; /* spurious slow-down; reset full pipe detection */ -+ bbr->full_bw_cnt = 0; -+ bbr->loss_in_round = 0; -+ -+ if (!bbr->params.undo) -+ return tp->snd_cwnd; -+ -+ /* Revert to cwnd and other state saved before loss episode. */ -+ bbr->bw_lo = max(bbr->bw_lo, bbr->undo_bw_lo); -+ bbr->inflight_lo = max(bbr->inflight_lo, bbr->undo_inflight_lo); -+ bbr->inflight_hi = max(bbr->inflight_hi, bbr->undo_inflight_hi); -+ return bbr->prior_cwnd; -+} -+ -+/* Entering loss recovery, so save state for when we undo recovery. */ -+static u32 bbr2_ssthresh(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr_save_cwnd(sk); -+ /* For undo, save state that adapts based on loss signal. */ -+ bbr->undo_bw_lo = bbr->bw_lo; -+ bbr->undo_inflight_lo = bbr->inflight_lo; -+ bbr->undo_inflight_hi = bbr->inflight_hi; -+ return tcp_sk(sk)->snd_ssthresh; -+} -+ -+static enum tcp_bbr2_phase bbr2_get_phase(struct bbr *bbr) -+{ -+ switch (bbr->mode) { -+ case BBR_STARTUP: -+ return BBR2_PHASE_STARTUP; -+ case BBR_DRAIN: -+ return BBR2_PHASE_DRAIN; -+ case BBR_PROBE_BW: -+ break; -+ case BBR_PROBE_RTT: -+ return BBR2_PHASE_PROBE_RTT; -+ default: -+ return BBR2_PHASE_INVALID; -+ } -+ switch (bbr->cycle_idx) { -+ case BBR_BW_PROBE_UP: -+ return BBR2_PHASE_PROBE_BW_UP; -+ case BBR_BW_PROBE_DOWN: -+ return BBR2_PHASE_PROBE_BW_DOWN; -+ case BBR_BW_PROBE_CRUISE: -+ return BBR2_PHASE_PROBE_BW_CRUISE; -+ case BBR_BW_PROBE_REFILL: -+ return BBR2_PHASE_PROBE_BW_REFILL; -+ default: -+ return BBR2_PHASE_INVALID; -+ } -+} -+ -+static size_t bbr2_get_info(struct sock *sk, u32 ext, int *attr, -+ union tcp_cc_info *info) -+{ -+ if (ext & (1 << (INET_DIAG_BBRINFO - 1)) || -+ ext & (1 << (INET_DIAG_VEGASINFO - 1))) { -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw = bbr_bw_bytes_per_sec(sk, bbr_bw(sk)); -+ u64 bw_hi = bbr_bw_bytes_per_sec(sk, bbr_max_bw(sk)); -+ u64 bw_lo = bbr->bw_lo == ~0U ? -+ ~0ULL : bbr_bw_bytes_per_sec(sk, bbr->bw_lo); -+ -+ memset(&info->bbr2, 0, sizeof(info->bbr2)); -+ info->bbr2.bbr_bw_lsb = (u32)bw; -+ info->bbr2.bbr_bw_msb = (u32)(bw >> 32); -+ info->bbr2.bbr_min_rtt = bbr->min_rtt_us; -+ info->bbr2.bbr_pacing_gain = bbr->pacing_gain; -+ info->bbr2.bbr_cwnd_gain = bbr->cwnd_gain; -+ info->bbr2.bbr_bw_hi_lsb = (u32)bw_hi; -+ info->bbr2.bbr_bw_hi_msb = (u32)(bw_hi >> 32); -+ info->bbr2.bbr_bw_lo_lsb = (u32)bw_lo; -+ info->bbr2.bbr_bw_lo_msb = (u32)(bw_lo >> 32); -+ info->bbr2.bbr_mode = bbr->mode; -+ info->bbr2.bbr_phase = (__u8)bbr2_get_phase(bbr); -+ info->bbr2.bbr_version = (__u8)2; -+ info->bbr2.bbr_inflight_lo = bbr->inflight_lo; -+ info->bbr2.bbr_inflight_hi = bbr->inflight_hi; -+ info->bbr2.bbr_extra_acked = bbr_extra_acked(sk); -+ *attr = INET_DIAG_BBRINFO; -+ return sizeof(info->bbr2); -+ } -+ return 0; -+} -+ -+static void bbr2_set_state(struct sock *sk, u8 new_state) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (new_state == TCP_CA_Loss) { -+ struct rate_sample rs = { .losses = 1 }; -+ struct bbr_context ctx = { 0 }; -+ -+ bbr->prev_ca_state = TCP_CA_Loss; -+ bbr->full_bw = 0; -+ if (!bbr2_is_probing_bandwidth(sk) && bbr->inflight_lo == ~0U) { -+ /* bbr_adapt_lower_bounds() needs cwnd before -+ * we suffered an RTO, to update inflight_lo: -+ */ -+ bbr->inflight_lo = -+ max(tp->snd_cwnd, bbr->prior_cwnd); -+ } -+ bbr_debug(sk, 0, &rs, &ctx); -+ } else if (bbr->prev_ca_state == TCP_CA_Loss && -+ new_state != TCP_CA_Loss) { -+ tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd); -+ bbr->try_fast_path = 0; /* bound cwnd using latest model */ -+ } -+} -+ -+static struct tcp_congestion_ops tcp_bbr2_cong_ops __read_mostly = { -+ .flags = TCP_CONG_NON_RESTRICTED | TCP_CONG_WANTS_CE_EVENTS, -+ .name = "bbr2", -+ .owner = THIS_MODULE, -+ .init = bbr2_init, -+ .cong_control = bbr2_main, -+ .sndbuf_expand = bbr_sndbuf_expand, -+ .skb_marked_lost = bbr2_skb_marked_lost, -+ .undo_cwnd = bbr2_undo_cwnd, -+ .cwnd_event = bbr_cwnd_event, -+ .ssthresh = bbr2_ssthresh, -+ .tso_segs = bbr_tso_segs, -+ .get_info = bbr2_get_info, -+ .set_state = bbr2_set_state, -+}; -+ -+static int __init bbr_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct bbr) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&tcp_bbr2_cong_ops); -+} -+ -+static void __exit bbr_unregister(void) -+{ -+ tcp_unregister_congestion_control(&tcp_bbr2_cong_ops); -+} -+ -+module_init(bbr_register); -+module_exit(bbr_unregister); -+ -+MODULE_AUTHOR("Van Jacobson <vanj@google.com>"); -+MODULE_AUTHOR("Neal Cardwell <ncardwell@google.com>"); -+MODULE_AUTHOR("Yuchung Cheng <ycheng@google.com>"); -+MODULE_AUTHOR("Soheil Hassas Yeganeh <soheil@google.com>"); -+MODULE_AUTHOR("Priyaranjan Jha <priyarjha@google.com>"); -+MODULE_AUTHOR("Yousuk Seung <ysseung@google.com>"); -+MODULE_AUTHOR("Kevin Yang <yyd@google.com>"); -+MODULE_AUTHOR("Arjun Roy <arjunroy@google.com>"); -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("TCP BBR (Bottleneck Bandwidth and RTT)"); -diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c -index db5831e6c136..153ed9010c0c 100644 ---- a/net/ipv4/tcp_cong.c -+++ b/net/ipv4/tcp_cong.c -@@ -179,6 +179,7 @@ void tcp_init_congestion_control(struct sock *sk) - struct inet_connection_sock *icsk = inet_csk(sk); - - tcp_sk(sk)->prior_ssthresh = 0; -+ tcp_sk(sk)->fast_ack_mode = 0; - if (icsk->icsk_ca_ops->init) - icsk->icsk_ca_ops->init(sk); - if (tcp_ca_needs_ecn(sk)) -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index 149ceb5c94ff..af1f5742b4f8 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -348,7 +348,7 @@ static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb) - tcp_enter_quickack_mode(sk, 2); - break; - case INET_ECN_CE: -- if (tcp_ca_needs_ecn(sk)) -+ if (tcp_ca_wants_ce_events(sk)) - tcp_ca_event(sk, CA_EVENT_ECN_IS_CE); - - if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) { -@@ -359,7 +359,7 @@ static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb) - tp->ecn_flags |= TCP_ECN_SEEN; - break; - default: -- if (tcp_ca_needs_ecn(sk)) -+ if (tcp_ca_wants_ce_events(sk)) - tcp_ca_event(sk, CA_EVENT_ECN_NO_CE); - tp->ecn_flags |= TCP_ECN_SEEN; - break; -@@ -1039,7 +1039,12 @@ static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb) - */ - static void tcp_notify_skb_loss_event(struct tcp_sock *tp, const struct sk_buff *skb) - { -+ struct sock *sk = (struct sock *)tp; -+ const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; -+ - tp->lost += tcp_skb_pcount(skb); -+ if (ca_ops->skb_marked_lost) -+ ca_ops->skb_marked_lost(sk, skb); - } - - void tcp_mark_skb_lost(struct sock *sk, struct sk_buff *skb) -@@ -1420,6 +1425,17 @@ static bool tcp_shifted_skb(struct sock *sk, struct sk_buff *prev, - WARN_ON_ONCE(tcp_skb_pcount(skb) < pcount); - tcp_skb_pcount_add(skb, -pcount); - -+ /* Adjust tx.in_flight as pcount is shifted from skb to prev. */ -+ if (WARN_ONCE(TCP_SKB_CB(skb)->tx.in_flight < pcount, -+ "prev in_flight: %u skb in_flight: %u pcount: %u", -+ TCP_SKB_CB(prev)->tx.in_flight, -+ TCP_SKB_CB(skb)->tx.in_flight, -+ pcount)) -+ TCP_SKB_CB(skb)->tx.in_flight = 0; -+ else -+ TCP_SKB_CB(skb)->tx.in_flight -= pcount; -+ TCP_SKB_CB(prev)->tx.in_flight += pcount; -+ - /* When we're adding to gso_segs == 1, gso_size will be zero, - * in theory this shouldn't be necessary but as long as DSACK - * code can come after this skb later on it's better to keep -@@ -3189,7 +3205,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, const struct sk_buff *ack_skb, - long seq_rtt_us = -1L; - long ca_rtt_us = -1L; - u32 pkts_acked = 0; -- u32 last_in_flight = 0; - bool rtt_update; - int flag = 0; - -@@ -3225,7 +3240,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, const struct sk_buff *ack_skb, - if (!first_ackt) - first_ackt = last_ackt; - -- last_in_flight = TCP_SKB_CB(skb)->tx.in_flight; - if (before(start_seq, reord)) - reord = start_seq; - if (!after(scb->end_seq, tp->high_seq)) -@@ -3291,8 +3305,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, const struct sk_buff *ack_skb, - seq_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, first_ackt); - ca_rtt_us = tcp_stamp_us_delta(tp->tcp_mstamp, last_ackt); - -- if (pkts_acked == 1 && last_in_flight < tp->mss_cache && -- last_in_flight && !prior_sacked && fully_acked && -+ if (pkts_acked == 1 && fully_acked && !prior_sacked && -+ (tp->snd_una - prior_snd_una) < tp->mss_cache && - sack->rate->prior_delivered + 1 == tp->delivered && - !(flag & (FLAG_CA_ALERT | FLAG_SYN_ACKED))) { - /* Conservatively mark a delayed ACK. It's typically -@@ -3349,9 +3363,10 @@ static int tcp_clean_rtx_queue(struct sock *sk, const struct sk_buff *ack_skb, - - if (icsk->icsk_ca_ops->pkts_acked) { - struct ack_sample sample = { .pkts_acked = pkts_acked, -- .rtt_us = sack->rate->rtt_us, -- .in_flight = last_in_flight }; -+ .rtt_us = sack->rate->rtt_us }; - -+ sample.in_flight = tp->mss_cache * -+ (tp->delivered - sack->rate->prior_delivered); - icsk->icsk_ca_ops->pkts_acked(sk, &sample); - } - -@@ -3749,6 +3764,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) - - prior_fack = tcp_is_sack(tp) ? tcp_highest_sack_seq(tp) : tp->snd_una; - rs.prior_in_flight = tcp_packets_in_flight(tp); -+ tcp_rate_check_app_limited(sk); - - /* ts_recent update must be made after we are sure that the packet - * is in window. -@@ -3846,6 +3862,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) - delivered = tcp_newly_delivered(sk, delivered, flag); - lost = tp->lost - lost; /* freshly marked lost */ - rs.is_ack_delayed = !!(flag & FLAG_ACK_MAYBE_DELAYED); -+ rs.is_ece = !!(flag & FLAG_ECE); - tcp_rate_gen(sk, delivered, lost, is_sack_reneg, sack_state.rate); - tcp_cong_control(sk, ack, delivered, flag, sack_state.rate); - tcp_xmit_recovery(sk, rexmit); -@@ -5414,13 +5431,14 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) - - /* More than one full frame received... */ - if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && -+ (tp->fast_ack_mode == 1 || - /* ... and right edge of window advances far enough. - * (tcp_recvmsg() will send ACK otherwise). - * If application uses SO_RCVLOWAT, we want send ack now if - * we have not received enough bytes to satisfy the condition. - */ -- (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat || -- __tcp_select_window(sk) >= tp->rcv_wnd)) || -+ (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat || -+ __tcp_select_window(sk) >= tp->rcv_wnd))) || - /* We ACK each frame or... */ - tcp_in_quickack_mode(sk) || - /* Protocol state mandates a one-time immediate ACK */ -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 29553fce8502..0eb462008718 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -377,7 +377,8 @@ static void tcp_ecn_send(struct sock *sk, struct sk_buff *skb, - th->cwr = 1; - skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; - } -- } else if (!tcp_ca_needs_ecn(sk)) { -+ } else if (!(tp->ecn_flags & TCP_ECN_ECT_PERMANENT) && -+ !tcp_ca_needs_ecn(sk)) { - /* ACK or retransmitted segment: clear ECT|CE */ - INET_ECN_dontxmit(sk); - } -@@ -1256,8 +1257,6 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, - tp->tcp_wstamp_ns = max(tp->tcp_wstamp_ns, tp->tcp_clock_cache); - skb->skb_mstamp_ns = tp->tcp_wstamp_ns; - if (clone_it) { -- TCP_SKB_CB(skb)->tx.in_flight = TCP_SKB_CB(skb)->end_seq -- - tp->snd_una; - oskb = skb; - - tcp_skb_tsorted_save(oskb) { -@@ -1536,7 +1535,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue, - { - struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *buff; -- int nsize, old_factor; -+ int nsize, old_factor, inflight_prev; - long limit; - int nlen; - u8 flags; -@@ -1615,6 +1614,15 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue, - - if (diff) - tcp_adjust_pcount(sk, skb, diff); -+ -+ /* Set buff tx.in_flight as if buff were sent by itself. */ -+ inflight_prev = TCP_SKB_CB(skb)->tx.in_flight - old_factor; -+ if (WARN_ONCE(inflight_prev < 0, -+ "inconsistent: tx.in_flight: %u old_factor: %d", -+ TCP_SKB_CB(skb)->tx.in_flight, old_factor)) -+ inflight_prev = 0; -+ TCP_SKB_CB(buff)->tx.in_flight = inflight_prev + -+ tcp_skb_pcount(buff); - } - - /* Link BUFF into the send queue. */ -@@ -1983,13 +1991,12 @@ static u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now, - static u32 tcp_tso_segs(struct sock *sk, unsigned int mss_now) - { - const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; -- u32 min_tso, tso_segs; -+ u32 tso_segs; - -- min_tso = ca_ops->min_tso_segs ? -- ca_ops->min_tso_segs(sk) : -- sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs; -- -- tso_segs = tcp_tso_autosize(sk, mss_now, min_tso); -+ tso_segs = ca_ops->tso_segs ? -+ ca_ops->tso_segs(sk, mss_now) : -+ tcp_tso_autosize(sk, mss_now, -+ sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs); - return min_t(u32, tso_segs, sk->sk_gso_max_segs); - } - -@@ -2629,6 +2636,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, - skb->skb_mstamp_ns = tp->tcp_wstamp_ns = tp->tcp_clock_cache; - list_move_tail(&skb->tcp_tsorted_anchor, &tp->tsorted_sent_queue); - tcp_init_tso_segs(skb, mss_now); -+ tcp_set_tx_in_flight(sk, skb); - goto repair; /* Skip network transmission */ - } - -diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c -index 0de693565963..796fa6e5310c 100644 ---- a/net/ipv4/tcp_rate.c -+++ b/net/ipv4/tcp_rate.c -@@ -34,6 +34,24 @@ - * ready to send in the write queue. - */ - -+void tcp_set_tx_in_flight(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 in_flight; -+ -+ /* Check, sanitize, and record packets in flight after skb was sent. */ -+ in_flight = tcp_packets_in_flight(tp) + tcp_skb_pcount(skb); -+ if (WARN_ONCE(in_flight > TCPCB_IN_FLIGHT_MAX, -+ "insane in_flight %u cc %s mss %u " -+ "cwnd %u pif %u %u %u %u\n", -+ in_flight, inet_csk(sk)->icsk_ca_ops->name, -+ tp->mss_cache, tp->snd_cwnd, -+ tp->packets_out, tp->retrans_out, -+ tp->sacked_out, tp->lost_out)) -+ in_flight = TCPCB_IN_FLIGHT_MAX; -+ TCP_SKB_CB(skb)->tx.in_flight = in_flight; -+} -+ - /* Snapshot the current delivery information in the skb, to generate - * a rate sample later when the skb is (s)acked in tcp_rate_skb_delivered(). - */ -@@ -65,7 +83,10 @@ void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb) - TCP_SKB_CB(skb)->tx.first_tx_mstamp = tp->first_tx_mstamp; - TCP_SKB_CB(skb)->tx.delivered_mstamp = tp->delivered_mstamp; - TCP_SKB_CB(skb)->tx.delivered = tp->delivered; -+ TCP_SKB_CB(skb)->tx.delivered_ce = tp->delivered_ce; -+ TCP_SKB_CB(skb)->tx.lost = tp->lost; - TCP_SKB_CB(skb)->tx.is_app_limited = tp->app_limited ? 1 : 0; -+ tcp_set_tx_in_flight(sk, skb); - } - - /* When an skb is sacked or acked, we fill in the rate sample with the (prior) -@@ -86,16 +107,20 @@ void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb, - - if (!rs->prior_delivered || - after(scb->tx.delivered, rs->prior_delivered)) { -+ rs->prior_lost = scb->tx.lost; -+ rs->prior_delivered_ce = scb->tx.delivered_ce; - rs->prior_delivered = scb->tx.delivered; - rs->prior_mstamp = scb->tx.delivered_mstamp; - rs->is_app_limited = scb->tx.is_app_limited; - rs->is_retrans = scb->sacked & TCPCB_RETRANS; -+ rs->tx_in_flight = scb->tx.in_flight; - - /* Record send time of most recently ACKed packet: */ - tp->first_tx_mstamp = tcp_skb_timestamp_us(skb); - /* Find the duration of the "send phase" of this window: */ -- rs->interval_us = tcp_stamp_us_delta(tp->first_tx_mstamp, -- scb->tx.first_tx_mstamp); -+ rs->interval_us = tcp_stamp32_us_delta( -+ tp->first_tx_mstamp, -+ scb->tx.first_tx_mstamp); - - } - /* Mark off the skb delivered once it's sacked to avoid being -@@ -137,6 +162,11 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, - return; - } - rs->delivered = tp->delivered - rs->prior_delivered; -+ rs->lost = tp->lost - rs->prior_lost; -+ -+ rs->delivered_ce = tp->delivered_ce - rs->prior_delivered_ce; -+ /* delivered_ce occupies less than 32 bits in the skb control block */ -+ rs->delivered_ce &= TCPCB_DELIVERED_CE_MASK; - - /* Model sending data and receiving ACKs as separate pipeline phases - * for a window. Usually the ACK phase is longer, but with ACK -@@ -144,7 +174,7 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, - * longer phase. - */ - snd_us = rs->interval_us; /* send phase */ -- ack_us = tcp_stamp_us_delta(tp->tcp_mstamp, -+ ack_us = tcp_stamp32_us_delta(tp->tcp_mstamp, - rs->prior_mstamp); /* ack phase */ - rs->interval_us = max(snd_us, ack_us); - -diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c -index 20cf4a98c69d..b5f7e49a003a 100644 ---- a/net/ipv4/tcp_timer.c -+++ b/net/ipv4/tcp_timer.c -@@ -607,6 +607,7 @@ void tcp_write_timer_handler(struct sock *sk) - goto out; - } - -+ tcp_rate_check_app_limited(sk); - tcp_mstamp_refresh(tcp_sk(sk)); - event = icsk->icsk_pending; - --- -2.33.0 - diff --git a/sys-kernel_arch-sources-g14_files-9008-fix-cpu-hotplug.patch b/sys-kernel_arch-sources-g14_files-9008-fix-cpu-hotplug.patch deleted file mode 100644 index f80a0850d67a..000000000000 --- a/sys-kernel_arch-sources-g14_files-9008-fix-cpu-hotplug.patch +++ /dev/null @@ -1,73 +0,0 @@ -Date: Fri, 13 Aug 2021 11:18:42 -0500 [thread overview] -Message-ID: <20210813161842.222414-1-mario.limonciello@amd.com> (raw) - -A number of systems are showing "hotplug capable" CPUs when they -are not really hotpluggable. This is because the MADT has extra -CPU entries to support different CPUs that may be inserted into -the socket with different numbers of cores. - -Starting with ACPI 6.3 the spec has an Online Capable bit in the -MADT used to determine whether or not a CPU is hotplug capable -when the enabled bit is not set. - -Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html?#local-apic-flags -Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> ---- - arch/x86/kernel/acpi/boot.c | 10 ++++++++++ - include/acpi/actbl2.h | 1 + - 2 files changed, 11 insertions(+) - -Changes from v1->v2: - * Check the revision field in MADT to determine if it matches the - bump from ACPI 6.3 as suggested by Hanjun Guo - * Update description - -diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c -index e55e0c1fad8c..bfa69a5c9c0b 100644 ---- a/arch/x86/kernel/acpi/boot.c -+++ b/arch/x86/kernel/acpi/boot.c -@@ -53,6 +53,8 @@ int acpi_ioapic; - int acpi_strict; - int acpi_disable_cmcff; - -+bool acpi_support_online_capable; -+ - /* ACPI SCI override configuration */ - u8 acpi_sci_flags __initdata; - u32 acpi_sci_override_gsi __initdata = INVALID_ACPI_IRQ; -@@ -138,6 +140,8 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) - - pr_debug("Local APIC address 0x%08x\n", madt->address); - } -+ if (madt->header.revision >= 5) -+ acpi_support_online_capable = true; - - default_acpi_madt_oem_check(madt->header.oem_id, - madt->header.oem_table_id); -@@ -239,6 +243,12 @@ acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end) - if (processor->id == 0xff) - return 0; - -+ /* don't register processors that can not be onlined */ -+ if (acpi_support_online_capable && -+ !(processor->lapic_flags & ACPI_MADT_ENABLED) && -+ !(processor->lapic_flags & ACPI_MADT_ONLINE_CAPABLE)) -+ return 0; -+ - /* - * We need to register disabled CPU as well to permit - * counting disabled CPUs. This allows us to size -diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h -index 2069ac38a4e2..fae45e383987 100644 ---- a/include/acpi/actbl2.h -+++ b/include/acpi/actbl2.h -@@ -808,6 +808,7 @@ struct acpi_madt_multiproc_wakeup_mailbox { - /* MADT Local APIC flags */ - - #define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */ -+#define ACPI_MADT_ONLINE_CAPABLE (2) /* 01: System HW supports enabling processor at runtime */ - - /* MADT MPS INTI flags (inti_flags) */ - --- -2.25.1
\ No newline at end of file diff --git a/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch b/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch deleted file mode 100644 index da19351fa6a8..000000000000 --- a/sys-kernel_arch-sources-g14_files-9009-amd-pstate-sqashed.patch +++ /dev/null @@ -1,2298 +0,0 @@ -From e0aeb1b7aaf55f3550cac74057c0d850c6a8f24e Mon Sep 17 00:00:00 2001 -From: Scott B <arglebargle@arglebargle.dev> -Date: Sun, 26 Sep 2021 11:02:58 -0700 -Subject: [PATCH] amd-pstate v2 - -Squashed commit of the following: - -commit 15a541d4c1406bad735799bc0d663ac8c8ed860f -Author: Huang Rui <ray.huang@amd.com> -Date: Thu Jun 10 23:40:18 2021 +0800 - - Documentation: amd-pstate: add amd-pstate driver introduction - - Introduce the amd-pstate driver design and implementation. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 556f332dc97bf90e2df72482fd1d078bd9206ab4 -Author: Huang Rui <ray.huang@amd.com> -Date: Thu Jun 10 23:48:03 2021 +0800 - - cpupower: print amd-pstate information on cpupower - - amd-pstate kernel module is using the fine grain frequency instead of - acpi hardware pstate. So the performance and frequency values should be - printed in frequency-info. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 8f775fa6057be3964ecdfe0616b15ac515dafc97 -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Sep 26 16:26:06 2021 +0800 - - cpupower: move print_speed function into misc helper - - The print_speed can be as a common function, and expose it into misc - helper header. Then it can be used on other helper files as well. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit ecd25fc5e7776669011b06ec0142c42224e415fd -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Jun 20 17:35:45 2021 +0800 - - cpupower: enable boost state support for amd-pstate module - - The legacy ACPI hardware P-States function has 3 P-States on ACPI table, - the CPU frequency only can be switched between the 3 P-States. While the - processor supports the boost state, it will have another boost state - that the frequency can be higher than P0 state, and the state can be - decoded by the function of decode_pstates() and read by - amd_pci_get_num_boost_states(). - - However, the new AMD P-States function is different than legacy ACPI - hardware P-State on AMD processors. That has a finer grain frequency - range between the highest and lowest frequency. And boost frequency is - actually the frequency which is mapped on highest performance ratio. The - similiar previous P0 frequency is mapped on nominal performance ratio. - If the highest performance on the processor is higher than nominal - performance, then we think the current processor supports the boost - state. And it uses amd_pstate_boost_init() to initialize boost for AMD - P-States function. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit bdbc7ab476c821eadefa00b89e80f33439749bf6 -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Jun 20 17:07:25 2021 +0800 - - cpupower: add amd-pstate sysfs definition and access helper - - Introduce the marco definitions and access helper function for - amd-pstate sysfs interfaces such as each performance goals and frequency - levels in amd helper file. They will be used to read the sysfs attribute - from amd-pstate cpufreq driver for cpupower utilities. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit e8d0f2a79d9ea76c838bc253389c3642139ebf05 -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Sep 26 10:55:53 2021 +0800 - - cpupower: add the function to get the sysfs value from specific table - - Expose the helper into cpufreq header, then cpufreq driver can use this - function to get the sysfs value if it has any specific sysfs interfaces. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit c084ef5a4583083d09812801fcc4f881b6b80102 -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Jun 27 22:40:14 2021 +0800 - - cpupower: initial AMD P-state capability - - If kernel starts the amd-pstate module, the cpupower will initial the - capability flag as CPUPOWER_CAP_AMD_PSTATE. And once amd-pstate - capability is set, it won't need to set legacy ACPI relative - capabilities anymore. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit f531c849130c1104ad81232bcd03ab6e17f2661d -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Jun 27 22:25:39 2021 +0800 - - cpupower: add the function to check amd-pstate enabled - - The processor with amd-pstate function also supports legacy ACPI - hardware P-States feature as well. Once driver sets amd-pstate eanbled, - the processor will respond the finer grain amd-pstate feature instead of - legacy ACPI P-States. So it introduces the cpupower_amd_pstate_enabled() - to check whether the current kernel enables amd-pstate or acpi-cpufreq - module. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 510b487ccfe71ab5c19e2d0ef624f8925f15f600 -Author: Huang Rui <ray.huang@amd.com> -Date: Mon Jun 14 22:52:01 2021 +0800 - - cpupower: add AMD P-state capability flag - - Add AMD P-state capability flag in cpupower to indicate AMD new P-state - kernel module support on Ryzen processors. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 4351bf1becc53385a8ea76ddef076a753062309b -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Jun 20 15:01:08 2021 +0800 - - cpufreq: amd: add amd-pstate performance attributes - - Introduce sysfs attributes to get the different level amd-pstate - performances. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 264932a7ddbee32b36af09261cc921e67bcdc61d -Author: Huang Rui <ray.huang@amd.com> -Date: Sun Jun 20 13:26:01 2021 +0800 - - cpufreq: amd: add amd-pstate frequencies attributes - - Introduce sysfs attributes to get the different level processor - frequencies. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 40fde676994657f0c27cffb192d43f52e8da1c3d -Author: Huang Rui <ray.huang@amd.com> -Date: Sat Jun 19 23:41:30 2021 +0800 - - cpufreq: amd: add amd-pstate checking support check attribute - - The amd-pstate hardware support check will be needed by cpupower to know - whether amd-pstate is enabled and supported. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 690f2eaa700abee63d31c17873deac058433125b -Author: Huang Rui <ray.huang@amd.com> -Date: Thu Jun 10 23:13:00 2021 +0800 - - cpufreq: amd: add boost mode support for amd-pstate - - If the sbios supports the boost mode of amd-pstate, let's switch to - boost enabled by default. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit c9876ed4e1b126300ae8eecb2c3db64b2d043f88 -Author: Huang Rui <ray.huang@amd.com> -Date: Thu Jun 10 20:24:00 2021 +0800 - - cpufreq: amd: add trace for amd-pstate module - - Add trace event to monitor the performance value changes which is - controlled by cpu governors. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 668359efad049de2efaedffa4a94a029f6a24982 -Author: Huang Rui <ray.huang@amd.com> -Date: Mon Aug 9 19:06:51 2021 +0800 - - cpufreq: amd: add acpi cppc function as the backend for legacy processors - - In some old Zen based processors, they are using the shared memory that - exposed from ACPI SBIOS. - - Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com> - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 735f6c6664e3da48e67b44a6a59f9fa4b82c576d -Author: Huang Rui <ray.huang@amd.com> -Date: Fri Aug 13 18:43:47 2021 +0800 - - cpufreq: amd: add fast switch function for amd-pstate module - - Introduce the fast switch function for amd-pstate module on the AMD - processors which support the full MSR register control. It's able to - decrease the lattency on interrupt context. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit ecab8f33c0660e9c96c42a5c27078a324185d601 -Author: Huang Rui <ray.huang@amd.com> -Date: Thu Jun 10 18:04:45 2021 +0800 - - cpufreq: amd: introduce a new amd pstate driver to support future processors - - amd-pstate is the AMD CPU performance scaling driver that introduces a - new CPU frequency control mechanism on AMD Zen based CPU series in Linux - kernel. The new mechanism is based on Collaborative processor - performance control (CPPC) which is finer grain frequency management - than legacy ACPI hardware P-States. Current AMD CPU platforms are using - the ACPI P-states driver to manage CPU frequency and clocks with - switching only in 3 P-states. AMD P-States is to replace the ACPI - P-states controls, allows a flexible, low-latency interface for the - Linux kernel to directly communicate the performance hints to hardware. - - "amd-pstate" leverages the Linux kernel governors such as *schedutil*, - *ondemand*, etc. to manage the performance hints which are provided by CPPC - hardware functionality. The first version for amd-pstate is to support one - of the Zen3 processors, and we will support more in future after we verify - the hardware and SBIOS functionalities. - - There are two types of hardware implementations for amd-pstate: one is full - MSR support and another is shared memory support. It can use - X86_FEATURE_AMD_CPPC_EXT feature flag to distinguish the different types. - - Using the new AMD P-States method + kernel governors (*schedutil*, - *ondemand*, ...) to manage the frequency update is the most appropriate - bridge between AMD Zen based hardware processor and Linux kernel, the - processor is able to ajust to the most efficiency frequency according to - the kernel scheduler loading. - - Performance Per Watt (PPW) Caculation: - - The PPW caculation is referred by below paper: - https://software.intel.com/content/dam/develop/external/us/en/documents/performance-per-what-paper.pdf - - Below formula is referred from below spec to measure the PPW: - - (F / t) / P = F * t / (t * E) = F / E, - - "F" is the number of frames per second. - "P" is power measurd in watts. - "E" is energy measured in joules. - - We use the RAPL interface with "perf" tool to get the energy data of the - package power. - - The data comparsions between amd-pstate and acpi-freq module are tested on - AMD Cezanne processor: - - 1) TBench CPU benchmark: - - +---------------------------------------------------------------------+ - | | - | TBench (Performance Per Watt) | - | Higher is better | - +-------------------+------------------------+------------------------+ - | | Performance Per Watt | Performance Per Watt | - | Kernel Module | (Schedutil) | (Ondemand) | - | | Unit: MB / (s * J) | Unit: MB / (s * J) | - +-------------------+------------------------+------------------------+ - | | | | - | acpi-cpufreq | 3.022 | 2.969 | - | | | | - +-------------------+------------------------+------------------------+ - | | | | - | amd-pstate | 3.131 | 3.284 | - | | | | - +-------------------+------------------------+------------------------+ - - 2) Gitsource CPU benchmark: - - +---------------------------------------------------------------------+ - | | - | Gitsource (Performance Per Watt) | - | Higher is better | - +-------------------+------------------------+------------------------+ - | | Performance Per Watt | Performance Per Watt | - | Kernel Module | (Schedutil) | (Ondemand) | - | | Unit: 1 / (s * J) | Unit: 1 / (s * J) | - +-------------------+------------------------+------------------------+ - | | | | - | acpi-cpufreq | 3.42172E-07 | 2.74508E-07 | - | | | | - +-------------------+------------------------+------------------------+ - | | | | - | amd-pstate | 4.09141E-07 | 3.47610E-07 | - | | | | - +-------------------+------------------------+------------------------+ - - 3) Speedometer 2.0 CPU benchmark: - - +---------------------------------------------------------------------+ - | | - | Speedometer 2.0 (Performance Per Watt) | - | Higher is better | - +-------------------+------------------------+------------------------+ - | | Performance Per Watt | Performance Per Watt | - | Kernel Module | (Schedutil) | (Ondemand) | - | | Unit: 1 / (s * J) | Unit: 1 / (s * J) | - +-------------------+------------------------+------------------------+ - | | | | - | acpi-cpufreq | 0.116111767 | 0.110321664 | - | | | | - +-------------------+------------------------+------------------------+ - | | | | - | amd-pstate | 0.115825281 | 0.122024299 | - | | | | - +-------------------+------------------------+------------------------+ - - According to above average data, we can see this solution has shown better - performance per watt scaling on mobile CPU benchmarks in most of cases. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 47c390a1770904355262aef37bc25f0cee3cc3fc -Author: Jinzhou Su <Jinzhou.Su@amd.com> -Date: Mon Aug 9 19:04:17 2021 +0800 - - ACPI: CPPC: add cppc enable register function - - Add a new function to enable CPPC feature. This function - will write Continuous Performance Control package - EnableRegister field on the processor. - - Signed-off-by: Jinzhou Su <Jinzhou.Su@amd.com> - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 3b19018de66c74ed41fa6b9241fa5cffbbade6b2 -Author: Mario Limonciello <mario.limonciello@amd.com> -Date: Wed Jul 28 05:48:34 2021 +0800 - - ACPI: CPPC: Check online CPUs for determining _CPC is valid - - As this is a static check, it should be based upon what is currently - present on the system. This makes probeing more deterministic. - - While local APIC flags field (lapic_flags) of cpu core in MADT table is - 0, then the cpu core won't be enabled. In this case, _CPC won't be found - in this core, and return back to _CPC invalid with walking through - possible cpus (include disable cpus). This is not expected, so switch to - check online CPUs instead. - - Reported-by: Jinzhou Su <Jinzhou.Su@amd.com> - Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 2ab6419bfa88161ec5cf0ff45681923c793d9eff -Author: Huang Rui <ray.huang@amd.com> -Date: Mon Jan 25 15:50:24 2021 +0800 - - x86/msr: add AMD CPPC MSR definitions - - AMD CPPC (Collaborative Processor Performance Control) function uses MSR - registers to manage the performance hints. So add the MSR register macro - here. - - Signed-off-by: Huang Rui <ray.huang@amd.com> - -commit 1993446c3c798df5946f0717122f545dd8f1278d -Author: Huang Rui <ray.huang@amd.com> -Date: Thu Jan 28 10:50:26 2021 +0800 - - x86/cpufreatures: add AMD Collaborative Processor Performance Control feature flag - - Add Collaborative Processor Performance Control feature flag for AMD - processors. - - This feature flag will be used on the following amd-pstate driver. The - amd-pstate driver has two approaches to implement the frequency control - behavior. That depends on the CPU hardware implementation. One is "Full - MSR Support" and another is "Shared Memory Support". The feature flag - indicates the current processors with "Full MSR Support". - - Signed-off-by: Huang Rui <ray.huang@amd.com> ---- - Documentation/admin-guide/pm/amd_pstate.rst | 377 +++++++++ - .../admin-guide/pm/working-state.rst | 1 + - arch/x86/include/asm/cpufeatures.h | 1 + - arch/x86/include/asm/msr-index.h | 17 + - drivers/acpi/cppc_acpi.c | 50 +- - drivers/cpufreq/Kconfig.x86 | 13 + - drivers/cpufreq/Makefile | 5 + - drivers/cpufreq/amd-pstate-trace.c | 2 + - drivers/cpufreq/amd-pstate-trace.h | 96 +++ - drivers/cpufreq/amd-pstate.c | 724 ++++++++++++++++++ - include/acpi/cppc_acpi.h | 5 + - tools/power/cpupower/lib/cpufreq.c | 21 +- - tools/power/cpupower/lib/cpufreq.h | 12 + - tools/power/cpupower/utils/cpufreq-info.c | 68 +- - tools/power/cpupower/utils/helpers/amd.c | 82 ++ - tools/power/cpupower/utils/helpers/cpuid.c | 13 + - tools/power/cpupower/utils/helpers/helpers.h | 21 + - tools/power/cpupower/utils/helpers/misc.c | 64 ++ - 18 files changed, 1514 insertions(+), 58 deletions(-) - create mode 100644 Documentation/admin-guide/pm/amd_pstate.rst - create mode 100644 drivers/cpufreq/amd-pstate-trace.c - create mode 100644 drivers/cpufreq/amd-pstate-trace.h - create mode 100644 drivers/cpufreq/amd-pstate.c - -diff --git a/Documentation/admin-guide/pm/amd_pstate.rst b/Documentation/admin-guide/pm/amd_pstate.rst -new file mode 100644 -index 000000000000..c3659dde0cee ---- /dev/null -+++ b/Documentation/admin-guide/pm/amd_pstate.rst -@@ -0,0 +1,377 @@ -+.. SPDX-License-Identifier: GPL-2.0 -+.. include:: <isonum.txt> -+ -+=============================================== -+``amd-pstate`` CPU Performance Scaling Driver -+=============================================== -+ -+:Copyright: |copy| 2021 Advanced Micro Devices, Inc. -+ -+:Author: Huang Rui <ray.huang@amd.com> -+ -+ -+Introduction -+=================== -+ -+``amd-pstate`` is the AMD CPU performance scaling driver that introduces a -+new CPU frequency control mechanism on modern AMD APU and CPU series in -+Linux kernel. The new mechanism is based on Collaborative Processor -+Performance Control (CPPC) which provides finer grain frequency management -+than legacy ACPI hardware P-States. Current AMD CPU/APU platforms are using -+the ACPI P-states driver to manage CPU frequency and clocks with switching -+only in 3 P-states. CPPC replaces the ACPI P-states controls, allows a -+flexible, low-latency interface for the Linux kernel to directly -+communicate the performance hints to hardware. -+ -+``amd-pstate`` leverages the Linux kernel governors such as ``schedutil``, -+``ondemand``, etc. to manage the performance hints which are provided by -+CPPC hardware functionality that internally follows the hardware -+specification (for details refer to AMD64 Architecture Programmer's Manual -+Volume 2: System Programming [1]_). Currently ``amd-pstate`` supports basic -+frequency control function according to kernel governors on some of the -+Zen2 and Zen3 processors, and we will implement more AMD specific functions -+in future after we verify them on the hardware and SBIOS. -+ -+ -+AMD CPPC Overview -+======================= -+ -+Collaborative Processor Performance Control (CPPC) interface enumerates a -+continuous, abstract, and unit-less performance value in a scale that is -+not tied to a specific performance state / frequency. This is an ACPI -+standard [2]_ which software can specify application performance goals and -+hints as a relative target to the infrastructure limits. AMD processors -+provides the low latency register model (MSR) instead of AML code -+interpreter for performance adjustments. ``amd-pstate`` will initialize a -+``struct cpufreq_driver`` instance ``amd_pstate_driver`` with the callbacks -+to manage each performance update behavior. :: -+ -+ Highest Perf ------>+-----------------------+ +-----------------------+ -+ | | | | -+ | | | | -+ | | Max Perf ---->| | -+ | | | | -+ | | | | -+ Nominal Perf ------>+-----------------------+ +-----------------------+ -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | Desired Perf ---->| | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ | | | | -+ Lowest non- | | | | -+ linear perf ------>+-----------------------+ +-----------------------+ -+ | | | | -+ | | Lowest perf ---->| | -+ | | | | -+ Lowest perf ------>+-----------------------+ +-----------------------+ -+ | | | | -+ | | | | -+ | | | | -+ 0 ------>+-----------------------+ +-----------------------+ -+ -+ AMD P-States Performance Scale -+ -+ -+.. _perf_cap: -+ -+AMD CPPC Performance Capability -+-------------------------------- -+ -+Highest Performance (RO) -+......................... -+ -+It is the absolute maximum performance an individual processor may reach, -+assuming ideal conditions. This performance level may not be sustainable -+for long durations and may only be achievable if other platform components -+are in a specific state; for example, it may require other processors be in -+an idle state. This would be equivalent to the highest frequencies -+supported by the processor. -+ -+Nominal (Guaranteed) Performance (RO) -+...................................... -+ -+It is the maximum sustained performance level of the processor, assuming -+ideal operating conditions. In absence of an external constraint (power, -+thermal, etc.) this is the performance level the processor is expected to -+be able to maintain continuously. All cores/processors are expected to be -+able to sustain their nominal performance state simultaneously. -+ -+Lowest non-linear Performance (RO) -+................................... -+ -+It is the lowest performance level at which nonlinear power savings are -+achieved, for example, due to the combined effects of voltage and frequency -+scaling. Above this threshold, lower performance levels should be generally -+more energy efficient than higher performance levels. This register -+effectively conveys the most efficient performance level to ``amd-pstate``. -+ -+Lowest Performance (RO) -+........................ -+ -+It is the absolute lowest performance level of the processor. Selecting a -+performance level lower than the lowest nonlinear performance level may -+cause an efficiency penalty but should reduce the instantaneous power -+consumption of the processor. -+ -+AMD CPPC Performance Control -+------------------------------ -+ -+``amd-pstate`` passes performance goals through these registers. The -+register drives the behavior of the desired performance target. -+ -+Minimum requested performance (RW) -+................................... -+ -+``amd-pstate`` specifies the minimum allowed performance level. -+ -+Maximum requested performance (RW) -+................................... -+ -+``amd-pstate`` specifies a limit the maximum performance that is expected -+to be supplied by the hardware. -+ -+Desired performance target (RW) -+................................... -+ -+``amd-pstate`` specifies a desired target in the CPPC performance scale as -+a relative number. This can be expressed as percentage of nominal -+performance (infrastructure max). Below the nominal sustained performance -+level, desired performance expresses the average performance level of the -+processor subject to hardware. Above the nominal performance level, -+processor must provide at least nominal performance requested and go higher -+if current operating conditions allow. -+ -+Energy Performance Preference (EPP) (RW) -+......................................... -+ -+Provides a hint to the hardware if software wants to bias toward performance -+(0x0) or energy efficiency (0xff). -+ -+ -+Key Governors Support -+======================= -+ -+``amd-pstate`` can be used with all the (generic) scaling governors listed -+by the ``scaling_available_governors`` policy attribute in ``sysfs``. Then, -+it is responsible for the configuration of policy objects corresponding to -+CPUs and provides the ``CPUFreq`` core (and the scaling governors attached -+to the policy objects) with accurate information on the maximum and minimum -+operating frequencies supported by the hardware. Users can check the -+``scaling_cur_freq`` information comes from the ``CPUFreq`` core. -+ -+``amd-pstate`` mainly supports ``schedutil`` and ``ondemand`` for dynamic -+frequency control. It is to fine tune the processor configuration on -+``amd-pstate`` to the ``schedutil`` with CPU CFS scheduler. ``amd-pstate`` -+registers adjust_perf callback to implement the CPPC similar performance -+update behavior. It is initialized by ``sugov_start`` and then populate the -+CPU's update_util_data pointer to assign ``sugov_update_single_perf`` as -+the utilization update callback function in CPU scheduler. CPU scheduler -+will call ``cpufreq_update_util`` and assign the target performance -+according to the ``struct sugov_cpu`` that utilization update belongs to. -+Then ``amd-pstate`` updates the desired performance according to the CPU -+scheduler assigned. -+ -+ -+Processor Support -+======================= -+ -+The ``amd-pstate`` initialization will fail if the _CPC in ACPI SBIOS is -+not existed at the detected processor, and it uses ``acpi_cpc_valid`` to -+check the _CPC existence. All Zen based processors support legacy ACPI -+hardware P-States function, so while the ``amd-pstate`` fails to be -+initialized, the kernel will fall back to initialize ``acpi-cpufreq`` -+driver. -+ -+There are two types of hardware implementations for ``amd-pstate``: one is -+`Full MSR Support <perf_cap_>`_ and another is `Shared Memory Support -+<perf_cap_>`_. It can use :c:macro:`X86_FEATURE_AMD_CPPC_EXT` feature flag -+(for details refer to Processor Programming Reference (PPR) for AMD Family -+19h Model 21h, Revision B0 Processors [3]_) to indicate the different -+types. ``amd-pstate`` is to register different ``amd_pstate_perf_funcs`` -+instances for different hardware implementations. -+ -+Currently, some of Zen2 and Zen3 processors support ``amd-pstate``. In the -+future, it will be supported on more and more AMD processors. -+ -+Full MSR Support -+----------------- -+ -+Some new Zen3 processors such as Cezanne provide the MSR registers directly -+while the :c:macro:`X86_FEATURE_AMD_CPPC_EXT` CPU feature flag is set. -+``amd-pstate`` can handle the MSR register to implement the fast switch -+function in ``CPUFreq`` that can shrink latency of frequency control on the -+interrupt context. -+ -+Shared Memory Support -+---------------------- -+ -+If :c:macro:`X86_FEATURE_AMD_CPPC_EXT` CPU feature flag is not set, that -+means the processor supports shared memory solution. In this case, -+``amd-pstate`` uses the ``cppc_acpi`` helper methods to implement the -+callback functions of ``amd_pstate_perf_funcs``. -+ -+ -+AMD P-States and ACPI hardware P-States always can be supported in one -+processor. But AMD P-States has the higher priority and if it is enabled -+with :c:macro:`MSR_AMD_CPPC_ENABLE` or ``cppc_set_enable``, it will respond -+to the request from AMD P-States. -+ -+ -+User Space Interface in ``sysfs`` -+================================== -+ -+``amd-pstate`` exposes several global attributes (files) in ``sysfs`` to -+control its functionality at the system level. They located in the -+``/sys/devices/system/cpu/cpufreq/policyX/`` directory and affect all CPUs. :: -+ -+ root@hr-test1:/home/ray# ls /sys/devices/system/cpu/cpufreq/policy0/*amd* -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_highest_perf -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_freq -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_nonlinear_perf -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_lowest_perf -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_max_freq -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_min_freq -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_nominal_freq -+ /sys/devices/system/cpu/cpufreq/policy0/amd_pstate_nominal_perf -+ /sys/devices/system/cpu/cpufreq/policy0/is_amd_pstate_enabled -+ -+ -+``is_amd_pstate_enabled`` -+ -+Query whether current kernel loads ``amd-pstate`` to enable the AMD -+P-States functionality. -+This attribute is read-only. -+ -+``amd_pstate_highest_perf / amd_pstate_max_freq`` -+ -+Maximum CPPC performance and CPU frequency that the driver is allowed to -+set in percent of the maximum supported CPPC performance level (the highest -+performance supported in `AMD CPPC Performance Capability <perf_cap_>`_). -+This attribute is read-only. -+ -+``amd_pstate_nominal_perf / amd_pstate_nominal_freq`` -+ -+Nominal CPPC performance and CPU frequency that the driver is allowed to -+set in percent of the maximum supported CPPC performance level (Please see -+nominal performance in `AMD CPPC Performance Capability <perf_cap_>`_). -+This attribute is read-only. -+ -+``amd_pstate_lowest_nonlinear_perf / amd_pstate_lowest_nonlinear_freq`` -+ -+The lowest non-linear CPPC performance and CPU frequency that the driver is -+allowed to set in percent of the maximum supported CPPC performance level -+(Please see the lowest non-linear performance in `AMD CPPC Performance -+Capability <perf_cap_>`_). -+This attribute is read-only. -+ -+``amd_pstate_lowest_perf / amd_pstate_min_freq`` -+ -+The lowest physical CPPC performance and CPU frequency. -+This attribute is read-only. -+ -+ -+``amd-pstate`` vs ``acpi-cpufreq`` -+====================================== -+ -+On majority of AMD platforms supported by ``acpi-cpufreq``, the ACPI tables -+provided by the platform firmware used for CPU performance scaling, but -+only provides 3 P-states on AMD processors. -+However, on modern AMD APU and CPU series, it provides the collaborative -+processor performance control according to ACPI protocol and customize this -+for AMD platforms. That is fine-grain and continuous frequency range -+instead of the legacy hardware P-states. ``amd-pstate`` is the kernel -+module which supports the new AMD P-States mechanism on most of future AMD -+platforms. The AMD P-States mechanism will be the more performance and energy -+efficiency frequency management method on AMD processors. -+ -+``cpupower`` tool support for ``amd-pstate`` -+=============================================== -+ -+``amd-pstate`` is supported on ``cpupower`` tool that can be used to dump the frequency -+information. And it is in progress to support more and more operations for new -+``amd-pstate`` module with this tool. :: -+ -+ root@hr-test1:/home/ray# cpupower frequency-info -+ analyzing CPU 0: -+ driver: amd-pstate -+ CPUs which run at the same hardware frequency: 0 -+ CPUs which need to have their frequency coordinated by software: 0 -+ maximum transition latency: 131 us -+ hardware limits: 400 MHz - 4.68 GHz -+ available cpufreq governors: ondemand conservative powersave userspace performance schedutil -+ current policy: frequency should be within 400 MHz and 4.68 GHz. -+ The governor "schedutil" may decide which speed to use -+ within this range. -+ current CPU frequency: Unable to call hardware -+ current CPU frequency: 4.02 GHz (asserted by call to kernel) -+ boost state support: -+ Supported: yes -+ Active: yes -+ AMD PSTATE Highest Performance: 166. Maximum Frequency: 4.68 GHz. -+ AMD PSTATE Nominal Performance: 117. Nominal Frequency: 3.30 GHz. -+ AMD PSTATE Lowest Non-linear Performance: 39. Lowest Non-linear Frequency: 1.10 GHz. -+ AMD PSTATE Lowest Performance: 15. Lowest Frequency: 400 MHz. -+ -+ -+Diagnostics and Tuning -+======================= -+ -+Trace Events -+-------------- -+ -+There are two static trace events that can be used for ``amd-pstate`` -+diagnostics. One of them is the cpu_frequency trace event generally used -+by ``CPUFreq``, and the other one is the ``amd_pstate_perf`` trace event -+specific to ``amd-pstate``. The following sequence of shell commands can -+be used to enable them and see their output (if the kernel is generally -+configured to support event tracing). :: -+ -+ root@hr-test1:/home/ray# cd /sys/kernel/tracing/ -+ root@hr-test1:/sys/kernel/tracing# echo 1 > events/amd_cpu/enable -+ root@hr-test1:/sys/kernel/tracing# cat trace -+ # tracer: nop -+ # -+ # entries-in-buffer/entries-written: 47827/42233061 #P:2 -+ # -+ # _-----=> irqs-off -+ # / _----=> need-resched -+ # | / _---=> hardirq/softirq -+ # || / _--=> preempt-depth -+ # ||| / delay -+ # TASK-PID CPU# |||| TIMESTAMP FUNCTION -+ # | | | |||| | | -+ <idle>-0 [000] d.s. 244057.464842: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6 -+ <idle>-0 [000] d.h. 244057.475436: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6 -+ <idle>-0 [000] d.h. 244057.476629: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6 -+ <idle>-0 [000] d.s. 244057.484847: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6 -+ <idle>-0 [000] d.h. 244057.499821: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6 -+ avahi-daemon-528 [000] d... 244057.513568: amd_pstate_perf: amd_min_perf=39 amd_des_perf=39 amd_max_perf=166 cpu_id=0 prev=0x2727a6 value=0x2727a6 -+ -+The cpu_frequency trace event will be triggered either by the ``schedutil`` scaling -+governor (for the policies it is attached to), or by the ``CPUFreq`` core (for the -+policies with other scaling governors). -+ -+ -+Reference -+=========== -+ -+.. [1] AMD64 Architecture Programmer's Manual Volume 2: System Programming, -+ https://www.amd.com/system/files/TechDocs/24593.pdf -+ -+.. [2] Advanced Configuration and Power Interface Specification, -+ https://uefi.org/sites/default/files/resources/ACPI_Spec_6_4_Jan22.pdf -+ -+.. [3] Processor Programming Reference (PPR) for AMD Family 19h Model 21h, Revision B0 Processors -+ https://www.amd.com/system/files/TechDocs/55898_B1_pub_0.50.zip -+ -diff --git a/Documentation/admin-guide/pm/working-state.rst b/Documentation/admin-guide/pm/working-state.rst -index f40994c422dc..28db6156b55d 100644 ---- a/Documentation/admin-guide/pm/working-state.rst -+++ b/Documentation/admin-guide/pm/working-state.rst -@@ -11,6 +11,7 @@ Working-State Power Management - intel_idle - cpufreq - intel_pstate -+ amd_pstate - cpufreq_drivers - intel_epb - intel-speed-select -diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h -index d0ce5cfd3ac1..f23dc1abd485 100644 ---- a/arch/x86/include/asm/cpufeatures.h -+++ b/arch/x86/include/asm/cpufeatures.h -@@ -313,6 +313,7 @@ - #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ - #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ - #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ -+#define X86_FEATURE_AMD_CPPC (13*32+27) /* Collaborative Processor Performance Control */ - - /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ - #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ -diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h -index a7c413432b33..ce42e15cf303 100644 ---- a/arch/x86/include/asm/msr-index.h -+++ b/arch/x86/include/asm/msr-index.h -@@ -486,6 +486,23 @@ - - #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f - -+/* AMD Collaborative Processor Performance Control MSRs */ -+#define MSR_AMD_CPPC_CAP1 0xc00102b0 -+#define MSR_AMD_CPPC_ENABLE 0xc00102b1 -+#define MSR_AMD_CPPC_CAP2 0xc00102b2 -+#define MSR_AMD_CPPC_REQ 0xc00102b3 -+#define MSR_AMD_CPPC_STATUS 0xc00102b4 -+ -+#define CAP1_LOWEST_PERF(x) (((x) >> 0) & 0xff) -+#define CAP1_LOWNONLIN_PERF(x) (((x) >> 8) & 0xff) -+#define CAP1_NOMINAL_PERF(x) (((x) >> 16) & 0xff) -+#define CAP1_HIGHEST_PERF(x) (((x) >> 24) & 0xff) -+ -+#define REQ_MAX_PERF(x) (((x) & 0xff) << 0) -+#define REQ_MIN_PERF(x) (((x) & 0xff) << 8) -+#define REQ_DES_PERF(x) (((x) & 0xff) << 16) -+#define REQ_ENERGY_PERF_PREF(x) (((x) & 0xff) << 24) -+ - /* Fam 17h MSRs */ - #define MSR_F17H_IRPERF 0xc00000e9 - -diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c -index a4d4eebba1da..b285960c35e7 100644 ---- a/drivers/acpi/cppc_acpi.c -+++ b/drivers/acpi/cppc_acpi.c -@@ -411,7 +411,7 @@ bool acpi_cpc_valid(void) - struct cpc_desc *cpc_ptr; - int cpu; - -- for_each_possible_cpu(cpu) { -+ for_each_online_cpu(cpu) { - cpc_ptr = per_cpu(cpc_desc_ptr, cpu); - if (!cpc_ptr) - return false; -@@ -1220,6 +1220,54 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) - } - EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); - -+/** -+ * cppc_set_enable - Set to enable CPPC on the processor by writing the -+ * Continuous Performance Control package EnableRegister feild. -+ * @cpu: CPU for which to enable CPPC register. -+ * @enable: 0 - disable, 1 - enable CPPC feature on the processor. -+ * -+ * Return: 0 for success, -ERRNO or -EIO otherwise. -+ */ -+int cppc_set_enable(int cpu, u32 enable) -+{ -+ int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); -+ struct cpc_register_resource *enable_reg; -+ struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); -+ struct cppc_pcc_data *pcc_ss_data = NULL; -+ int ret = -1; -+ -+ /* check the input value*/ -+ if (cpu < 0 || cpu > num_possible_cpus() - 1 || enable > 1) -+ return -ENODEV; -+ -+ if (!cpc_desc) { -+ pr_debug("No CPC descriptor for CPU:%d\n", cpu); -+ return -ENODEV; -+ } -+ -+ enable_reg = &cpc_desc->cpc_regs[ENABLE]; -+ -+ if (CPC_IN_PCC(enable_reg)) { -+ -+ if (pcc_ss_id < 0) -+ return -EIO; -+ -+ ret = cpc_write(cpu, enable_reg, enable); -+ if (ret) -+ return ret; -+ -+ pcc_ss_data = pcc_data[pcc_ss_id]; -+ -+ down_write(&pcc_ss_data->pcc_lock); -+ /* after writing CPC, transfer the ownership of PCC to platfrom */ -+ ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE); -+ up_write(&pcc_ss_data->pcc_lock); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(cppc_set_enable); -+ - /** - * cppc_set_perf - Set a CPU's performance controls. - * @cpu: CPU for which to set performance controls. -diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 -index 92701a18bdd9..9cd7e338bdcd 100644 ---- a/drivers/cpufreq/Kconfig.x86 -+++ b/drivers/cpufreq/Kconfig.x86 -@@ -34,6 +34,19 @@ config X86_PCC_CPUFREQ - - If in doubt, say N. - -+config X86_AMD_PSTATE -+ tristate "AMD Processor P-State driver" -+ depends on X86 -+ select ACPI_PROCESSOR if ACPI -+ select ACPI_CPPC_LIB if X86_64 && ACPI && SCHED_MC_PRIO -+ select CPU_FREQ_GOV_SCHEDUTIL if SMP -+ help -+ This driver adds a CPUFreq driver which utilizes a fine grain -+ processor performance freqency control range instead of legacy -+ performance levels. This driver also supports newer AMD CPUs. -+ -+ If in doubt, say N. -+ - config X86_ACPI_CPUFREQ - tristate "ACPI Processor P-States driver" - depends on ACPI_PROCESSOR -diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index 27d3bd7ea9d4..04882bc4b145 100644 ---- a/drivers/cpufreq/Makefile -+++ b/drivers/cpufreq/Makefile -@@ -17,6 +17,10 @@ obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o - obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o - obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o - -+# Traces -+CFLAGS_amd-pstate-trace.o := -I$(src) -+amd_pstate-y := amd-pstate.o amd-pstate-trace.o -+ - ################################################################################## - # x86 drivers. - # Link order matters. K8 is preferred to ACPI because of firmware bugs in early -@@ -25,6 +29,7 @@ obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o - # speedstep-* is preferred over p4-clockmod. - - obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o -+obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o - obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o - obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o - obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o -diff --git a/drivers/cpufreq/amd-pstate-trace.c b/drivers/cpufreq/amd-pstate-trace.c -new file mode 100644 -index 000000000000..891b696dcd69 ---- /dev/null -+++ b/drivers/cpufreq/amd-pstate-trace.c -@@ -0,0 +1,2 @@ -+#define CREATE_TRACE_POINTS -+#include "amd-pstate-trace.h" -diff --git a/drivers/cpufreq/amd-pstate-trace.h b/drivers/cpufreq/amd-pstate-trace.h -new file mode 100644 -index 000000000000..50c85e150f30 ---- /dev/null -+++ b/drivers/cpufreq/amd-pstate-trace.h -@@ -0,0 +1,96 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * amd-pstate-trace.h - AMD Processor P-state Frequency Driver Tracer -+ * -+ * Copyright (C) 2021 Advanced Micro Devices, Inc. All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ * -+ * Author: Huang Rui <ray.huang@amd.com> -+ */ -+ -+#if !defined(_AMD_PSTATE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _AMD_PSTATE_TRACE_H -+ -+#include <linux/cpufreq.h> -+#include <linux/tracepoint.h> -+#include <linux/trace_events.h> -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM amd_cpu -+ -+#undef TRACE_INCLUDE_FILE -+#define TRACE_INCLUDE_FILE amd-pstate-trace -+ -+#define TPS(x) tracepoint_string(x) -+ -+TRACE_EVENT(amd_pstate_perf, -+ -+ TP_PROTO(unsigned long min_perf, -+ unsigned long target_perf, -+ unsigned long capacity, -+ unsigned int cpu_id, -+ u64 prev, -+ u64 value, -+ int type -+ ), -+ -+ TP_ARGS(min_perf, -+ target_perf, -+ capacity, -+ cpu_id, -+ prev, -+ value, -+ type -+ ), -+ -+ TP_STRUCT__entry( -+ __field(unsigned long, min_perf) -+ __field(unsigned long, target_perf) -+ __field(unsigned long, capacity) -+ __field(unsigned int, cpu_id) -+ __field(u64, prev) -+ __field(u64, value) -+ __field(int, type) -+ ), -+ -+ TP_fast_assign( -+ __entry->min_perf = min_perf; -+ __entry->target_perf = target_perf; -+ __entry->capacity = capacity; -+ __entry->cpu_id = cpu_id; -+ __entry->prev = prev; -+ __entry->value = value; -+ __entry->type = type; -+ ), -+ -+ TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu cpu_id=%u prev=0x%llx value=0x%llx type=0x%d", -+ (unsigned long)__entry->min_perf, -+ (unsigned long)__entry->target_perf, -+ (unsigned long)__entry->capacity, -+ (unsigned int)__entry->cpu_id, -+ (u64)__entry->prev, -+ (u64)__entry->value, -+ (int)__entry->type -+ ) -+); -+ -+#endif /* _AMD_PSTATE_TRACE_H */ -+ -+/* This part must be outside protection */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+ -+#include <trace/define_trace.h> -diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c -new file mode 100644 -index 000000000000..b0353d13f74a ---- /dev/null -+++ b/drivers/cpufreq/amd-pstate.c -@@ -0,0 +1,724 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * amd-pstate.c - AMD Processor P-state Frequency Driver -+ * -+ * Copyright (C) 2021 Advanced Micro Devices, Inc. All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ * -+ * Author: Huang Rui <ray.huang@amd.com> -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/smp.h> -+#include <linux/sched.h> -+#include <linux/cpufreq.h> -+#include <linux/compiler.h> -+#include <linux/dmi.h> -+#include <linux/slab.h> -+#include <linux/acpi.h> -+#include <linux/io.h> -+#include <linux/delay.h> -+#include <linux/uaccess.h> -+#include <linux/static_call.h> -+ -+#include <acpi/processor.h> -+#include <acpi/cppc_acpi.h> -+ -+#include <asm/msr.h> -+#include <asm/processor.h> -+#include <asm/cpufeature.h> -+#include <asm/cpu_device_id.h> -+#include "amd-pstate-trace.h" -+ -+#define AMD_PSTATE_TRANSITION_LATENCY 0x20000 -+#define AMD_PSTATE_TRANSITION_DELAY 500 -+ -+enum switch_type -+{ -+ AMD_TARGET = 0, -+ AMD_ADJUST_PERF -+}; -+ -+static struct cpufreq_driver amd_pstate_driver; -+ -+struct amd_cpudata { -+ int cpu; -+ -+ struct freq_qos_request req[2]; -+ struct cpufreq_policy *policy; -+ -+ u64 cppc_req_cached; -+ -+ u32 highest_perf; -+ u32 nominal_perf; -+ u32 lowest_nonlinear_perf; -+ u32 lowest_perf; -+ -+ u32 max_freq; -+ u32 min_freq; -+ u32 nominal_freq; -+ u32 lowest_nonlinear_freq; -+ -+ bool boost_supported; -+}; -+ -+static inline int pstate_enable(bool enable) -+{ -+ return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable ? 1 : 0); -+} -+ -+static int cppc_enable(bool enable) -+{ -+ int cpu, ret = 0; -+ -+ for_each_online_cpu(cpu) { -+ ret = cppc_set_enable(cpu, enable ? 1 : 0); -+ if (ret) -+ return ret; -+ } -+ -+ return ret; -+} -+ -+DEFINE_STATIC_CALL(amd_pstate_enable, pstate_enable); -+ -+static inline int amd_pstate_enable(bool enable) -+{ -+ return static_call(amd_pstate_enable)(enable); -+} -+ -+static int pstate_init_perf(struct amd_cpudata *cpudata) -+{ -+ u64 cap1; -+ -+ int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1, -+ &cap1); -+ if (ret) -+ return ret; -+ -+ /* -+ * TODO: Introduce AMD specific power feature. -+ * -+ * CPPC entry doesn't indicate the highest performance in some ASICs. -+ */ -+ WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); -+ -+ WRITE_ONCE(cpudata->nominal_perf, CAP1_NOMINAL_PERF(cap1)); -+ WRITE_ONCE(cpudata->lowest_nonlinear_perf, CAP1_LOWNONLIN_PERF(cap1)); -+ WRITE_ONCE(cpudata->lowest_perf, CAP1_LOWEST_PERF(cap1)); -+ -+ return 0; -+} -+ -+static int cppc_init_perf(struct amd_cpudata *cpudata) -+{ -+ struct cppc_perf_caps cppc_perf; -+ -+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); -+ if (ret) -+ return ret; -+ -+ WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf()); -+ -+ WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); -+ WRITE_ONCE(cpudata->lowest_nonlinear_perf, -+ cppc_perf.lowest_nonlinear_perf); -+ WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf); -+ -+ return 0; -+} -+ -+DEFINE_STATIC_CALL(amd_pstate_init_perf, pstate_init_perf); -+ -+static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata) -+{ -+ return static_call(amd_pstate_init_perf)(cpudata); -+} -+ -+static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, -+ u32 des_perf, u32 max_perf, -+ bool fast_switch) -+{ -+ if (fast_switch) -+ wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached)); -+ else -+ wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, -+ READ_ONCE(cpudata->cppc_req_cached)); -+} -+ -+static void cppc_update_perf(struct amd_cpudata *cpudata, -+ u32 min_perf, u32 des_perf, -+ u32 max_perf, bool fast_switch) -+{ -+ struct cppc_perf_ctrls perf_ctrls; -+ -+ perf_ctrls.max_perf = max_perf; -+ perf_ctrls.min_perf = min_perf; -+ perf_ctrls.desired_perf = des_perf; -+ -+ cppc_set_perf(cpudata->cpu, &perf_ctrls); -+} -+ -+DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf); -+ -+static inline void -+amd_pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf, -+ u32 des_perf, u32 max_perf, bool fast_switch) -+{ -+ static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf, -+ max_perf, fast_switch); -+} -+ -+static void -+amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf, -+ u32 des_perf, u32 max_perf, bool fast_switch) -+{ -+ u64 prev = READ_ONCE(cpudata->cppc_req_cached); -+ u64 value = prev; -+ enum switch_type type = fast_switch ? AMD_ADJUST_PERF : AMD_TARGET; -+ -+ value &= ~REQ_MIN_PERF(~0L); -+ value |= REQ_MIN_PERF(min_perf); -+ -+ value &= ~REQ_DES_PERF(~0L); -+ value |= REQ_DES_PERF(des_perf); -+ -+ value &= ~REQ_MAX_PERF(~0L); -+ value |= REQ_MAX_PERF(max_perf); -+ -+ trace_amd_pstate_perf(min_perf, des_perf, max_perf, -+ cpudata->cpu, prev, value, type); -+ -+ if (value == prev) -+ return; -+ -+ WRITE_ONCE(cpudata->cppc_req_cached, value); -+ -+ amd_pstate_update_perf(cpudata, min_perf, des_perf, -+ max_perf, fast_switch); -+} -+ -+static int amd_pstate_verify(struct cpufreq_policy_data *policy) -+{ -+ cpufreq_verify_within_cpu_limits(policy); -+ -+ return 0; -+} -+ -+static int amd_pstate_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, -+ unsigned int relation) -+{ -+ struct cpufreq_freqs freqs; -+ struct amd_cpudata *cpudata = policy->driver_data; -+ unsigned long amd_max_perf, amd_min_perf, amd_des_perf, -+ amd_cap_perf; -+ -+ if (!cpudata->max_freq) -+ return -ENODEV; -+ -+ amd_cap_perf = READ_ONCE(cpudata->highest_perf); -+ amd_min_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); -+ amd_max_perf = amd_cap_perf; -+ -+ freqs.old = policy->cur; -+ freqs.new = target_freq; -+ -+ amd_des_perf = DIV_ROUND_CLOSEST(target_freq * amd_cap_perf, -+ cpudata->max_freq); -+ -+ cpufreq_freq_transition_begin(policy, &freqs); -+ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf, -+ amd_max_perf, false); -+ cpufreq_freq_transition_end(policy, &freqs, false); -+ -+ return 0; -+} -+ -+static void amd_pstate_adjust_perf(unsigned int cpu, -+ unsigned long min_perf, -+ unsigned long target_perf, -+ unsigned long capacity) -+{ -+ unsigned long amd_max_perf, amd_min_perf, amd_des_perf, -+ amd_cap_perf, lowest_nonlinear_perf; -+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); -+ struct amd_cpudata *cpudata = policy->driver_data; -+ -+ amd_cap_perf = READ_ONCE(cpudata->highest_perf); -+ lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); -+ -+ if (target_perf < capacity) -+ amd_des_perf = DIV_ROUND_UP(amd_cap_perf * target_perf, -+ capacity); -+ -+ amd_min_perf = READ_ONCE(cpudata->highest_perf); -+ if (min_perf < capacity) -+ amd_min_perf = DIV_ROUND_UP(amd_cap_perf * min_perf, capacity); -+ -+ if (amd_min_perf < lowest_nonlinear_perf) -+ amd_min_perf = lowest_nonlinear_perf; -+ -+ amd_max_perf = amd_cap_perf; -+ if (amd_max_perf < amd_min_perf) -+ amd_max_perf = amd_min_perf; -+ -+ amd_des_perf = clamp_t(unsigned long, amd_des_perf, -+ amd_min_perf, amd_max_perf); -+ -+ amd_pstate_update(cpudata, amd_min_perf, amd_des_perf, -+ amd_max_perf, true); -+} -+ -+static int amd_get_min_freq(struct amd_cpudata *cpudata) -+{ -+ struct cppc_perf_caps cppc_perf; -+ -+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); -+ if (ret) -+ return ret; -+ -+ /* Switch to khz */ -+ return cppc_perf.lowest_freq * 1000; -+} -+ -+static int amd_get_max_freq(struct amd_cpudata *cpudata) -+{ -+ struct cppc_perf_caps cppc_perf; -+ u32 max_perf, max_freq, nominal_freq, nominal_perf; -+ u64 boost_ratio; -+ -+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); -+ if (ret) -+ return ret; -+ -+ nominal_freq = cppc_perf.nominal_freq; -+ nominal_perf = READ_ONCE(cpudata->nominal_perf); -+ max_perf = READ_ONCE(cpudata->highest_perf); -+ -+ boost_ratio = div_u64(max_perf << SCHED_CAPACITY_SHIFT, -+ nominal_perf); -+ -+ max_freq = nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT; -+ -+ /* Switch to khz */ -+ return max_freq * 1000; -+} -+ -+static int amd_get_nominal_freq(struct amd_cpudata *cpudata) -+{ -+ struct cppc_perf_caps cppc_perf; -+ u32 nominal_freq; -+ -+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); -+ if (ret) -+ return ret; -+ -+ nominal_freq = cppc_perf.nominal_freq; -+ -+ /* Switch to khz */ -+ return nominal_freq * 1000; -+} -+ -+static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata) -+{ -+ struct cppc_perf_caps cppc_perf; -+ u32 lowest_nonlinear_freq, lowest_nonlinear_perf, -+ nominal_freq, nominal_perf; -+ u64 lowest_nonlinear_ratio; -+ -+ int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); -+ if (ret) -+ return ret; -+ -+ nominal_freq = cppc_perf.nominal_freq; -+ nominal_perf = READ_ONCE(cpudata->nominal_perf); -+ -+ lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf; -+ -+ lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << -+ SCHED_CAPACITY_SHIFT, nominal_perf); -+ -+ lowest_nonlinear_freq = nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT; -+ -+ /* Switch to khz */ -+ return lowest_nonlinear_freq * 1000; -+} -+ -+static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state) -+{ -+ struct amd_cpudata *cpudata = policy->driver_data; -+ int ret; -+ -+ if (!cpudata->boost_supported) { -+ pr_err("Boost mode is not supported by this processor or SBIOS\n"); -+ return -EINVAL; -+ } -+ -+ if (state) -+ policy->cpuinfo.max_freq = cpudata->max_freq; -+ else -+ policy->cpuinfo.max_freq = cpudata->nominal_freq; -+ -+ policy->max = policy->cpuinfo.max_freq; -+ -+ ret = freq_qos_update_request(&cpudata->req[1], -+ policy->cpuinfo.max_freq); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static void amd_pstate_boost_init(struct amd_cpudata *cpudata) -+{ -+ u32 highest_perf, nominal_perf; -+ -+ highest_perf = READ_ONCE(cpudata->highest_perf); -+ nominal_perf = READ_ONCE(cpudata->nominal_perf); -+ -+ if (highest_perf <= nominal_perf) -+ return; -+ -+ cpudata->boost_supported = true; -+ amd_pstate_driver.boost_enabled = true; -+} -+ -+static int amd_pstate_init_freqs_in_cpudata(struct amd_cpudata *cpudata, -+ u32 max_freq, u32 min_freq, -+ u32 nominal_freq, -+ u32 lowest_nonlinear_freq) -+{ -+ if (!cpudata) -+ return -EINVAL; -+ -+ /* Initial processor data capability frequencies */ -+ cpudata->max_freq = max_freq; -+ cpudata->min_freq = min_freq; -+ cpudata->nominal_freq = nominal_freq; -+ cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq; -+ -+ return 0; -+} -+ -+static int amd_pstate_cpu_init(struct cpufreq_policy *policy) -+{ -+ int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; -+ unsigned int cpu = policy->cpu; -+ struct device *dev; -+ struct amd_cpudata *cpudata; -+ -+ dev = get_cpu_device(policy->cpu); -+ if (!dev) -+ return -ENODEV; -+ -+ cpudata = kzalloc(sizeof(*cpudata), GFP_KERNEL); -+ if (!cpudata) -+ return -ENOMEM; -+ -+ cpudata->cpu = cpu; -+ cpudata->policy = policy; -+ -+ ret = amd_pstate_init_perf(cpudata); -+ if (ret) -+ goto free_cpudata1; -+ -+ min_freq = amd_get_min_freq(cpudata); -+ max_freq = amd_get_max_freq(cpudata); -+ nominal_freq = amd_get_nominal_freq(cpudata); -+ lowest_nonlinear_freq = amd_get_lowest_nonlinear_freq(cpudata); -+ -+ if (min_freq < 0 || max_freq < 0 || min_freq > max_freq) { -+ dev_err(dev, "min_freq(%d) or max_freq(%d) value is incorrect\n", -+ min_freq, max_freq); -+ ret = -EINVAL; -+ goto free_cpudata1; -+ } -+ -+ policy->cpuinfo.transition_latency = AMD_PSTATE_TRANSITION_LATENCY; -+ policy->transition_delay_us = AMD_PSTATE_TRANSITION_DELAY; -+ -+ policy->min = min_freq; -+ policy->max = max_freq; -+ -+ policy->cpuinfo.min_freq = min_freq; -+ policy->cpuinfo.max_freq = max_freq; -+ -+ /* It will be updated by governor */ -+ policy->cur = policy->cpuinfo.min_freq; -+ -+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC)) -+ policy->fast_switch_possible = true; -+ -+ ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0], -+ FREQ_QOS_MIN, policy->cpuinfo.min_freq); -+ if (ret < 0) { -+ dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret); -+ goto free_cpudata1; -+ } -+ -+ ret = freq_qos_add_request(&policy->constraints, &cpudata->req[1], -+ FREQ_QOS_MAX, policy->cpuinfo.max_freq); -+ if (ret < 0) { -+ dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret); -+ goto free_cpudata2; -+ } -+ -+ ret = amd_pstate_init_freqs_in_cpudata(cpudata, max_freq, min_freq, -+ nominal_freq, -+ lowest_nonlinear_freq); -+ if (ret) { -+ dev_err(dev, "Failed to init cpudata (%d)\n", ret); -+ goto free_cpudata3; -+ } -+ -+ policy->driver_data = cpudata; -+ -+ amd_pstate_boost_init(cpudata); -+ -+ return 0; -+ -+free_cpudata3: -+ freq_qos_remove_request(&cpudata->req[1]); -+free_cpudata2: -+ freq_qos_remove_request(&cpudata->req[0]); -+free_cpudata1: -+ kfree(cpudata); -+ return ret; -+} -+ -+static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) -+{ -+ struct amd_cpudata *cpudata; -+ -+ cpudata = policy->driver_data; -+ -+ freq_qos_remove_request(&cpudata->req[1]); -+ freq_qos_remove_request(&cpudata->req[0]); -+ kfree(cpudata); -+ -+ return 0; -+} -+ -+/* Sysfs attributes */ -+ -+static ssize_t show_amd_pstate_max_freq(struct cpufreq_policy *policy, -+ char *buf) -+{ -+ int max_freq; -+ struct amd_cpudata *cpudata; -+ -+ cpudata = policy->driver_data; -+ -+ max_freq = amd_get_max_freq(cpudata); -+ if (max_freq < 0) -+ return max_freq; -+ -+ return sprintf(&buf[0], "%u\n", max_freq); -+} -+ -+static ssize_t show_amd_pstate_nominal_freq(struct cpufreq_policy *policy, -+ char *buf) -+{ -+ int nominal_freq; -+ struct amd_cpudata *cpudata; -+ -+ cpudata = policy->driver_data; -+ -+ nominal_freq = amd_get_nominal_freq(cpudata); -+ if (nominal_freq < 0) -+ return nominal_freq; -+ -+ return sprintf(&buf[0], "%u\n", nominal_freq); -+} -+ -+static ssize_t -+show_amd_pstate_lowest_nonlinear_freq(struct cpufreq_policy *policy, char *buf) -+{ -+ int freq; -+ struct amd_cpudata *cpudata; -+ -+ cpudata = policy->driver_data; -+ -+ freq = amd_get_lowest_nonlinear_freq(cpudata); -+ if (freq < 0) -+ return freq; -+ -+ return sprintf(&buf[0], "%u\n", freq); -+} -+ -+static ssize_t show_amd_pstate_min_freq(struct cpufreq_policy *policy, char *buf) -+{ -+ int min_freq; -+ struct amd_cpudata *cpudata; -+ -+ cpudata = policy->driver_data; -+ -+ min_freq = amd_get_min_freq(cpudata); -+ if (min_freq < 0) -+ return min_freq; -+ -+ return sprintf(&buf[0], "%u\n", min_freq); -+} -+ -+static ssize_t -+show_amd_pstate_highest_perf(struct cpufreq_policy *policy, char *buf) -+{ -+ u32 perf; -+ struct amd_cpudata *cpudata = policy->driver_data; -+ -+ perf = READ_ONCE(cpudata->highest_perf); -+ -+ return sprintf(&buf[0], "%u\n", perf); -+} -+ -+static ssize_t -+show_amd_pstate_nominal_perf(struct cpufreq_policy *policy, char *buf) -+{ -+ u32 perf; -+ struct amd_cpudata *cpudata = policy->driver_data; -+ -+ perf = READ_ONCE(cpudata->nominal_perf); -+ -+ return sprintf(&buf[0], "%u\n", perf); -+} -+ -+static ssize_t -+show_amd_pstate_lowest_nonlinear_perf(struct cpufreq_policy *policy, char *buf) -+{ -+ u32 perf; -+ struct amd_cpudata *cpudata = policy->driver_data; -+ -+ perf = READ_ONCE(cpudata->lowest_nonlinear_perf); -+ -+ return sprintf(&buf[0], "%u\n", perf); -+} -+ -+static ssize_t -+show_amd_pstate_lowest_perf(struct cpufreq_policy *policy, char *buf) -+{ -+ u32 perf; -+ struct amd_cpudata *cpudata = policy->driver_data; -+ -+ perf = READ_ONCE(cpudata->lowest_perf); -+ -+ return sprintf(&buf[0], "%u\n", perf); -+} -+ -+static ssize_t show_is_amd_pstate_enabled(struct cpufreq_policy *policy, -+ char *buf) -+{ -+ return sprintf(&buf[0], "%d\n", acpi_cpc_valid() ? 1 : 0); -+} -+ -+cpufreq_freq_attr_ro(is_amd_pstate_enabled); -+ -+cpufreq_freq_attr_ro(amd_pstate_max_freq); -+cpufreq_freq_attr_ro(amd_pstate_nominal_freq); -+cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); -+cpufreq_freq_attr_ro(amd_pstate_min_freq); -+ -+cpufreq_freq_attr_ro(amd_pstate_highest_perf); -+cpufreq_freq_attr_ro(amd_pstate_nominal_perf); -+cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_perf); -+cpufreq_freq_attr_ro(amd_pstate_lowest_perf); -+ -+static struct freq_attr *amd_pstate_attr[] = { -+ &is_amd_pstate_enabled, -+ &amd_pstate_max_freq, -+ &amd_pstate_nominal_freq, -+ &amd_pstate_lowest_nonlinear_freq, -+ &amd_pstate_min_freq, -+ &amd_pstate_highest_perf, -+ &amd_pstate_nominal_perf, -+ &amd_pstate_lowest_nonlinear_perf, -+ &amd_pstate_lowest_perf, -+ NULL, -+}; -+ -+static struct cpufreq_driver amd_pstate_driver = { -+ .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, -+ .verify = amd_pstate_verify, -+ .target = amd_pstate_target, -+ .init = amd_pstate_cpu_init, -+ .exit = amd_pstate_cpu_exit, -+ .set_boost = amd_pstate_set_boost, -+ .name = "amd-pstate", -+ .attr = amd_pstate_attr, -+}; -+ -+static int __init amd_pstate_init(void) -+{ -+ int ret; -+ -+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) -+ return -ENODEV; -+ -+ if (!acpi_cpc_valid()) { -+ pr_debug("%s, the _CPC object is not present in SBIOS\n", -+ __func__); -+ return -ENODEV; -+ } -+ -+ /* don't keep reloading if cpufreq_driver exists */ -+ if (cpufreq_get_current_driver()) -+ return -EEXIST; -+ -+ /* capability check */ -+ if (boot_cpu_has(X86_FEATURE_AMD_CPPC)) { -+ pr_debug("%s, AMD CPPC MSR based functionality is supported\n", -+ __func__); -+ amd_pstate_driver.adjust_perf = amd_pstate_adjust_perf; -+ } else { -+ 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); -+ } -+ -+ /* enable amd pstate feature */ -+ ret = amd_pstate_enable(true); -+ if (ret) { -+ pr_err("%s, failed to enable amd-pstate with return %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ ret = cpufreq_register_driver(&amd_pstate_driver); -+ if (ret) { -+ pr_err("%s, return %d\n", __func__, ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void __exit amd_pstate_exit(void) -+{ -+ cpufreq_unregister_driver(&amd_pstate_driver); -+ -+ amd_pstate_enable(false); -+} -+ -+module_init(amd_pstate_init); -+module_exit(amd_pstate_exit); -+ -+MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>"); -+MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver"); -+MODULE_LICENSE("GPL"); -diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h -index 9f4985b4d64d..3fdae40a75fc 100644 ---- a/include/acpi/cppc_acpi.h -+++ b/include/acpi/cppc_acpi.h -@@ -137,6 +137,7 @@ struct cppc_cpudata { - extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf); - extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); - extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); -+extern int cppc_set_enable(int cpu, u32 enable); - extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); - extern bool acpi_cpc_valid(void); - extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); -@@ -157,6 +158,10 @@ static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) - { - return -ENOTSUPP; - } -+static inline int cppc_set_enable(int cpu, u32 enable) -+{ -+ return -ENOTSUPP; -+} - static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps) - { - return -ENOTSUPP; -diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c -index c3b56db8b921..02719cc400a1 100644 ---- a/tools/power/cpupower/lib/cpufreq.c -+++ b/tools/power/cpupower/lib/cpufreq.c -@@ -83,20 +83,21 @@ static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = { - [STATS_NUM_TRANSITIONS] = "stats/total_trans" - }; - -- --static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, -- enum cpufreq_value which) -+unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, -+ const char **table, -+ unsigned index, -+ unsigned size) - { - unsigned long value; - unsigned int len; - char linebuf[MAX_LINE_LEN]; - char *endp; - -- if (which >= MAX_CPUFREQ_VALUE_READ_FILES) -+ if (!table && !table[index] && index >= size) - return 0; - -- len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which], -- linebuf, sizeof(linebuf)); -+ len = sysfs_cpufreq_read_file(cpu, table[index], linebuf, -+ sizeof(linebuf)); - - if (len == 0) - return 0; -@@ -109,6 +110,14 @@ static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, - return value; - } - -+static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, -+ enum cpufreq_value which) -+{ -+ return cpufreq_get_sysfs_value_from_table(cpu, cpufreq_value_files, -+ which, -+ MAX_CPUFREQ_VALUE_READ_FILES); -+} -+ - /* read access to files which contain one string */ - - enum cpufreq_string { -diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h -index 95f4fd9e2656..107668c0c454 100644 ---- a/tools/power/cpupower/lib/cpufreq.h -+++ b/tools/power/cpupower/lib/cpufreq.h -@@ -203,6 +203,18 @@ int cpufreq_modify_policy_governor(unsigned int cpu, char *governor); - int cpufreq_set_frequency(unsigned int cpu, - unsigned long target_frequency); - -+/* -+ * get the sysfs value from specific table -+ * -+ * Read the value with the sysfs file name from specific table. Does -+ * only work if the cpufreq driver has the specific sysfs interfaces. -+ */ -+ -+unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, -+ const char **table, -+ unsigned index, -+ unsigned size); -+ - #ifdef __cplusplus - } - #endif -diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c -index f9895e31ff5a..f828f3c35a6f 100644 ---- a/tools/power/cpupower/utils/cpufreq-info.c -+++ b/tools/power/cpupower/utils/cpufreq-info.c -@@ -84,43 +84,6 @@ static void proc_cpufreq_output(void) - } - - static int no_rounding; --static void print_speed(unsigned long speed) --{ -- unsigned long tmp; -- -- if (no_rounding) { -- if (speed > 1000000) -- printf("%u.%06u GHz", ((unsigned int) speed/1000000), -- ((unsigned int) speed%1000000)); -- else if (speed > 1000) -- printf("%u.%03u MHz", ((unsigned int) speed/1000), -- (unsigned int) (speed%1000)); -- else -- printf("%lu kHz", speed); -- } else { -- if (speed > 1000000) { -- tmp = speed%10000; -- if (tmp >= 5000) -- speed += 10000; -- printf("%u.%02u GHz", ((unsigned int) speed/1000000), -- ((unsigned int) (speed%1000000)/10000)); -- } else if (speed > 100000) { -- tmp = speed%1000; -- if (tmp >= 500) -- speed += 1000; -- printf("%u MHz", ((unsigned int) speed/1000)); -- } else if (speed > 1000) { -- tmp = speed%100; -- if (tmp >= 50) -- speed += 100; -- printf("%u.%01u MHz", ((unsigned int) speed/1000), -- ((unsigned int) (speed%1000)/100)); -- } -- } -- -- return; --} -- - static void print_duration(unsigned long duration) - { - unsigned long tmp; -@@ -183,9 +146,12 @@ static int get_boost_mode_x86(unsigned int cpu) - printf(_(" Supported: %s\n"), support ? _("yes") : _("no")); - printf(_(" Active: %s\n"), active ? _("yes") : _("no")); - -- if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD && -- cpupower_cpu_info.family >= 0x10) || -- cpupower_cpu_info.vendor == X86_VENDOR_HYGON) { -+ if (cpupower_cpu_info.vendor == X86_VENDOR_AMD && -+ cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) { -+ amd_pstate_show_perf_and_freq(cpu, no_rounding); -+ } else if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD && -+ cpupower_cpu_info.family >= 0x10) || -+ cpupower_cpu_info.vendor == X86_VENDOR_HYGON) { - ret = decode_pstates(cpu, b_states, pstates, &pstate_no); - if (ret) - return ret; -@@ -254,11 +220,11 @@ static int get_boost_mode(unsigned int cpu) - if (freqs) { - printf(_(" boost frequency steps: ")); - while (freqs->next) { -- print_speed(freqs->frequency); -+ print_speed(freqs->frequency, no_rounding); - printf(", "); - freqs = freqs->next; - } -- print_speed(freqs->frequency); -+ print_speed(freqs->frequency, no_rounding); - printf("\n"); - cpufreq_put_available_frequencies(freqs); - } -@@ -277,7 +243,7 @@ static int get_freq_kernel(unsigned int cpu, unsigned int human) - return -EINVAL; - } - if (human) { -- print_speed(freq); -+ print_speed(freq, no_rounding); - } else - printf("%lu", freq); - printf(_(" (asserted by call to kernel)\n")); -@@ -296,7 +262,7 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human) - return -EINVAL; - } - if (human) { -- print_speed(freq); -+ print_speed(freq, no_rounding); - } else - printf("%lu", freq); - printf(_(" (asserted by call to hardware)\n")); -@@ -316,9 +282,9 @@ static int get_hardware_limits(unsigned int cpu, unsigned int human) - - if (human) { - printf(_(" hardware limits: ")); -- print_speed(min); -+ print_speed(min, no_rounding); - printf(" - "); -- print_speed(max); -+ print_speed(max, no_rounding); - printf("\n"); - } else { - printf("%lu %lu\n", min, max); -@@ -350,9 +316,9 @@ static int get_policy(unsigned int cpu) - return -EINVAL; - } - printf(_(" current policy: frequency should be within ")); -- print_speed(policy->min); -+ print_speed(policy->min, no_rounding); - printf(_(" and ")); -- print_speed(policy->max); -+ print_speed(policy->max, no_rounding); - - printf(".\n "); - printf(_("The governor \"%s\" may decide which speed to use\n" -@@ -436,7 +402,7 @@ static int get_freq_stats(unsigned int cpu, unsigned int human) - struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time); - while (stats) { - if (human) { -- print_speed(stats->frequency); -+ print_speed(stats->frequency, no_rounding); - printf(":%.2f%%", - (100.0 * stats->time_in_state) / total_time); - } else -@@ -486,11 +452,11 @@ static void debug_output_one(unsigned int cpu) - if (freqs) { - printf(_(" available frequency steps: ")); - while (freqs->next) { -- print_speed(freqs->frequency); -+ print_speed(freqs->frequency, no_rounding); - printf(", "); - freqs = freqs->next; - } -- print_speed(freqs->frequency); -+ print_speed(freqs->frequency, no_rounding); - printf("\n"); - cpufreq_put_available_frequencies(freqs); - } -diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c -index 97f2c857048e..d68d052ee4cb 100644 ---- a/tools/power/cpupower/utils/helpers/amd.c -+++ b/tools/power/cpupower/utils/helpers/amd.c -@@ -8,7 +8,9 @@ - #include <pci/pci.h> - - #include "helpers/helpers.h" -+#include "cpufreq.h" - -+/* ACPI P-States Helper Functions for AMD Processors ***************/ - #define MSR_AMD_PSTATE_STATUS 0xc0010063 - #define MSR_AMD_PSTATE 0xc0010064 - #define MSR_AMD_PSTATE_LIMIT 0xc0010061 -@@ -146,4 +148,84 @@ int amd_pci_get_num_boost_states(int *active, int *states) - pci_cleanup(pci_acc); - return 0; - } -+ -+/* ACPI P-States Helper Functions for AMD Processors ***************/ -+ -+/* AMD P-States Helper Functions ***************/ -+enum amd_pstate_value { -+ AMD_PSTATE_HIGHEST_PERF, -+ AMD_PSTATE_NOMINAL_PERF, -+ AMD_PSTATE_LOWEST_NONLINEAR_PERF, -+ AMD_PSTATE_LOWEST_PERF, -+ AMD_PSTATE_MAX_FREQ, -+ AMD_PSTATE_NOMINAL_FREQ, -+ AMD_PSTATE_LOWEST_NONLINEAR_FREQ, -+ AMD_PSTATE_MIN_FREQ, -+ MAX_AMD_PSTATE_VALUE_READ_FILES -+}; -+ -+static const char *amd_pstate_value_files[MAX_AMD_PSTATE_VALUE_READ_FILES] = { -+ [AMD_PSTATE_HIGHEST_PERF] = "amd_pstate_highest_perf", -+ [AMD_PSTATE_NOMINAL_PERF] = "amd_pstate_nominal_perf", -+ [AMD_PSTATE_LOWEST_NONLINEAR_PERF] = "amd_pstate_lowest_nonlinear_perf", -+ [AMD_PSTATE_LOWEST_PERF] = "amd_pstate_lowest_perf", -+ [AMD_PSTATE_MAX_FREQ] = "amd_pstate_max_freq", -+ [AMD_PSTATE_NOMINAL_FREQ] = "amd_pstate_nominal_freq", -+ [AMD_PSTATE_LOWEST_NONLINEAR_FREQ] = "amd_pstate_lowest_nonlinear_freq", -+ [AMD_PSTATE_MIN_FREQ] = "amd_pstate_min_freq" -+}; -+ -+static unsigned long amd_pstate_get_data(unsigned int cpu, -+ enum amd_pstate_value value) -+{ -+ return cpufreq_get_sysfs_value_from_table(cpu, -+ amd_pstate_value_files, -+ value, -+ MAX_AMD_PSTATE_VALUE_READ_FILES); -+} -+ -+void amd_pstate_boost_init(unsigned int cpu, int *support, int *active) -+{ -+ unsigned long highest_perf, nominal_perf, cpuinfo_min, -+ cpuinfo_max, amd_pstate_max; -+ -+ highest_perf = amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF); -+ nominal_perf = amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_PERF); -+ -+ *support = highest_perf > nominal_perf ? 1 : 0; -+ if (!(*support)) -+ return; -+ -+ cpufreq_get_hardware_limits(cpu, &cpuinfo_min, &cpuinfo_max); -+ amd_pstate_max = amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ); -+ -+ *active = cpuinfo_max == amd_pstate_max ? 1 : 0; -+} -+ -+void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding) -+{ -+ printf(_(" AMD PSTATE Highest Performance: %lu. Maximum Frequency: "), -+ amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF)); -+ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ), no_rounding); -+ printf(".\n"); -+ -+ printf(_(" AMD PSTATE Nominal Performance: %lu. Nominal Frequency: "), -+ amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_PERF)); -+ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_NOMINAL_FREQ), -+ no_rounding); -+ printf(".\n"); -+ -+ printf(_(" AMD PSTATE Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "), -+ amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_NONLINEAR_PERF)); -+ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_NONLINEAR_FREQ), -+ no_rounding); -+ printf(".\n"); -+ -+ printf(_(" AMD PSTATE Lowest Performance: %lu. Lowest Frequency: "), -+ amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_PERF)); -+ print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MIN_FREQ), no_rounding); -+ printf(".\n"); -+} -+ -+/* AMD P-States Helper Functions ***************/ - #endif /* defined(__i386__) || defined(__x86_64__) */ -diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c -index 72eb43593180..2a6dc104e76b 100644 ---- a/tools/power/cpupower/utils/helpers/cpuid.c -+++ b/tools/power/cpupower/utils/helpers/cpuid.c -@@ -149,6 +149,19 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info) - if (ext_cpuid_level >= 0x80000008 && - cpuid_ebx(0x80000008) & (1 << 4)) - cpu_info->caps |= CPUPOWER_CAP_AMD_RDPRU; -+ -+ if (cpupower_amd_pstate_enabled()) { -+ cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE; -+ -+ /* -+ * If AMD P-state is enabled, the firmware will treat -+ * AMD P-state function as high priority. -+ */ -+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB; -+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB_MSR; -+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_HW_PSTATE; -+ cpu_info->caps &= ~CPUPOWER_CAP_AMD_PSTATEDEF; -+ } - } - - if (cpu_info->vendor == X86_VENDOR_INTEL) { -diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h -index 33ffacee7fcb..80755568afc4 100644 ---- a/tools/power/cpupower/utils/helpers/helpers.h -+++ b/tools/power/cpupower/utils/helpers/helpers.h -@@ -73,6 +73,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, - #define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100 - #define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200 - #define CPUPOWER_CAP_AMD_CPB_MSR 0x00000400 -+#define CPUPOWER_CAP_AMD_PSTATE 0x00000800 - - #define CPUPOWER_AMD_CPBDIS 0x02000000 - -@@ -135,6 +136,16 @@ extern int decode_pstates(unsigned int cpu, int boost_states, - - extern int cpufreq_has_boost_support(unsigned int cpu, int *support, - int *active, int * states); -+ -+/* AMD P-States stuff **************************/ -+extern unsigned long cpupower_amd_pstate_enabled(void); -+extern void amd_pstate_boost_init(unsigned int cpu, -+ int *support, int *active); -+extern void amd_pstate_show_perf_and_freq(unsigned int cpu, -+ int no_rounding); -+ -+/* AMD P-States stuff **************************/ -+ - /* - * CPUID functions returning a single datum - */ -@@ -167,6 +178,15 @@ static inline int cpufreq_has_boost_support(unsigned int cpu, int *support, - int *active, int * states) - { return -1; } - -+static inline unsigned long cpupower_amd_pstate_enabled(void) -+{ return 0; } -+static void amd_pstate_boost_init(unsigned int cpu, -+ int *support, int *active) -+{ return; } -+static inline void amd_pstate_show_perf_and_freq(unsigned int cpu, -+ int no_rounding) -+{ return; } -+ - /* cpuid and cpuinfo helpers **************************/ - - static inline unsigned int cpuid_eax(unsigned int op) { return 0; }; -@@ -184,5 +204,6 @@ extern struct bitmask *offline_cpus; - void get_cpustate(void); - void print_online_cpus(void); - void print_offline_cpus(void); -+void print_speed(unsigned long speed, int no_rounding); - - #endif /* __CPUPOWERUTILS_HELPERS__ */ -diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c -index fc6e34511721..730f670ab90d 100644 ---- a/tools/power/cpupower/utils/helpers/misc.c -+++ b/tools/power/cpupower/utils/helpers/misc.c -@@ -39,6 +39,8 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, - if (ret) - return ret; - } -+ } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) { -+ amd_pstate_boost_init(cpu, support, active); - } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA) - *support = *active = 1; - return 0; -@@ -83,6 +85,26 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val) - return 0; - } - -+unsigned long cpupower_amd_pstate_enabled(void) -+{ -+ char linebuf[MAX_LINE_LEN]; -+ char path[SYSFS_PATH_MAX]; -+ unsigned long val; -+ char *endp; -+ -+ snprintf(path, sizeof(path), -+ PATH_TO_CPU "cpu0/cpufreq/is_amd_pstate_enabled"); -+ -+ if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) -+ return 0; -+ -+ val = strtoul(linebuf, &endp, 0); -+ if (endp == linebuf || errno == ERANGE) -+ return 0; -+ -+ return val; -+} -+ - #endif /* #if defined(__i386__) || defined(__x86_64__) */ - - /* get_cpustate -@@ -144,3 +166,45 @@ void print_offline_cpus(void) - printf(_("cpupower set operation was not performed on them\n")); - } - } -+ -+/* -+ * print_speed -+ * -+ * Print the exact CPU frequency with appropriate unit -+ */ -+void print_speed(unsigned long speed, int no_rounding) -+{ -+ unsigned long tmp; -+ -+ if (no_rounding) { -+ if (speed > 1000000) -+ printf("%u.%06u GHz", ((unsigned int) speed/1000000), -+ ((unsigned int) speed%1000000)); -+ else if (speed > 1000) -+ printf("%u.%03u MHz", ((unsigned int) speed/1000), -+ (unsigned int) (speed%1000)); -+ else -+ printf("%lu kHz", speed); -+ } else { -+ if (speed > 1000000) { -+ tmp = speed%10000; -+ if (tmp >= 5000) -+ speed += 10000; -+ printf("%u.%02u GHz", ((unsigned int) speed/1000000), -+ ((unsigned int) (speed%1000000)/10000)); -+ } else if (speed > 100000) { -+ tmp = speed%1000; -+ if (tmp >= 500) -+ speed += 1000; -+ printf("%u MHz", ((unsigned int) speed/1000)); -+ } else if (speed > 1000) { -+ tmp = speed%100; -+ if (tmp >= 50) -+ speed += 100; -+ printf("%u.%01u MHz", ((unsigned int) speed/1000), -+ ((unsigned int) (speed%1000)/100)); -+ } -+ } -+ -+ return; -+} --- -2.33.0 - diff --git a/sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch b/sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch deleted file mode 100644 index c77aa387e8b4..000000000000 --- a/sys-kernel_arch-sources-g14_files-9010-ACPI-PM-s2idle-Don-t-report-missing-devices-as-faili.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c5d0ba7e96f765859bb2ddbd5fc0407d7e6e7124 Mon Sep 17 00:00:00 2001 -From: Mario Limonciello <mario.limonciello@amd.com> -Date: Fri, 24 Sep 2021 12:32:06 -0500 -Subject: [PATCH 1/2] ACPI: PM: s2idle: Don't report missing devices as failing - constraints - -ACPI tables may have entries for devices that are not physically -present but that can be connected. These devices shouldn't cause -constraints checking to fail. - -Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> -Change-Id: I34f5ca978aab69ff0a0906191eec21649b19fe27 ---- - drivers/acpi/x86/s2idle.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c -index bd92b549fd5a..c8d4f7909fa9 100644 ---- a/drivers/acpi/x86/s2idle.c -+++ b/drivers/acpi/x86/s2idle.c -@@ -309,6 +309,12 @@ static void lpi_check_constraints(void) - continue; - } - -+ if (!acpi_get_first_physical_node(adev)) { -+ acpi_handle_debug(handle, "LPI: Device is not physically present\n"); -+ lpi_constraints_table[i].handle = NULL; -+ continue; -+ } -+ - if (adev->power.state < lpi_constraints_table[i].min_dstate) - acpi_handle_info(handle, - "LPI: Constraint not met; min power state:%s current power state:%s\n", --- -2.25.1 - |