From 3937e51421b640358d842fca50867c674c8313d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A5=D0=B8=D1=80=D0=B5=D1=86=D0=BA=D0=B8=D0=B9=20=D0=9C?= =?UTF-8?q?=D0=B8=D1=85=D0=B0=D0=B8=D0=BB?= Date: Wed, 2 Dec 2020 17:50:26 +0300 Subject: [PATCH 1/6] =?UTF-8?q?sys-boot/plymouth:=20=D0=BE=D0=B1=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF=D0=B0=D1=82=D1=87?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=BB=D1=8F=200.9.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plymouth/plymouth-init_fb-0.9.4.patch | 188 ++++++++++++++++++ .../sys-boot/plymouth/plymouth-init_fb.patch | 65 +++--- .../plymouth/plymouth-shutdown-0.9.4.patch | 23 +++ .../sys-boot/plymouth/plymouth-shutdown.patch | 4 +- 4 files changed, 239 insertions(+), 41 deletions(-) create mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb-0.9.4.patch create mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown-0.9.4.patch diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb-0.9.4.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb-0.9.4.patch new file mode 100644 index 000000000..9e65b0cb6 --- /dev/null +++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb-0.9.4.patch @@ -0,0 +1,188 @@ +# Calculate format=diff merge(sys-boot/plymouth)<0.9.5 +commit 4ec46d8b9a1fdd4eb791013bae98e4ca34b412de +Author: Mir Calculate +Date: Wed Feb 13 15:35:50 2019 +0300 + + Изменён порядок инициализации framebuffer для plymouth + + Добавлена переменная конфигурационного файла + FBDeviceTimeout, по истечении которого plymouth будет ожидать не только DRM + устройства, но и framebuffer. По истечении DeviceTimeout plymouth будет + запущен для text mode. + +diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c +index 55248ac..4350324 100644 +--- a/src/libply-splash-core/ply-device-manager.c ++++ b/src/libply-splash-core/ply-device-manager.c +@@ -39,12 +39,14 @@ + #include "ply-hashtable.h" + #include "ply-list.h" + #include "ply-utils.h" ++#include + + #define SUBSYSTEM_DRM "drm" + #define SUBSYSTEM_FRAME_BUFFER "graphics" + + #ifdef HAVE_UDEV + static void create_devices_from_udev (ply_device_manager_t *manager); ++static void create_fb_devices_from_udev (ply_device_manager_t *manager); + #endif + + static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager, +@@ -81,6 +83,7 @@ struct _ply_device_manager + + uint32_t paused : 1; + uint32_t device_timeout_elapsed : 1; ++ uint32_t fb_device_timeout_elapsed : 1; + }; + + static void +@@ -361,7 +364,12 @@ on_udev_event (ply_device_manager_t *manager) + ply_trace ("ignoring since we're already using text splash for local console"); + else + create_devices_for_udev_device (manager, device); +- } else { ++ } else if (manager->fb_device_timeout_elapsed && strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0){ ++ if (manager->local_console_managed && manager->local_console_is_text) ++ ply_trace ("ignoring since we're already using text splash for local console"); ++ else ++ create_devices_for_udev_device (manager, device); ++ } else { + ply_trace ("ignoring since we only handle subsystem %s devices after timeout", subsystem); + } + } else if (strcmp (action, "remove") == 0) { +@@ -539,6 +547,9 @@ ply_device_manager_free (ply_device_manager_t *manager) + ply_event_loop_stop_watching_for_timeout (manager->loop, + (ply_event_loop_timeout_handler_t) + create_devices_from_udev, manager); ++ ply_event_loop_stop_watching_for_timeout (manager->loop, ++ (ply_event_loop_timeout_handler_t) ++ create_fb_devices_from_udev, manager); + + if (manager->udev_monitor != NULL) + udev_monitor_unref (manager->udev_monitor); +@@ -838,6 +849,24 @@ create_devices_from_udev (ply_device_manager_t *manager) + ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware"); + create_non_graphical_devices (manager); + } ++ ++static void ++create_fb_devices_from_udev (ply_device_manager_t *manager) ++{ ++ bool found_drm_device, found_fb_device; ++ ++ manager->fb_device_timeout_elapsed = true; ++ ++ if (manager->paused) { ++ ply_trace ("create_fb_devices_from_udev timeout elapsed while paused, deferring execution"); ++ return; ++ } ++ ++ ply_trace ("Timeout elapsed, looking for framebuffer devices from udev"); ++ ++ found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM); ++ found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); ++} + #endif + + static void +@@ -851,6 +880,7 @@ create_fallback_devices (ply_device_manager_t *manager) + + void + ply_device_manager_watch_devices (ply_device_manager_t *manager, ++ double fb_device_timeout, + double device_timeout, + ply_keyboard_added_handler_t keyboard_added_handler, + ply_keyboard_removed_handler_t keyboard_removed_handler, +@@ -870,6 +900,9 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager, + manager->text_display_removed_handler = text_display_removed_handler; + manager->event_handler_data = data; + ++ if (isnan (fb_device_timeout)) ++ fb_device_timeout = 5; ++ + /* Try to create devices for each serial device right away, if possible + */ + done_with_initial_devices_setup = create_devices_from_terminals (manager); +@@ -892,6 +925,10 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager, + #ifdef HAVE_UDEV + watch_for_udev_events (manager); + create_devices_for_subsystem (manager, SUBSYSTEM_DRM); ++ ply_event_loop_watch_for_timeout (manager->loop, ++ fb_device_timeout, ++ (ply_event_loop_timeout_handler_t) ++ create_fb_devices_from_udev, manager); + ply_event_loop_watch_for_timeout (manager->loop, + device_timeout, + (ply_event_loop_timeout_handler_t) +@@ -1035,6 +1072,10 @@ ply_device_manager_unpause (ply_device_manager_t *manager) + ply_trace ("ply_device_manager_unpause() called, resuming watching for udev events"); + manager->paused = false; + #ifdef HAVE_UDEV ++ if (manager->fb_device_timeout_elapsed) { ++ ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for framebuffer udev devices"); ++ create_fb_devices_from_udev (manager); ++ } + if (manager->device_timeout_elapsed) { + ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for udev devices"); + create_devices_from_udev (manager); +diff --git a/src/libply-splash-core/ply-device-manager.h b/src/libply-splash-core/ply-device-manager.h +index 389b636..37198a2 100644 +--- a/src/libply-splash-core/ply-device-manager.h ++++ b/src/libply-splash-core/ply-device-manager.h +@@ -47,6 +47,7 @@ typedef void (* ply_text_display_removed_handler_t) (void *, ply_text_display_t + ply_device_manager_t *ply_device_manager_new (const char *default_tty, + ply_device_manager_flags_t flags); + void ply_device_manager_watch_devices (ply_device_manager_t *manager, ++ double fb_device_timeout, + double device_timeout, + ply_keyboard_added_handler_t keyboard_added_handler, + ply_keyboard_removed_handler_t keyboard_removed_handler, +diff --git a/src/main.c b/src/main.c +index ddc1883..f8f980c 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -103,6 +103,7 @@ typedef struct + double start_time; + double splash_delay; + double device_timeout; ++ double fb_device_timeout; + + uint32_t no_boot_log : 1; + uint32_t showing_details : 1; +@@ -340,6 +341,19 @@ load_settings (state_t *state, + } + } + ++ if (isnan (state->fb_device_timeout)) { ++ char *timeout_string; ++ ++ timeout_string = ply_key_file_get_value (key_file, "Daemon", "FBDeviceTimeout"); ++ ++ if (timeout_string != NULL) { ++ state->fb_device_timeout = atof (timeout_string); ++ ply_trace ("Framebuffer device timeout is set to %lf", state->fb_device_timeout); ++ ++ free (timeout_string); ++ } ++ } ++ + scale_string = ply_key_file_get_value (key_file, "Daemon", "DeviceScale"); + + if (scale_string != NULL) { +@@ -1100,6 +1114,7 @@ load_devices (state_t *state, + state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); + + ply_device_manager_watch_devices (state->device_manager, ++ state->fb_device_timeout, + state->device_timeout, + (ply_keyboard_added_handler_t) + on_keyboard_added, +@@ -2269,6 +2284,7 @@ main (int argc, + state.progress = ply_progress_new (); + state.splash_delay = NAN; + state.device_timeout = NAN; ++ state.fb_device_timeout = NAN; + + ply_progress_load_cache (state.progress, + get_cache_file_for_mode (state.mode)); diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch index e9a4373ea..fb7f7f623 100644 --- a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch +++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-init_fb.patch @@ -1,17 +1,6 @@ -# Calculate format=diff -commit 4ec46d8b9a1fdd4eb791013bae98e4ca34b412de -Author: Mir Calculate -Date: Wed Feb 13 15:35:50 2019 +0300 - - Изменён порядок инициализации framebuffer для plymouth - - Добавлена переменная конфигурационного файла - FBDeviceTimeout, по истечении которого plymouth будет ожидать не только DRM - устройства, но и framebuffer. По истечении DeviceTimeout plymouth будет - запущен для text mode. - +# Calculate format=diff merge(sys-boot/plymouth)>=0.9.5 diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c -index 55248ac..4350324 100644 +index f65d731..954a241 100644 --- a/src/libply-splash-core/ply-device-manager.c +++ b/src/libply-splash-core/ply-device-manager.c @@ -39,12 +39,14 @@ @@ -29,29 +18,29 @@ index 55248ac..4350324 100644 #endif static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager, -@@ -81,6 +83,7 @@ struct _ply_device_manager +@@ -84,6 +86,7 @@ struct _ply_device_manager uint32_t paused : 1; uint32_t device_timeout_elapsed : 1; -+ uint32_t fb_device_timeout_elapsed : 1; ++ uint32_t fb_device_timeout_elapsed : 1; + uint32_t found_drm_device : 1; + uint32_t found_fb_device : 1; }; - - static void -@@ -361,7 +364,12 @@ on_udev_event (ply_device_manager_t *manager) +@@ -442,7 +445,12 @@ on_udev_event (ply_device_manager_t *manager) ply_trace ("ignoring since we're already using text splash for local console"); else - create_devices_for_udev_device (manager, device); + on_drm_udev_add_or_change (manager, action, device); - } else { + } else if (manager->fb_device_timeout_elapsed && strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0){ + if (manager->local_console_managed && manager->local_console_is_text) + ply_trace ("ignoring since we're already using text splash for local console"); + else -+ create_devices_for_udev_device (manager, device); ++ on_drm_udev_add_or_change (manager, action, device); + } else { ply_trace ("ignoring since we only handle subsystem %s devices after timeout", subsystem); } } else if (strcmp (action, "remove") == 0) { -@@ -539,6 +547,9 @@ ply_device_manager_free (ply_device_manager_t *manager) +@@ -620,6 +628,9 @@ ply_device_manager_free (ply_device_manager_t *manager) ply_event_loop_stop_watching_for_timeout (manager->loop, (ply_event_loop_timeout_handler_t) create_devices_from_udev, manager); @@ -61,7 +50,7 @@ index 55248ac..4350324 100644 if (manager->udev_monitor != NULL) udev_monitor_unref (manager->udev_monitor); -@@ -838,6 +849,24 @@ create_devices_from_udev (ply_device_manager_t *manager) +@@ -917,6 +928,22 @@ create_devices_from_udev (ply_device_manager_t *manager) ply_trace ("Creating non-graphical devices, since there's no suitable graphics hardware"); create_non_graphical_devices (manager); } @@ -69,8 +58,6 @@ index 55248ac..4350324 100644 +static void +create_fb_devices_from_udev (ply_device_manager_t *manager) +{ -+ bool found_drm_device, found_fb_device; -+ + manager->fb_device_timeout_elapsed = true; + + if (manager->paused) { @@ -80,31 +67,31 @@ index 55248ac..4350324 100644 + + ply_trace ("Timeout elapsed, looking for framebuffer devices from udev"); + -+ found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM); -+ found_fb_device = create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); ++ create_devices_for_subsystem (manager, SUBSYSTEM_DRM); ++ create_devices_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER); +} #endif static void -@@ -851,6 +880,7 @@ create_fallback_devices (ply_device_manager_t *manager) +@@ -930,6 +957,7 @@ create_fallback_devices (ply_device_manager_t *manager) void ply_device_manager_watch_devices (ply_device_manager_t *manager, -+ double fb_device_timeout, ++ double fb_device_timeout, double device_timeout, ply_keyboard_added_handler_t keyboard_added_handler, ply_keyboard_removed_handler_t keyboard_removed_handler, -@@ -870,6 +900,9 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager, +@@ -949,6 +977,9 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager, manager->text_display_removed_handler = text_display_removed_handler; manager->event_handler_data = data; -+ if (isnan (fb_device_timeout)) -+ fb_device_timeout = 5; ++ if (isnan (fb_device_timeout)) ++ fb_device_timeout = 5; + /* Try to create devices for each serial device right away, if possible */ done_with_initial_devices_setup = create_devices_from_terminals (manager); -@@ -892,6 +925,10 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager, +@@ -971,6 +1002,10 @@ ply_device_manager_watch_devices (ply_device_manager_t *manager, #ifdef HAVE_UDEV watch_for_udev_events (manager); create_devices_for_subsystem (manager, SUBSYSTEM_DRM); @@ -115,12 +102,12 @@ index 55248ac..4350324 100644 ply_event_loop_watch_for_timeout (manager->loop, device_timeout, (ply_event_loop_timeout_handler_t) -@@ -1035,6 +1072,10 @@ ply_device_manager_unpause (ply_device_manager_t *manager) +@@ -1114,6 +1149,10 @@ ply_device_manager_unpause (ply_device_manager_t *manager) ply_trace ("ply_device_manager_unpause() called, resuming watching for udev events"); manager->paused = false; #ifdef HAVE_UDEV + if (manager->fb_device_timeout_elapsed) { -+ ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for framebuffer udev devices"); ++ ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for udev devices"); + create_fb_devices_from_udev (manager); + } if (manager->device_timeout_elapsed) { @@ -139,10 +126,10 @@ index 389b636..37198a2 100644 ply_keyboard_added_handler_t keyboard_added_handler, ply_keyboard_removed_handler_t keyboard_removed_handler, diff --git a/src/main.c b/src/main.c -index ddc1883..f8f980c 100644 +index 850c3b0..13c9272 100644 --- a/src/main.c +++ b/src/main.c -@@ -103,6 +103,7 @@ typedef struct +@@ -97,6 +97,7 @@ typedef struct double start_time; double splash_delay; double device_timeout; @@ -150,7 +137,7 @@ index ddc1883..f8f980c 100644 uint32_t no_boot_log : 1; uint32_t showing_details : 1; -@@ -340,6 +341,19 @@ load_settings (state_t *state, +@@ -317,6 +318,19 @@ load_settings (state_t *state, } } @@ -170,7 +157,7 @@ index ddc1883..f8f980c 100644 scale_string = ply_key_file_get_value (key_file, "Daemon", "DeviceScale"); if (scale_string != NULL) { -@@ -1100,6 +1114,7 @@ load_devices (state_t *state, +@@ -1096,6 +1110,7 @@ load_devices (state_t *state, state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); ply_device_manager_watch_devices (state->device_manager, @@ -178,7 +165,7 @@ index ddc1883..f8f980c 100644 state->device_timeout, (ply_keyboard_added_handler_t) on_keyboard_added, -@@ -2269,6 +2284,7 @@ main (int argc, +@@ -2244,6 +2259,7 @@ main (int argc, state.progress = ply_progress_new (); state.splash_delay = NAN; state.device_timeout = NAN; diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown-0.9.4.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown-0.9.4.patch new file mode 100644 index 000000000..d31fef9c7 --- /dev/null +++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown-0.9.4.patch @@ -0,0 +1,23 @@ +# Calculate format=diff merge(sys-boot/plymouth)<0.9.5 +commit c0e512de2352611112c5476e0032514e2b2d713c +Author: Mir Calculate +Date: Tue Feb 19 12:17:41 2019 +0300 + + Добавлена возможность указать запуск splash только для shutdown + +diff --git a/src/main.c b/src/main.c +index f8f980c..c702c10 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -916,6 +916,11 @@ plymouth_should_show_default_splash (state_t *state) + return true; + } + ++ if (ply_kernel_command_line_has_argument ("splash=shutdown") && state->mode == PLY_MODE_SHUTDOWN) { ++ ply_trace ("using default splash because kernel command line has option \"splash=shutdown\""); ++ return true; ++ } ++ + if (ply_kernel_command_line_has_argument ("splash=silent")) { + ply_trace ("using default splash because kernel command line has option \"splash=silent\""); + return true; diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch index 828758b41..a6fea453e 100644 --- a/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch +++ b/profiles/templates/3.6/6_ac_install_patch/sys-boot/plymouth/plymouth-shutdown.patch @@ -1,4 +1,4 @@ -# Calculate format=diff +# Calculate format=diff pkg(sys-boot/plymouth)>=0.9.5 commit c0e512de2352611112c5476e0032514e2b2d713c Author: Mir Calculate Date: Tue Feb 19 12:17:41 2019 +0300 @@ -13,7 +13,7 @@ index f8f980c..c702c10 100644 return true; } -+ if (ply_kernel_command_line_has_argument ("splash=shutdown") && state->mode == PLY_MODE_SHUTDOWN) { ++ if (ply_kernel_command_line_has_argument ("splash=shutdown") && state->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN) { + ply_trace ("using default splash because kernel command line has option \"splash=shutdown\""); + return true; + } From b1aa85c1e828cf4350cdd153cb66a3bec835be01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A5=D0=B8=D1=80=D0=B5=D1=86=D0=BA=D0=B8=D0=B9=20=D0=9C?= =?UTF-8?q?=D0=B8=D1=85=D0=B0=D0=B8=D0=BB?= Date: Wed, 2 Dec 2020 18:05:05 +0300 Subject: [PATCH 2/6] =?UTF-8?q?sys-boot/plymouth-calculate-plugin:=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=200.9.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sys-boot/plymouth-calculate-plugin/Manifest | 1 + .../files/0.9.5-calculate.plymouth | 74 + .../files/0.9.5-plugin.c | 2223 +++++++++++++++++ .../plymouth-calculate-plugin-0.9.5.ebuild | 98 + 4 files changed, 2396 insertions(+) create mode 100644 sys-boot/plymouth-calculate-plugin/files/0.9.5-calculate.plymouth create mode 100644 sys-boot/plymouth-calculate-plugin/files/0.9.5-plugin.c create mode 100644 sys-boot/plymouth-calculate-plugin/plymouth-calculate-plugin-0.9.5.ebuild diff --git a/sys-boot/plymouth-calculate-plugin/Manifest b/sys-boot/plymouth-calculate-plugin/Manifest index 8c959d026..c41ebb209 100644 --- a/sys-boot/plymouth-calculate-plugin/Manifest +++ b/sys-boot/plymouth-calculate-plugin/Manifest @@ -1 +1,2 @@ DIST plymouth-0.9.4.tar.xz 1103496 BLAKE2B abad2cefb89e9d17b77113396d7203090544759b3dd7f73f67153d9f126db28e5366d36aa11e2335566bf4046bebd50d8d9dd47c75634446fb3a0314cd458925 SHA512 83eb2de7e6d0980e9f7fa4e0b0f20c46a8238051d84bc38dbbb5dfa438e41c1a39846dcd652374256d9f1fe79967b154a3576cd9c433ef816b6c962be2d31e93 +DIST plymouth-0.9.5.tar.xz 1186200 BLAKE2B 8fd073703773fcf7f3e26454c860f094fb4b3d712c56c9df6716ef11815a79f7d5b078ab6c6567b76421026d84a086f95865bf9f3e4ae6363cb1ffc2caa68537 SHA512 686220e8d5b1a8be298156786d979d0e3fb9e010b930d0e8082a2bb152cf07c1bf493d820c243838a1771ee859dc0b4723bd9f10ee434a94a096ce9236c36ce9 diff --git a/sys-boot/plymouth-calculate-plugin/files/0.9.5-calculate.plymouth b/sys-boot/plymouth-calculate-plugin/files/0.9.5-calculate.plymouth new file mode 100644 index 000000000..d23ed1b73 --- /dev/null +++ b/sys-boot/plymouth-calculate-plugin/files/0.9.5-calculate.plymouth @@ -0,0 +1,74 @@ +[Plymouth Theme] +Name=Calculate +Description=Calculate spinner theme +ModuleName=calculate + +[calculate] +Font=DroidSans 12 +TitleFont=DroidSans 30 +ImageDir=/usr/share/plymouth/themes/calculate +DialogHorizontalAlignment=.5 +DialogVerticalAlignment=.382 +TitleHorizontalAlignment=.5 +TitleVerticalAlignment=.5 +HorizontalAlignment=.5 +VerticalAlignment=.5 +WatermarkHorizontalAlignment=.5 +WatermarkVerticalAlignment=.5 +Transition=none +TransitionDuration=0.0 +BackgroundStartColor=0x000000 +BackgroundEndColor=0x000000 +ProgressBarBackgroundColor=0x606060 +ProgressBarForegroundColor=0xffffff +DialogClearsFirmwareBackground=true +MessageBelowAnimation=true + +[boot-up] +UseEndAnimation=false +UseFirmwareBackground=false +VerticalAlignmentType=below_watermark +VerticalAlignment=.0 +WatermarkImage=/usr/share/plymouth/themes/calculate/boot.png + +[shutdown] +UseEndAnimation=false +UseFirmwareBackground=false +Title=Shutdown... +TitleColor=0xaaaaaa +VerticalAlignment=.0 +VerticalAlignmentType=below_title +WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown + +[reboot] +UseEndAnimation=false +UseFirmwareBackground=false +Title=Reboot... +TitleColor=0xaaaaaa +VerticalAlignment=.0 +VerticalAlignmentType=below_title +WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown + +[updates] +UseFirmwareBackground=false +SuppressMessages=true +ProgressBarShowPercentComplete=true +UseProgressBar=true +Title=Installing Updates... +SubTitle=Do not turn off your computer + +[system-upgrade] +UseFirmwareBackground=false +SuppressMessages=true +ProgressBarShowPercentComplete=true +UseProgressBar=true +Title=Upgrading System... +SubTitle=Do not turn off your computer + +[firmware-upgrade] +UseFirmwareBackground=false +SuppressMessages=true +ProgressBarShowPercentComplete=true +UseProgressBar=true +Title=Upgrading Firmware... +SubTitle=Do not turn off your computer diff --git a/sys-boot/plymouth-calculate-plugin/files/0.9.5-plugin.c b/sys-boot/plymouth-calculate-plugin/files/0.9.5-plugin.c new file mode 100644 index 000000000..98d0c809a --- /dev/null +++ b/sys-boot/plymouth-calculate-plugin/files/0.9.5-plugin.c @@ -0,0 +1,2223 @@ +/* + * + * Copyright (C) 2009-2019 Red Hat, Inc. + * + * 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, 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: William Jon McCann, Hans de Goede + * + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ply-boot-splash-plugin.h" +#include "ply-buffer.h" +#include "ply-capslock-icon.h" +#include "ply-entry.h" +#include "ply-event-loop.h" +#include "ply-label.h" +#include "ply-list.h" +#include "ply-logger.h" +#include "ply-image.h" +#include "ply-key-file.h" +#include "ply-keymap-icon.h" +#include "ply-trigger.h" +#include "ply-pixel-buffer.h" +#include "ply-pixel-display.h" +#include "ply-utils.h" +#include "ply-i18n.h" + +#include "ply-animation.h" +#include "ply-progress-animation.h" +#include "ply-throbber.h" +#include "ply-progress-bar.h" + +#include + +#ifndef FRAMES_PER_SECOND +#define FRAMES_PER_SECOND 30 +#endif + +#ifndef SHOW_ANIMATION_FRACTION +#define SHOW_ANIMATION_FRACTION 0.9 +#endif + +#define PROGRESS_BAR_WIDTH 400 +#define PROGRESS_BAR_HEIGHT 5 + +#define BGRT_STATUS_ORIENTATION_OFFSET_0 (0 << 1) +#define BGRT_STATUS_ORIENTATION_OFFSET_90 (1 << 1) +#define BGRT_STATUS_ORIENTATION_OFFSET_180 (2 << 1) +#define BGRT_STATUS_ORIENTATION_OFFSET_270 (3 << 1) +#define BGRT_STATUS_ORIENTATION_OFFSET_MASK (3 << 1) + +typedef enum +{ + PLY_BOOT_SPLASH_DISPLAY_NORMAL, + PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY, + PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY +} ply_boot_splash_display_type_t; + +typedef enum +{ + PROGRESS_FUNCTION_TYPE_WWOODS, + PROGRESS_FUNCTION_TYPE_LINEAR, +} progress_function_t; + +typedef struct +{ + ply_boot_splash_plugin_t *plugin; + ply_pixel_display_t *display; + ply_entry_t *entry; + ply_keymap_icon_t *keymap_icon; + ply_capslock_icon_t *capslock_icon; + ply_animation_t *end_animation; + ply_progress_animation_t *progress_animation; + ply_progress_bar_t *progress_bar; + ply_throbber_t *throbber; + ply_label_t *label; + ply_label_t *message_label; + ply_label_t *title_label; + ply_label_t *subtitle_label; + ply_rectangle_t box_area, lock_area, watermark_area, title_area, dialog_area; + ply_trigger_t *end_trigger; + ply_pixel_buffer_t *background_buffer; + ply_image_t *watermark_image; + int animation_bottom; +} view_t; + +typedef struct +{ + bool suppress_messages; + bool progress_bar_show_percent_complete; + bool use_progress_bar; + bool use_animation; + bool use_end_animation; + bool use_firmware_background; + char *title; + char *subtitle; + uint32_t background_start_color; + uint32_t background_end_color; + uint32_t title_color; + char *watermark_imagename; + double animation_horizontal_alignment; + double animation_vertical_alignment; + char *animation_vertical_alignment_type; +} mode_settings_t; + +struct _ply_boot_splash_plugin +{ + ply_event_loop_t *loop; + ply_boot_splash_mode_t mode; + mode_settings_t mode_settings[PLY_BOOT_SPLASH_MODE_COUNT]; + char *font; + ply_image_t *lock_image; + ply_image_t *box_image; + ply_image_t *corner_image; + ply_image_t *header_image; + ply_image_t *background_tile_image; + ply_image_t *background_bgrt_image; + ply_list_t *views; + + ply_boot_splash_display_type_t state; + + double dialog_horizontal_alignment; + double dialog_vertical_alignment; + + double title_horizontal_alignment; + double title_vertical_alignment; + char *title_font; + + double watermark_horizontal_alignment; + double watermark_vertical_alignment; + char *watermark_imagename; + + double animation_horizontal_alignment; + double animation_vertical_alignment; + char *animation_vertical_alignment_type; + char *animation_dir; + + ply_progress_animation_transition_t transition; + double transition_duration; + + uint32_t background_start_color; + uint32_t background_end_color; + uint32_t title_color; + int background_bgrt_raw_width; + int background_bgrt_raw_height; + + double progress_bar_horizontal_alignment; + double progress_bar_vertical_alignment; + long progress_bar_width; + long progress_bar_height; + uint32_t progress_bar_bg_color; + uint32_t progress_bar_fg_color; + + progress_function_t progress_function; + + ply_trigger_t *idle_trigger; + ply_trigger_t *stop_trigger; + + uint32_t root_is_mounted : 1; + uint32_t is_visible : 1; + uint32_t is_animating : 1; + uint32_t is_idle : 1; + uint32_t use_firmware_background : 1; + uint32_t dialog_clears_firmware_background : 1; + uint32_t message_below_animation : 1; +}; + +ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void); + +static void stop_animation (ply_boot_splash_plugin_t *plugin); +static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin); +static void display_message (ply_boot_splash_plugin_t *plugin, + const char *message); +static void become_idle (ply_boot_splash_plugin_t *plugin, + ply_trigger_t *idle_trigger); +static void view_show_message (view_t *view, const char *message); + +bool is_dir(const char* path) { + struct stat path_stat; + stat(path, &path_stat); + return S_ISDIR(path_stat.st_mode); +} + +void image_get_res(const char *basedir, int *xres, int *yres) +{ + FILE *fp; + char buf[512]; + int oxres, oyres; + + oxres = *xres; + oyres = *yres; + snprintf(buf, 512, "%s/%dx%d.png", basedir, oxres, oyres); + + fp = fopen(buf, "r"); + if (!fp) { + *xres = 1024; + *yres = 768; + unsigned int t, tx, ty, mdist = 0xffffffff; + struct dirent *dent; + DIR *tdir; + + snprintf(buf, 512, "%s", basedir); + tdir = opendir(buf); + if (!tdir) { + *xres = 0; + *yres = 0; + return; + } + while ((dent = readdir(tdir))) { + if (sscanf(dent->d_name, "%dx%d.png", &tx, &ty) != 2) + continue; + + /* We only want configs for resolutions smaller than the current one, + * so that we can actually fit the image on the screen. */ + if (tx >= oxres || ty >= oyres) + continue; + + t = (tx - oxres) * (tx - oxres) + (ty - oyres) * (ty - oyres); + + /* Penalize configs for resolutions with different aspect ratios. */ + if (oxres / oyres != tx / ty) + t *= 10; + + if (t < mdist) { + *xres = tx; + *yres = ty; + mdist = t; + } + } + closedir(tdir); + } else { + fclose(fp); + } +} + +char *detect_image(const char *logo_image, int xres, int yres) { + char *buf; + if(logo_image != NULL) { + if(is_dir(logo_image)) { + image_get_res(logo_image, &xres, &yres); + if(asprintf(&buf, "%s/%dx%d.png", logo_image, xres, yres) != -1) + return buf; + } else { + return strdup (logo_image); + } + } + return NULL; +} + +long +calculate_animation_y(view_t *view, double animation_vertical_alignment, + char *animation_vertical_alignment_type, unsigned long screen_height, long height) +{ + ply_boot_splash_plugin_t *plugin; + plugin = view->plugin; + long y; + if (animation_vertical_alignment_type == NULL) { + y = animation_vertical_alignment * screen_height - height / 2.0; + } else if (strcmp(animation_vertical_alignment_type, + "below_title") == 0) { + y = view->title_area.y + view->title_area.height; + if( y + height >= screen_height) { + y = animation_vertical_alignment * screen_height - height / 2.0; + } else { + y += animation_vertical_alignment * (screen_height - y); + if( animation_vertical_alignment != 0.0) { + y -= height / 2; + } + } + } else if (strcmp(animation_vertical_alignment_type, + "below_watermark") == 0 && view->watermark_image != NULL) { + y = view->watermark_area.y + view->watermark_area.height; + if( y + height >= screen_height) { + y = animation_vertical_alignment * screen_height - height / 2.0; + } else { + y += animation_vertical_alignment * (screen_height - y); + if( animation_vertical_alignment != 0.0) { + y -= height / 2; + } + } + } else { + y = animation_vertical_alignment * screen_height - height / 2.0; + } + return y; +} + +static view_t * +view_new (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) +{ + view_t *view; + + view = calloc (1, sizeof(view_t)); + view->plugin = plugin; + view->display = display; + view->watermark_image = NULL; + + view->entry = ply_entry_new (plugin->animation_dir); + view->keymap_icon = ply_keymap_icon_new (display, plugin->animation_dir); + view->capslock_icon = ply_capslock_icon_new (plugin->animation_dir); + view->progress_animation = ply_progress_animation_new (plugin->animation_dir, + "progress-"); + ply_progress_animation_set_transition (view->progress_animation, + plugin->transition, + plugin->transition_duration); + + view->progress_bar = ply_progress_bar_new (); + ply_progress_bar_set_colors (view->progress_bar, + plugin->progress_bar_fg_color, + plugin->progress_bar_bg_color); + + view->throbber = ply_throbber_new (plugin->animation_dir, + "throbber-"); + + view->label = ply_label_new (); + ply_label_set_font (view->label, plugin->font); + + view->message_label = ply_label_new (); + ply_label_set_font (view->message_label, plugin->font); + + view->title_label = ply_label_new (); + ply_label_set_font (view->title_label, plugin->title_font); + + view->subtitle_label = ply_label_new (); + ply_label_set_font (view->subtitle_label, plugin->font); + + return view; +} + +static void +view_free (view_t *view) +{ + ply_entry_free (view->entry); + ply_keymap_icon_free (view->keymap_icon); + ply_capslock_icon_free (view->capslock_icon); + ply_animation_free (view->end_animation); + ply_progress_animation_free (view->progress_animation); + ply_progress_bar_free (view->progress_bar); + ply_throbber_free (view->throbber); + ply_label_free (view->label); + ply_label_free (view->message_label); + ply_label_free (view->title_label); + ply_label_free (view->subtitle_label); + + if (view->watermark_image != NULL) + ply_image_free (view->watermark_image); + + if (view->background_buffer != NULL) + ply_pixel_buffer_free (view->background_buffer); + + free (view); +} + +static void +view_load_end_animation (view_t *view) +{ + ply_boot_splash_plugin_t *plugin = view->plugin; + const char *animation_prefix; + + if (!plugin->mode_settings[plugin->mode].use_end_animation) + return; + + ply_trace ("loading animation"); + + switch (plugin->mode) { + case PLY_BOOT_SPLASH_MODE_BOOT_UP: + case PLY_BOOT_SPLASH_MODE_UPDATES: + case PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE: + case PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE: + animation_prefix = "startup-animation-"; + break; + case PLY_BOOT_SPLASH_MODE_SHUTDOWN: + case PLY_BOOT_SPLASH_MODE_REBOOT: + animation_prefix = "shutdown-animation-"; + break; + case PLY_BOOT_SPLASH_MODE_INVALID: + default: + ply_trace ("unexpected splash mode 0x%x\n", plugin->mode); + return; + } + + ply_trace ("trying prefix: %s", animation_prefix); + view->end_animation = ply_animation_new (plugin->animation_dir, + animation_prefix); + + if (ply_animation_load (view->end_animation)) + return; + ply_animation_free (view->end_animation); + + ply_trace ("now trying more general prefix: animation-"); + view->end_animation = ply_animation_new (plugin->animation_dir, + "animation-"); + if (ply_animation_load (view->end_animation)) + return; + ply_animation_free (view->end_animation); + + ply_trace ("now trying old compat prefix: throbber-"); + view->end_animation = ply_animation_new (plugin->animation_dir, + "throbber-"); + if (ply_animation_load (view->end_animation)) { + /* files named throbber- are for end animation, so + * there's no throbber */ + ply_throbber_free (view->throbber); + view->throbber = NULL; + return; + } + + ply_trace ("optional animation didn't load"); + ply_animation_free (view->end_animation); + view->end_animation = NULL; + plugin->mode_settings[plugin->mode].use_end_animation = false; +} + +static bool +get_bgrt_sysfs_info(int *x_offset, int *y_offset, + ply_pixel_buffer_rotation_t *rotation) +{ + bool ret = false; + char buf[64]; + int status; + FILE *f; + + f = fopen("/sys/firmware/acpi/bgrt/status", "r"); + if (!f) + return false; + + if (!fgets(buf, sizeof(buf), f)) + goto out; + + if (sscanf(buf, "%d", &status) != 1) + goto out; + + fclose(f); + + switch (status & BGRT_STATUS_ORIENTATION_OFFSET_MASK) { + case BGRT_STATUS_ORIENTATION_OFFSET_0: + *rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; + break; + case BGRT_STATUS_ORIENTATION_OFFSET_90: + *rotation = PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE; + break; + case BGRT_STATUS_ORIENTATION_OFFSET_180: + *rotation = PLY_PIXEL_BUFFER_ROTATE_UPSIDE_DOWN; + break; + case BGRT_STATUS_ORIENTATION_OFFSET_270: + *rotation = PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE; + break; + } + + f = fopen("/sys/firmware/acpi/bgrt/xoffset", "r"); + if (!f) + return false; + + if (!fgets(buf, sizeof(buf), f)) + goto out; + + if (sscanf(buf, "%d", x_offset) != 1) + goto out; + + fclose(f); + + f = fopen("/sys/firmware/acpi/bgrt/yoffset", "r"); + if (!f) + return false; + + if (!fgets(buf, sizeof(buf), f)) + goto out; + + if (sscanf(buf, "%d", y_offset) != 1) + goto out; + + ret = true; +out: + fclose(f); + return ret; +} + +/* The Microsoft boot logo spec says that the logo must use a black background + * and have its center at 38.2% from the screen's top (golden ratio). + * We reproduce this exactly here so that we get a background which is an exact + * match of the firmware's boot splash. + * At the time of writing this comment this is documented in a document called + * "Boot screen components" which is available here: + * https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/boot-screen-components + * Note that we normally do not use the firmware reported x and y-offset as + * that is based on the EFI fb resolution which may not be the native + * resolution of the screen (esp. when using multiple heads). + */ +static void +view_set_bgrt_background (view_t *view) +{ + ply_pixel_buffer_rotation_t panel_rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; + ply_pixel_buffer_rotation_t bgrt_rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; + int x_offset, y_offset, sysfs_x_offset, sysfs_y_offset, width, height; + int panel_width = 0, panel_height = 0, panel_scale = 1; + int screen_width, screen_height, screen_scale; + ply_pixel_buffer_t *bgrt_buffer; + bool have_panel_props; + + if (!view->plugin->background_bgrt_image) + return; + + if (!get_bgrt_sysfs_info(&sysfs_x_offset, &sysfs_y_offset, + &bgrt_rotation)) { + ply_trace ("get bgrt sysfs info failed"); + return; + } + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + screen_scale = ply_pixel_display_get_device_scale (view->display); + + bgrt_buffer = ply_image_get_buffer (view->plugin->background_bgrt_image); + + have_panel_props = ply_renderer_get_panel_properties (ply_pixel_display_get_renderer (view->display), + &panel_width, &panel_height, + &panel_rotation, &panel_scale); + + /* + * Some buggy Lenovo 2-in-1s with a 90 degree rotated panel, behave as + * if the panel is mounted up-right / not rotated at all. These devices + * have a buggy efifb size (landscape resolution instead of the actual + * portrait resolution of the panel), this gets fixed-up by the kernel. + * These buggy devices also do not pre-rotate the bgrt_image nor do + * they set the ACPI-6.2 rotation status-bits. We can detect this by + * checking that the bgrt_image is perfectly centered horizontally + * when we use the panel's height as the width. + */ + if (have_panel_props && + (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE || + panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) && + (panel_width - view->plugin->background_bgrt_raw_width) / 2 != sysfs_x_offset && + (panel_height - view->plugin->background_bgrt_raw_width) / 2 == sysfs_x_offset) + bgrt_rotation = panel_rotation; + + /* + * Before the ACPI 6.2 specification, the BGRT table did not contain + * any rotation information, so to make sure that the firmware-splash + * showed the right way up the firmware would contain a pre-rotated + * image. Starting with ACPI 6.2 the bgrt status fields has 2 bits + * to tell the firmware the image needs to be rotated before being + * displayed. + * If these bits are set then the firmwares-splash is not pre-rotated, + * in this case we must not rotate it when rendering and when doing + * comparisons with the panel-size we must use the post rotation + * panel-size. + */ + if (bgrt_rotation != PLY_PIXEL_BUFFER_ROTATE_UPRIGHT) { + if (bgrt_rotation != panel_rotation) { + ply_trace ("bgrt orientation mismatch, bgrt_rot %d panel_rot %d", (int)bgrt_rotation, (int)panel_rotation); + return; + } + + /* Set panel properties to their post-rotations values */ + if (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE || + panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) { + int temp = panel_width; + panel_width = panel_height; + panel_height = temp; + } + panel_rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; + } + + if (have_panel_props) { + ply_pixel_buffer_set_device_rotation (bgrt_buffer, panel_rotation); + ply_pixel_buffer_set_device_scale (bgrt_buffer, panel_scale); + } + + width = ply_pixel_buffer_get_width (bgrt_buffer); + height = ply_pixel_buffer_get_height (bgrt_buffer); + + x_offset = (screen_width - width) / 2; + y_offset = screen_height * 382 / 1000 - height / 2; + + /* + * On laptops / tablets the LCD panel is typically brought up in + * its native resolution, so we can trust the x- and y-offset values + * provided by the firmware to be correct for a screen with the panels + * resolution. + * + * Moreover some laptop / tablet firmwares to do all kind of hacks wrt + * the y offset. This happens especially on devices where the panel is + * mounted 90 degrees rotated, but also on other devices. + * + * So on devices with an internal LCD panel, we prefer to use the + * firmware provided offsets, to make sure we match its quirky behavior. + * + * We check that the x-offset matches what we expect for the panel's + * native resolution to make sure that the values are indeed for the + * panel's native resolution and then we correct for any difference + * between the (external) screen's and the panel's resolution. + */ + if (have_panel_props && + (panel_width - view->plugin->background_bgrt_raw_width) / 2 == sysfs_x_offset) { + if (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_CLOCKWISE || + panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) { + /* + * For left side up panels the y_offset is from the + * right side of the image once rotated upright (the + * top of the physicial LCD panel is on the right side). + * Our coordinates have the left side as 0, so we need + * to "flip" the y_offset in this case. + */ + if (panel_rotation == PLY_PIXEL_BUFFER_ROTATE_COUNTER_CLOCKWISE) + sysfs_y_offset = panel_height - view->plugin->background_bgrt_raw_height - sysfs_y_offset; + + /* 90 degrees rotated, swap x and y */ + x_offset = sysfs_y_offset / panel_scale; + y_offset = sysfs_x_offset / panel_scale; + + x_offset += (screen_width - panel_height / panel_scale) / 2; + y_offset += (screen_height - panel_width / panel_scale) * 382 / 1000; + } else { + /* Normal orientation */ + x_offset = sysfs_x_offset / panel_scale; + y_offset = sysfs_y_offset / panel_scale; + + x_offset += (screen_width - panel_width / panel_scale) / 2; + y_offset += (screen_height - panel_height / panel_scale) * 382 / 1000; + } + } + + /* + * On desktops (no panel) we normally do not use the BGRT provided + * xoffset and yoffset because the resolution they are intended for + * may be differtent then the resolution of the current display. + * + * On some desktops (no panel) the image gets centered not only + * horizontally, but also vertically. In this case our default of using + * the golden ratio for the vertical position causes the BGRT image + * to jump. To avoid this we check here if the provided xoffset and + * yoffset perfectly center the image and in that case we use them. + */ + if (!have_panel_props && screen_scale == 1 && + (screen_width - width ) / 2 == sysfs_x_offset && + (screen_height - height) / 2 == sysfs_y_offset) { + x_offset = sysfs_x_offset; + y_offset = sysfs_y_offset; + } + + ply_trace ("using %dx%d bgrt image centered at %dx%d for %dx%d screen", + width, height, x_offset, y_offset, screen_width, screen_height); + + view->background_buffer = ply_pixel_buffer_new (screen_width * screen_scale, screen_height * screen_scale); + ply_pixel_buffer_set_device_scale (view->background_buffer, screen_scale); + ply_pixel_buffer_fill_with_hex_color (view->background_buffer, NULL, 0x000000); + if (x_offset >= 0 && y_offset >= 0) { + bgrt_buffer = ply_pixel_buffer_rotate_upright (bgrt_buffer); + ply_pixel_buffer_fill_with_buffer (view->background_buffer, bgrt_buffer, x_offset, y_offset); + ply_pixel_buffer_free (bgrt_buffer); + } +} + +static bool +view_load (view_t *view) +{ + unsigned long x, y, width, title_height = 0, subtitle_height = 0; + unsigned long screen_width, screen_height, screen_scale; + char *image_dir, *image_path; + ply_boot_splash_plugin_t *plugin; + ply_pixel_buffer_t *buffer; + + plugin = view->plugin; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + buffer = ply_renderer_get_buffer_for_head( + ply_pixel_display_get_renderer (view->display), + ply_pixel_display_get_renderer_head (view->display)); + screen_scale = ply_pixel_buffer_get_device_scale (buffer); + + view_set_bgrt_background (view); + + if (!view->background_buffer && plugin->background_tile_image != NULL) { + ply_trace ("tiling background to %lux%lu", screen_width, screen_height); + + /* Create a buffer at screen scale so that we only do the slow interpolating scale once */ + view->background_buffer = ply_pixel_buffer_new (screen_width * screen_scale, screen_height * screen_scale); + ply_pixel_buffer_set_device_scale (view->background_buffer, screen_scale); + + if (plugin->background_start_color != plugin->background_end_color) + ply_pixel_buffer_fill_with_gradient (view->background_buffer, NULL, + plugin->background_start_color, + plugin->background_end_color); + else + ply_pixel_buffer_fill_with_hex_color (view->background_buffer, NULL, + plugin->background_start_color); + + buffer = ply_pixel_buffer_tile (ply_image_get_buffer (plugin->background_tile_image), screen_width, screen_height); + ply_pixel_buffer_fill_with_buffer (view->background_buffer, buffer, 0, 0); + ply_pixel_buffer_free (buffer); + } + + if (view->watermark_image == NULL && plugin->mode_settings[plugin->mode].watermark_imagename) { + image_path = detect_image(plugin->mode_settings[plugin->mode].watermark_imagename, + screen_width, screen_height); + ply_trace ("assing watermark %s", image_path); + view->watermark_image = ply_image_new (image_path); + free (image_path); + } + if (view->watermark_image != NULL) { + ply_trace ("loading watermark image"); + if (!ply_image_load (view->watermark_image)) { + ply_image_free (view->watermark_image); + view->watermark_image = NULL; + } + } + + if (view->watermark_image != NULL) { + view->watermark_area.width = ply_image_get_width (view->watermark_image); + view->watermark_area.height = ply_image_get_height (view->watermark_image); + view->watermark_area.x = screen_width * plugin->watermark_horizontal_alignment - ply_image_get_width (view->watermark_image) * plugin->watermark_horizontal_alignment; + view->watermark_area.y = screen_height * plugin->watermark_vertical_alignment - ply_image_get_height (view->watermark_image) * plugin->watermark_vertical_alignment; + ply_trace ("using %ldx%ld watermark centered at %ldx%ld for %ldx%ld screen", + view->watermark_area.width, view->watermark_area.height, + view->watermark_area.x, view->watermark_area.y, + screen_width, screen_height); + } + + ply_trace ("loading entry"); + if (!ply_entry_load (view->entry)) + return false; + + ply_keymap_icon_load (view->keymap_icon); + ply_capslock_icon_load (view->capslock_icon); + + view_load_end_animation (view); + + if (view->progress_animation != NULL) { + ply_trace ("loading progress animation"); + if (!ply_progress_animation_load (view->progress_animation)) { + ply_trace ("optional progress animation wouldn't load"); + ply_progress_animation_free (view->progress_animation); + view->progress_animation = NULL; + } + } else { + ply_trace ("this theme has no progress animation"); + } + + if (view->throbber != NULL) { + ply_trace ("loading throbber"); + if (!ply_throbber_load (view->throbber)) { + ply_trace ("optional throbber was not loaded"); + ply_throbber_free (view->throbber); + view->throbber = NULL; + } + } else { + ply_trace ("this theme has no throbber\n"); + } + + if (plugin->mode_settings[plugin->mode].title) { + ply_label_set_text (view->title_label, + _(plugin->mode_settings[plugin->mode].title)); + title_height = ply_label_get_height (view->title_label); + } else { + ply_label_hide (view->title_label); + } + + if (plugin->mode_settings[plugin->mode].subtitle) { + ply_label_set_text (view->subtitle_label, + _(plugin->mode_settings[plugin->mode].subtitle)); + subtitle_height = ply_label_get_height (view->subtitle_label); + } else { + ply_label_hide (view->subtitle_label); + } + + y = (screen_height - title_height - 2 * subtitle_height) * plugin->title_vertical_alignment; + + view->title_area.width = 0; + view->title_area.height = 0; + view->title_area.x = -1; + view->title_area.y = 0; + if (plugin->mode_settings[plugin->mode].title) { + width = ply_label_get_width (view->title_label); + x = (screen_width - width) * plugin->title_horizontal_alignment; + ply_trace ("using %ldx%ld title centered at %ldx%ld for %ldx%ld screen", + width, title_height, x, y, screen_width, screen_height); + ply_label_show (view->title_label, view->display, x, y); + view->title_area.width = width; + view->title_area.height = 2 * title_height; + view->title_area.x = x; + view->title_area.y = y; + + /* Use subtitle_height pixels seperation between title and subtitle */ + y += title_height + subtitle_height; + } + + if (plugin->mode_settings[plugin->mode].subtitle) { + width = ply_label_get_width (view->subtitle_label); + x = (screen_width - width) * plugin->title_horizontal_alignment; + ply_trace ("using %ldx%ld subtitle centered at %ldx%ld for %ldx%ld screen", + width, subtitle_height, x, y, screen_width, screen_height); + ply_label_show (view->subtitle_label, view->display, x, y); + if( x == -1 || x < view->title_area.x ) { + view->title_area.x = x; + } + if( width > view->title_area.width ) { + view->title_area.width = width; + } + if (view->title_area.height != 0) { + view->title_area.height = title_height + subtitle_height + subtitle_height * 2; + } else { + view->title_area.height = subtitle_height * 2; + } + } + uint32_t title_color = 0xff00ff; + title_color = plugin->mode_settings[plugin->mode].title_color; + + if(view->title_label) { + ply_label_set_color(view->title_label, + ((title_color >> 16) & 0xff) / 255.0f, + ((title_color >> 8) & 0xff) / 255.0f, + (title_color & 0xff) / 255.0f, + 1.0f); + ply_label_set_color(view->subtitle_label, + ((title_color >> 16) & 0xff) / 255.0f, + ((title_color >> 8) & 0xff) / 255.0f, + (title_color & 0xff) / 255.0f, + 1.0f); + } + + return true; +} + +static bool +load_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + bool view_loaded; + view_t *view; + + view_loaded = false; + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) { + view = ply_list_node_get_data (node); + + if (view_load (view)) + view_loaded = true; + + node = ply_list_get_next_node (plugin->views, node); + } + + return view_loaded; +} + +static void +view_redraw (view_t *view) +{ + unsigned long screen_width, screen_height; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + ply_pixel_display_draw_area (view->display, 0, 0, + screen_width, screen_height); +} + +static void +redraw_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + view_t *view; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + view_redraw (view); + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +pause_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + view_t *view; + + ply_trace ("pausing views"); + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + ply_pixel_display_pause_updates (view->display); + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +unpause_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + view_t *view; + + ply_trace ("unpausing views"); + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + ply_pixel_display_unpause_updates (view->display); + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +view_start_end_animation (view_t *view, + ply_trigger_t *trigger) +{ + ply_boot_splash_plugin_t *plugin = view->plugin; + unsigned long screen_width, screen_height; + long x, y, width, height; + + ply_progress_bar_hide (view->progress_bar); + if (view->progress_animation != NULL) + ply_progress_animation_hide (view->progress_animation); + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + width = ply_animation_get_width (view->end_animation); + height = ply_animation_get_height (view->end_animation); + x = plugin->mode_settings[plugin->mode].animation_horizontal_alignment * screen_width - width / 2.0; + y = calculate_animation_y(view, + plugin->mode_settings[plugin->mode].animation_vertical_alignment, + plugin->mode_settings[plugin->mode].animation_vertical_alignment_type, + screen_height, height); + + ply_trace ("starting end sequence animation for %ldx%ld view", width, height); + ply_animation_start (view->end_animation, + view->display, + trigger, x, y); + view->animation_bottom = y + height; +} + +static void +on_view_throbber_stopped (view_t *view) +{ + view_start_end_animation (view, view->end_trigger); + view->end_trigger = NULL; +} + +static void +view_start_progress_animation (view_t *view) +{ + ply_boot_splash_plugin_t *plugin; + + long x, y; + long width, height; + unsigned long screen_width, screen_height; + + assert (view != NULL); + + plugin = view->plugin; + + plugin->is_idle = false; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + ply_pixel_display_draw_area (view->display, 0, 0, + screen_width, screen_height); + + if (plugin->mode_settings[plugin->mode].use_progress_bar) { + if (plugin->progress_bar_width != -1) + width = plugin->progress_bar_width; + else + width = screen_width; + height = plugin->progress_bar_height; + x = plugin->progress_bar_horizontal_alignment * (screen_width - width); + //y = plugin->progress_bar_vertical_alignment * (screen_height - height); + y = calculate_animation_y(view, + plugin->progress_bar_vertical_alignment, + plugin->mode_settings[plugin->mode].animation_vertical_alignment_type, + screen_height, height); + ply_progress_bar_show (view->progress_bar, view->display, + x, y, width, height); + ply_pixel_display_draw_area (view->display, x, y, width, height); + view->animation_bottom = y + height; + } + + if (plugin->mode_settings[plugin->mode].use_animation && + view->throbber != NULL) { + width = ply_throbber_get_width (view->throbber); + height = ply_throbber_get_height (view->throbber); + x = plugin->mode_settings[plugin->mode].animation_horizontal_alignment * screen_width - width / 2.0; + + y = calculate_animation_y(view, + plugin->mode_settings[plugin->mode].animation_vertical_alignment, + plugin->mode_settings[plugin->mode].animation_vertical_alignment_type, + screen_height, height); + ply_throbber_start (view->throbber, + plugin->loop, + view->display, x, y); + ply_pixel_display_draw_area (view->display, x, y, width, height); + view->animation_bottom = y + height; + } + + /* We don't really know how long shutdown will so + * don't show the progress animation + */ + if (plugin->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN || + plugin->mode == PLY_BOOT_SPLASH_MODE_REBOOT) + return; + + if (plugin->mode_settings[plugin->mode].use_animation && + view->progress_animation != NULL) { + width = ply_progress_animation_get_width (view->progress_animation); + height = ply_progress_animation_get_height (view->progress_animation); + x = plugin->mode_settings[plugin->mode].animation_horizontal_alignment * screen_width - width / 2.0; + y = calculate_animation_y(view, + plugin->mode_settings[plugin->mode].animation_vertical_alignment, + plugin->mode_settings[plugin->mode].animation_vertical_alignment_type, + screen_height, height); + ply_progress_animation_show (view->progress_animation, + view->display, x, y); + + ply_pixel_display_draw_area (view->display, x, y, width, height); + view->animation_bottom = y + height; + } +} + +static void +view_show_prompt (view_t *view, + const char *prompt, + const char *entry_text, + int number_of_bullets) +{ + ply_boot_splash_plugin_t *plugin; + unsigned long screen_width, screen_height, entry_width, entry_height; + unsigned long keyboard_indicator_width, keyboard_indicator_height; + bool show_keyboard_indicators = false; + long dialog_bottom; + int x, y; + + assert (view != NULL); + + plugin = view->plugin; + + screen_width = ply_pixel_display_get_width (view->display); + screen_height = ply_pixel_display_get_height (view->display); + + if (ply_entry_is_hidden (view->entry)) { + view->lock_area.width = ply_image_get_width (plugin->lock_image); + view->lock_area.height = ply_image_get_height (plugin->lock_image); + + entry_width = ply_entry_get_width (view->entry); + entry_height = ply_entry_get_height (view->entry); + + if (plugin->box_image) { + view->box_area.width = ply_image_get_width (plugin->box_image); + view->box_area.height = ply_image_get_height (plugin->box_image); + view->box_area.x = (screen_width - view->box_area.width) * plugin->dialog_horizontal_alignment; + view->box_area.y = (screen_height - view->box_area.height) * plugin->dialog_vertical_alignment; + view->dialog_area = view->box_area; + } else { + view->dialog_area.width = view->lock_area.width + entry_width; + view->dialog_area.height = MAX(view->lock_area.height, entry_height); + view->dialog_area.x = (screen_width - view->dialog_area.width) * plugin->dialog_horizontal_alignment; + view->dialog_area.y = (screen_height - view->dialog_area.height) * plugin->dialog_vertical_alignment; + } + + view->lock_area.x = + view->dialog_area.x + + (view->dialog_area.width - + (view->lock_area.width + entry_width)) / 2.0; + view->lock_area.y = + view->dialog_area.y + + (view->dialog_area.height - view->lock_area.height) / 2.0; + + x = view->lock_area.x + view->lock_area.width; + y = view->dialog_area.y + + (view->dialog_area.height - entry_height) / 2.0; + + ply_entry_show (view->entry, plugin->loop, view->display, x, y); + + show_keyboard_indicators = true; + } + + if (entry_text != NULL) + ply_entry_set_text (view->entry, entry_text); + + if (number_of_bullets != -1) + ply_entry_set_bullet_count (view->entry, number_of_bullets); + + dialog_bottom = view->dialog_area.y + view->dialog_area.height; + + if (prompt != NULL) { + ply_label_set_text (view->label, prompt); + + /* We center the prompt in the middle and use 80% of the horizontal space */ + int label_width = screen_width * 100 / 80; + ply_label_set_alignment (view->label, PLY_LABEL_ALIGN_CENTER); + ply_label_set_width (view->label, label_width); + + x = (screen_width - label_width) / 2; + y = dialog_bottom; + + ply_label_show (view->label, view->display, x, y); + + dialog_bottom += ply_label_get_height (view->label); + } + + if (show_keyboard_indicators) { + keyboard_indicator_width = + ply_keymap_icon_get_width (view->keymap_icon); + keyboard_indicator_height = MAX( + ply_capslock_icon_get_height (view->capslock_icon), + ply_keymap_icon_get_height (view->keymap_icon)); + + x = (screen_width - keyboard_indicator_width) * plugin->dialog_horizontal_alignment; + y = dialog_bottom + keyboard_indicator_height / 2 + + (keyboard_indicator_height - ply_keymap_icon_get_height (view->keymap_icon)) / 2.0; + ply_keymap_icon_show (view->keymap_icon, x, y); + + x += ply_keymap_icon_get_width (view->keymap_icon); + y = dialog_bottom + keyboard_indicator_height / 2 + + (keyboard_indicator_height - ply_capslock_icon_get_height (view->capslock_icon)) / 2.0; + ply_capslock_icon_show (view->capslock_icon, plugin->loop, view->display, x, y); + } +} + +static void +view_hide_prompt (view_t *view) +{ + assert (view != NULL); + + ply_entry_hide (view->entry); + ply_capslock_icon_hide (view->capslock_icon); + ply_keymap_icon_hide (view->keymap_icon); + ply_label_hide (view->label); +} + +static void +load_mode_settings (ply_boot_splash_plugin_t *plugin, + ply_key_file_t *key_file, + const char *group_name, + ply_boot_splash_mode_t mode) +{ + mode_settings_t *settings = &plugin->mode_settings[mode]; + + settings->suppress_messages = + ply_key_file_get_bool (key_file, group_name, "SuppressMessages"); + settings->progress_bar_show_percent_complete = + ply_key_file_get_bool (key_file, group_name, "ProgressBarShowPercentComplete"); + settings->use_progress_bar = + ply_key_file_get_bool (key_file, group_name, "UseProgressBar"); + settings->use_firmware_background = + ply_key_file_get_bool (key_file, group_name, "UseFirmwareBackground"); + + /* This defaults to !use_progress_bar for compat. with older themes */ + if (ply_key_file_has_key (key_file, group_name, "UseAnimation")) + settings->use_animation = + ply_key_file_get_bool (key_file, group_name, "UseAnimation"); + else + settings->use_animation = !settings->use_progress_bar; + + /* This defaults to true for compat. with older themes */ + if (ply_key_file_has_key (key_file, group_name, "UseEndAnimation")) + settings->use_end_animation = + ply_key_file_get_bool (key_file, group_name, "UseEndAnimation"); + else + settings->use_end_animation = true; + + /* If any mode uses the firmware background, then we need to load it */ + if (settings->use_firmware_background) + plugin->use_firmware_background = true; + + settings->watermark_imagename = ply_key_file_get_value (key_file, group_name, "WatermarkImage"); + if( settings->watermark_imagename == NULL && + plugin->watermark_imagename != NULL ) + settings->watermark_imagename = strdup(plugin->watermark_imagename); + + settings->title = ply_key_file_get_value (key_file, group_name, "Title"); + settings->subtitle = ply_key_file_get_value (key_file, group_name, "SubTitle"); + + settings->title_color = ply_key_file_get_long (key_file, group_name, "TitleColor", + plugin->title_color); + + settings->background_start_color = + ply_key_file_get_long (key_file, group_name, + "BackgroundStartColor", + plugin->background_start_color); + settings->background_end_color = + ply_key_file_get_long (key_file, group_name, + "BackgroundEndColor", + plugin->background_end_color); + + /* Throbber, progress- and end-animation alignment */ + settings->animation_horizontal_alignment = + ply_key_file_get_double (key_file, group_name, + "HorizontalAlignment", plugin->animation_horizontal_alignment); + settings->animation_vertical_alignment = + ply_key_file_get_double (key_file, group_name, + "VerticalAlignment", plugin->animation_vertical_alignment); + settings->animation_vertical_alignment_type = + ply_key_file_get_value (key_file, group_name, + "VerticalAlignmentType"); + if( settings->animation_vertical_alignment_type == NULL && + plugin->animation_vertical_alignment_type != NULL ) + settings->animation_vertical_alignment_type = strdup(plugin->animation_vertical_alignment_type); +} + +static ply_boot_splash_plugin_t * +create_plugin (ply_key_file_t *key_file) +{ + ply_boot_splash_plugin_t *plugin; + char *image_dir, *image_path; + char *transition; + char *progress_function; + + srand ((int) ply_get_timestamp ()); + plugin = calloc (1, sizeof(ply_boot_splash_plugin_t)); + + image_dir = ply_key_file_get_value (key_file, "calculate", "ImageDir"); + + ply_trace ("Using '%s' as working directory", image_dir); + + asprintf (&image_path, "%s/lock.png", image_dir); + plugin->lock_image = ply_image_new (image_path); + free (image_path); + + asprintf (&image_path, "%s/box.png", image_dir); + plugin->box_image = ply_image_new (image_path); + free (image_path); + + asprintf (&image_path, "%s/corner-image.png", image_dir); + plugin->corner_image = ply_image_new (image_path); + free (image_path); + + asprintf (&image_path, "%s/header-image.png", image_dir); + plugin->header_image = ply_image_new (image_path); + free (image_path); + + asprintf (&image_path, "%s/background-tile.png", image_dir); + plugin->background_tile_image = ply_image_new (image_path); + free (image_path); + + plugin->animation_dir = image_dir; + + plugin->font = ply_key_file_get_value (key_file, "calculate", "Font"); + plugin->title_font = ply_key_file_get_value (key_file, "calculate", "TitleFont"); + + /* Throbber, progress- and end-animation alignment */ + plugin->animation_horizontal_alignment = + ply_key_file_get_double (key_file, "calculate", + "HorizontalAlignment", 0.5); + plugin->animation_vertical_alignment = + ply_key_file_get_double (key_file, "calculate", + "VerticalAlignment", 0.5); + plugin->animation_vertical_alignment_type = + ply_key_file_get_value (key_file, "calculate", + "VerticalAlignmentType"); + + /* Progressbar alignment, this defaults to the animation alignment + * for compatibility with older themes. + */ + plugin->progress_bar_horizontal_alignment = + ply_key_file_get_double (key_file, "calculate", + "ProgressBarHorizontalAlignment", + plugin->animation_horizontal_alignment); + plugin->progress_bar_vertical_alignment = + ply_key_file_get_double (key_file, "calculate", + "ProgressBarVerticalAlignment", + plugin->animation_vertical_alignment); + + /* Watermark alignment */ + plugin->watermark_horizontal_alignment = + ply_key_file_get_double (key_file, "calculate", + "WatermarkHorizontalAlignment", 1.0); + plugin->watermark_vertical_alignment = + ply_key_file_get_double (key_file, "calculate", + "WatermarkVerticalAlignment", 0.5); + + /* Password (or other) dialog alignment */ + plugin->dialog_horizontal_alignment = + ply_key_file_get_double (key_file, "calculate", + "DialogHorizontalAlignment", 0.5); + plugin->dialog_vertical_alignment = + ply_key_file_get_double (key_file, "calculate", + "DialogVerticalAlignment", 0.5); + + /* Title alignment */ + plugin->title_horizontal_alignment = + ply_key_file_get_double (key_file, "calculate", + "TitleHorizontalAlignment", 0.5); + plugin->title_vertical_alignment = + ply_key_file_get_double (key_file, "calculate", + "TitleVerticalAlignment", 0.5); + + plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_NONE; + transition = ply_key_file_get_value (key_file, "calculate", "Transition"); + if (transition != NULL) { + if (strcmp (transition, "fade-over") == 0) + plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER; + else if (strcmp (transition, "cross-fade") == 0) + plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE; + else if (strcmp (transition, "merge-fade") == 0) + plugin->transition = PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE; + } + free (transition); + + plugin->transition_duration = + ply_key_file_get_double (key_file, "calculate", + "TransitionDuration", 0.0); + + plugin->background_start_color = + ply_key_file_get_long (key_file, "calculate", + "BackgroundStartColor", + PLYMOUTH_BACKGROUND_START_COLOR); + plugin->background_end_color = + ply_key_file_get_long (key_file, "calculate", + "BackgroundEndColor", + PLYMOUTH_BACKGROUND_END_COLOR); + plugin->title_color = ply_key_file_get_long ( + key_file, "calculate", "TitleColor", 0xffffff); + + plugin->progress_bar_bg_color = + ply_key_file_get_long (key_file, "calculate", + "ProgressBarBackgroundColor", + 0xffffff /* white */); + plugin->progress_bar_fg_color = + ply_key_file_get_long (key_file, "calculate", + "ProgressBarForegroundColor", + 0x000000 /* black */); + plugin->progress_bar_width = + ply_key_file_get_long (key_file, "calculate", + "ProgressBarWidth", + PROGRESS_BAR_WIDTH); + plugin->progress_bar_height = + ply_key_file_get_long (key_file, "calculate", + "ProgressBarHeight", + PROGRESS_BAR_HEIGHT); + + plugin->watermark_imagename = ply_key_file_get_value (key_file, "calculate", "WatermarkImage"); + + load_mode_settings (plugin, key_file, "boot-up", PLY_BOOT_SPLASH_MODE_BOOT_UP); + load_mode_settings (plugin, key_file, "shutdown", PLY_BOOT_SPLASH_MODE_SHUTDOWN); + load_mode_settings (plugin, key_file, "reboot", PLY_BOOT_SPLASH_MODE_REBOOT); + load_mode_settings (plugin, key_file, "updates", PLY_BOOT_SPLASH_MODE_UPDATES); + load_mode_settings (plugin, key_file, "system-upgrade", PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE); + load_mode_settings (plugin, key_file, "firmware-upgrade", PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE); + + if (plugin->use_firmware_background) + plugin->background_bgrt_image = ply_image_new ("/sys/firmware/acpi/bgrt/image"); + + plugin->dialog_clears_firmware_background = + ply_key_file_get_bool (key_file, "calculate", "DialogClearsFirmwareBackground"); + + plugin->message_below_animation = + ply_key_file_get_bool (key_file, "calculate", "MessageBelowAnimation"); + + progress_function = ply_key_file_get_value (key_file, "calculate", "ProgressFunction"); + + if (progress_function != NULL) { + if (strcmp (progress_function, "wwoods") == 0) { + ply_trace ("Using wwoods progress function"); + plugin->progress_function = PROGRESS_FUNCTION_TYPE_WWOODS; + } else if (strcmp (progress_function, "linear") == 0) { + ply_trace ("Using linear progress function"); + plugin->progress_function = PROGRESS_FUNCTION_TYPE_LINEAR; + } else { + ply_trace ("unknown progress function %s, defaulting to linear", progress_function); + plugin->progress_function = PROGRESS_FUNCTION_TYPE_LINEAR; + } + + free (progress_function); + } + + plugin->views = ply_list_new (); + + return plugin; +} + +static void +free_views (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + + ply_trace ("freeing views"); + + node = ply_list_get_first_node (plugin->views); + + while (node != NULL) { + ply_list_node_t *next_node; + view_t *view; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + view_free (view); + ply_list_remove_node (plugin->views, node); + + node = next_node; + } + + ply_list_free (plugin->views); + plugin->views = NULL; +} + +static void +destroy_plugin (ply_boot_splash_plugin_t *plugin) +{ + int i; + + if (plugin == NULL) + return; + + ply_trace ("destroying plugin"); + + if (plugin->loop != NULL) { + stop_animation (plugin); + + ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + detach_from_event_loop (plugin); + } + + ply_image_free (plugin->lock_image); + + if (plugin->box_image != NULL) + ply_image_free (plugin->box_image); + + if (plugin->corner_image != NULL) + ply_image_free (plugin->corner_image); + + if (plugin->header_image != NULL) + ply_image_free (plugin->header_image); + + if (plugin->background_tile_image != NULL) + ply_image_free (plugin->background_tile_image); + + if (plugin->background_bgrt_image != NULL) + ply_image_free (plugin->background_bgrt_image); + + for (i = 0; i < PLY_BOOT_SPLASH_MODE_COUNT; i++) { + free (plugin->mode_settings[i].title); + free (plugin->mode_settings[i].watermark_imagename); + free (plugin->mode_settings[i].subtitle); + free (plugin->mode_settings[i].animation_vertical_alignment_type); + } + + free (plugin->font); + free (plugin->title_font); + free (plugin->animation_vertical_alignment_type); + free (plugin->animation_dir); + free (plugin->watermark_imagename); + free_views (plugin); + free (plugin); +} + +static void +start_end_animation (ply_boot_splash_plugin_t *plugin, + ply_trigger_t *trigger) +{ + ply_list_node_t *node; + view_t *view; + + if (!plugin->mode_settings[plugin->mode].use_animation) { + ply_trigger_pull (trigger, NULL); + return; + } + + if (!plugin->mode_settings[plugin->mode].use_end_animation) { + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + + ply_progress_bar_hide (view->progress_bar); + + if (view->throbber != NULL) + ply_throbber_stop (view->throbber, NULL); + + if (view->progress_animation != NULL) + ply_progress_animation_hide (view->progress_animation); + + node = ply_list_get_next_node (plugin->views, node); + } + ply_trigger_pull (trigger, NULL); + return; + } + + ply_trace ("starting end animation"); + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + + ply_trigger_ignore_next_pull (trigger); + + if (view->throbber != NULL) { + ply_trigger_t *throbber_trigger; + ply_trace ("stopping throbber"); + view->end_trigger = trigger; + throbber_trigger = ply_trigger_new (NULL); + ply_trigger_add_handler (throbber_trigger, + (ply_trigger_handler_t) + on_view_throbber_stopped, + view); + ply_throbber_stop (view->throbber, throbber_trigger); + } else { + view_start_end_animation (view, trigger); + } + + node = ply_list_get_next_node (plugin->views, node); + } + ply_trigger_pull (trigger, NULL); +} + +static void +start_progress_animation (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + view_t *view; + + if (plugin->is_animating) + return; + + ply_trace ("starting animation"); + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + view_start_progress_animation (view); + node = ply_list_get_next_node (plugin->views, node); + } + + plugin->is_animating = true; + + /* We don't really know how long shutdown will, take + * but it's normally really fast, so just jump to + * the end animation + */ + if (plugin->mode_settings[plugin->mode].use_end_animation && + (plugin->mode == PLY_BOOT_SPLASH_MODE_SHUTDOWN || + plugin->mode == PLY_BOOT_SPLASH_MODE_REBOOT)) + become_idle (plugin, NULL); +} + +static void +stop_animation (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + view_t *view; + + assert (plugin != NULL); + assert (plugin->loop != NULL); + + if (!plugin->is_animating) + return; + + ply_trace ("stopping animation"); + plugin->is_animating = false; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + + ply_progress_bar_hide (view->progress_bar); + if (view->progress_animation != NULL) + ply_progress_animation_hide (view->progress_animation); + if (view->throbber != NULL) + ply_throbber_stop (view->throbber, NULL); + if (view->end_animation != NULL) + ply_animation_stop (view->end_animation); + + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +detach_from_event_loop (ply_boot_splash_plugin_t *plugin) +{ + plugin->loop = NULL; +} + +static void +draw_background (view_t *view, + ply_pixel_buffer_t *pixel_buffer, + int x, + int y, + int width, + int height) +{ + ply_boot_splash_plugin_t *plugin; + ply_rectangle_t area; + bool use_black_background = false; + + plugin = view->plugin; + + area.x = x; + area.y = y; + area.width = width; + area.height = height; + + /* When using the firmware logo as background and we should not use + * it for this mode, use solid black as background. + */ + if (plugin->background_bgrt_image && + !plugin->mode_settings[plugin->mode].use_firmware_background) + use_black_background = true; + + /* When using the firmware logo as background, use solid black as + * background for dialogs. + */ + if ((plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY || + plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY) && + plugin->background_bgrt_image && plugin->dialog_clears_firmware_background) + use_black_background = true; + + if (use_black_background) + ply_pixel_buffer_fill_with_hex_color (pixel_buffer, &area, 0); + else if (view->background_buffer != NULL) + ply_pixel_buffer_fill_with_buffer (pixel_buffer, view->background_buffer, 0, 0); + else if (plugin->mode_settings[plugin->mode].background_start_color != plugin->mode_settings[plugin->mode].background_end_color) + ply_pixel_buffer_fill_with_gradient (pixel_buffer, &area, + plugin->mode_settings[plugin->mode].background_start_color, + plugin->mode_settings[plugin->mode].background_end_color); + else + ply_pixel_buffer_fill_with_hex_color (pixel_buffer, &area, + plugin->mode_settings[plugin->mode].background_start_color); + + if (view->watermark_image != NULL) { + uint32_t *data; + + data = ply_image_get_data (view->watermark_image); + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &view->watermark_area, data); + } +} + +static void +on_draw (view_t *view, + ply_pixel_buffer_t *pixel_buffer, + int x, + int y, + int width, + int height) +{ + ply_boot_splash_plugin_t *plugin; + ply_rectangle_t screen_area; + ply_rectangle_t image_area; + + plugin = view->plugin; + + draw_background (view, pixel_buffer, x, y, width, height); + + ply_pixel_buffer_get_size (pixel_buffer, &screen_area); + + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY || + plugin->state == PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY) { + uint32_t *box_data, *lock_data; + + if (plugin->box_image) { + box_data = ply_image_get_data (plugin->box_image); + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, + &view->box_area, + box_data); + } + + ply_entry_draw_area (view->entry, + pixel_buffer, + x, y, width, height); + ply_keymap_icon_draw_area (view->keymap_icon, + pixel_buffer, + x, y, width, height); + ply_capslock_icon_draw_area (view->capslock_icon, + pixel_buffer, + x, y, width, height); + ply_label_draw_area (view->label, + pixel_buffer, + x, y, width, height); + + lock_data = ply_image_get_data (plugin->lock_image); + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, + &view->lock_area, + lock_data); + } else { + if (plugin->mode_settings[plugin->mode].use_progress_bar) + ply_progress_bar_draw_area (view->progress_bar, pixel_buffer, + x, y, width, height); + + if (plugin->mode_settings[plugin->mode].use_animation && + view->throbber != NULL) + ply_throbber_draw_area (view->throbber, pixel_buffer, + x, y, width, height); + + if (plugin->mode_settings[plugin->mode].use_animation && + view->progress_animation != NULL) + ply_progress_animation_draw_area (view->progress_animation, + pixel_buffer, + x, y, width, height); + + if (plugin->mode_settings[plugin->mode].use_animation && + view->end_animation != NULL) + ply_animation_draw_area (view->end_animation, + pixel_buffer, + x, y, width, height); + + if (plugin->corner_image != NULL) { + image_area.width = ply_image_get_width (plugin->corner_image); + image_area.height = ply_image_get_height (plugin->corner_image); + image_area.x = screen_area.width - image_area.width - 20; + image_area.y = screen_area.height - image_area.height - 20; + + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &image_area, ply_image_get_data (plugin->corner_image)); + } + + if (plugin->header_image != NULL) { + long sprite_height; + + + if (view->progress_animation != NULL) + sprite_height = ply_progress_animation_get_height (view->progress_animation); + else + sprite_height = 0; + + if (view->throbber != NULL) + sprite_height = MAX (ply_throbber_get_height (view->throbber), + sprite_height); + + image_area.width = ply_image_get_width (plugin->header_image); + image_area.height = ply_image_get_height (plugin->header_image); + image_area.x = screen_area.width / 2.0 - image_area.width / 2.0; + image_area.y = plugin->mode_settings[plugin->mode].animation_vertical_alignment * screen_area.height - sprite_height / 2.0 - image_area.height; + + + ply_pixel_buffer_fill_with_argb32_data (pixel_buffer, &image_area, ply_image_get_data (plugin->header_image)); + } + ply_label_draw_area (view->title_label, + pixel_buffer, + x, y, width, height); + ply_label_draw_area (view->subtitle_label, + pixel_buffer, + x, y, width, height); + } + ply_label_draw_area (view->message_label, + pixel_buffer, + x, y, width, height); +} + +static void +add_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) +{ + view_t *view; + + ply_trace ("adding pixel display to plugin"); + view = view_new (plugin, display); + + ply_pixel_display_set_draw_handler (view->display, + (ply_pixel_display_draw_handler_t) + on_draw, view); + if (plugin->is_visible) { + if (view_load (view)) { + ply_list_append_data (plugin->views, view); + if (plugin->is_animating) + view_start_progress_animation (view); + } else { + view_free (view); + } + } else { + ply_list_append_data (plugin->views, view); + } +} + +static void +remove_pixel_display (ply_boot_splash_plugin_t *plugin, + ply_pixel_display_t *display) +{ + ply_list_node_t *node; + + ply_trace ("removing pixel display from plugin"); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view_t *view; + ply_list_node_t *next_node; + + view = ply_list_node_get_data (node); + next_node = ply_list_get_next_node (plugin->views, node); + + if (view->display == display) { + ply_pixel_display_set_draw_handler (view->display, NULL, NULL); + view_free (view); + ply_list_remove_node (plugin->views, node); + return; + } + + node = next_node; + } +} + +static bool +show_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop, + ply_buffer_t *boot_buffer, + ply_boot_splash_mode_t mode) +{ + int i; + + assert (plugin != NULL); + + plugin->loop = loop; + plugin->mode = mode; + + ply_trace ("loading lock image"); + if (!ply_image_load (plugin->lock_image)) + return false; + + if (plugin->box_image != NULL) { + ply_trace ("loading box image"); + + if (!ply_image_load (plugin->box_image)) { + ply_image_free (plugin->box_image); + plugin->box_image = NULL; + } + } + + if (plugin->corner_image != NULL) { + ply_trace ("loading corner image"); + + if (!ply_image_load (plugin->corner_image)) { + ply_image_free (plugin->corner_image); + plugin->corner_image = NULL; + } + } + + if (plugin->header_image != NULL) { + ply_trace ("loading header image"); + + if (!ply_image_load (plugin->header_image)) { + ply_image_free (plugin->header_image); + plugin->header_image = NULL; + } + } + + if (plugin->background_tile_image != NULL) { + ply_trace ("loading background tile image"); + if (!ply_image_load (plugin->background_tile_image)) { + ply_image_free (plugin->background_tile_image); + plugin->background_tile_image = NULL; + } + } + + if (plugin->background_bgrt_image != NULL) { + ply_trace ("loading background bgrt image"); + if (ply_image_load (plugin->background_bgrt_image)) { + plugin->background_bgrt_raw_width = ply_image_get_width (plugin->background_bgrt_image); + plugin->background_bgrt_raw_height = ply_image_get_height (plugin->background_bgrt_image); + } else { + ply_image_free (plugin->background_bgrt_image); + plugin->background_bgrt_image = NULL; + for (i = 0; i < PLY_BOOT_SPLASH_MODE_COUNT; i++) + plugin->mode_settings[i].use_firmware_background = false; + plugin->use_firmware_background = false; + } + } + + if (!load_views (plugin)) { + ply_trace ("couldn't load views"); + return false; + } + + ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + + ply_trace ("starting boot animations"); + start_progress_animation (plugin); + + plugin->is_visible = true; + + return true; +} + +static void +update_status (ply_boot_splash_plugin_t *plugin, + const char *status) +{ + assert (plugin != NULL); +} + +static void +on_animation_stopped (ply_boot_splash_plugin_t *plugin) +{ + if (plugin->idle_trigger != NULL) { + ply_trigger_pull (plugin->idle_trigger, NULL); + plugin->idle_trigger = NULL; + } + plugin->is_idle = true; +} + +static void +update_progress_animation (ply_boot_splash_plugin_t *plugin, + double fraction_done) +{ + ply_list_node_t *node; + view_t *view; + char buf[64]; + + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + + if (view->progress_animation != NULL) + ply_progress_animation_set_fraction_done (view->progress_animation, + fraction_done); + + ply_progress_bar_set_fraction_done (view->progress_bar, fraction_done); + if (!ply_progress_bar_is_hidden (view->progress_bar) && + plugin->mode_settings[plugin->mode].progress_bar_show_percent_complete) { + snprintf (buf, sizeof(buf), _("%d%% complete"), (int)(fraction_done * 100)); + view_show_message (view, buf); + } + + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +on_boot_progress (ply_boot_splash_plugin_t *plugin, + double duration, + double fraction_done) +{ + if (plugin->mode == PLY_BOOT_SPLASH_MODE_UPDATES || + plugin->mode == PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE || + plugin->mode == PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE) + return; + + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) + return; + + if (plugin->is_idle) + return; + + /* + * If we do not have an end animation, we keep showing progress until + * become_idle gets called. + */ + if (plugin->mode_settings[plugin->mode].use_end_animation && + fraction_done >= SHOW_ANIMATION_FRACTION) { + if (plugin->stop_trigger == NULL) { + ply_trace ("boot progressed to end"); + + plugin->stop_trigger = ply_trigger_new (&plugin->stop_trigger); + ply_trigger_add_handler (plugin->stop_trigger, + (ply_trigger_handler_t) + on_animation_stopped, + plugin); + start_end_animation (plugin, plugin->stop_trigger); + } + } else { + double total_duration; + + fraction_done *= (1 / SHOW_ANIMATION_FRACTION); + + switch (plugin->progress_function) { + /* Fun made-up smoothing function to make the growth asymptotic: + * fraction(time,estimate)=1-2^(-(time^1.45)/estimate) */ + case PROGRESS_FUNCTION_TYPE_WWOODS: + total_duration = duration / fraction_done; + fraction_done = 1.0 - pow (2.0, -pow (duration, 1.45) / total_duration) * (1.0 - fraction_done); + break; + + case PROGRESS_FUNCTION_TYPE_LINEAR: + break; + } + + update_progress_animation (plugin, fraction_done); + } +} + +static void +hide_splash_screen (ply_boot_splash_plugin_t *plugin, + ply_event_loop_t *loop) +{ + assert (plugin != NULL); + + ply_trace ("hiding splash"); + if (plugin->loop != NULL) { + stop_animation (plugin); + + ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t) + detach_from_event_loop, + plugin); + detach_from_event_loop (plugin); + } + + plugin->is_visible = false; +} + +static void +show_prompt (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *entry_text, + int number_of_bullets) +{ + ply_list_node_t *node; + view_t *view; + + ply_trace ("showing prompt"); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + view_show_prompt (view, prompt, entry_text, number_of_bullets); + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +on_root_mounted (ply_boot_splash_plugin_t *plugin) +{ + ply_trace ("root filesystem mounted"); + plugin->root_is_mounted = true; +} + +static void +become_idle (ply_boot_splash_plugin_t *plugin, + ply_trigger_t *idle_trigger) +{ + ply_trace ("deactivation requested"); + if (plugin->is_idle) { + ply_trace ("plugin is already idle"); + ply_trigger_pull (idle_trigger, NULL); + return; + } + + plugin->idle_trigger = idle_trigger; + + if (plugin->stop_trigger == NULL) { + ply_trace ("waiting for plugin to stop"); + plugin->stop_trigger = ply_trigger_new (&plugin->stop_trigger); + ply_trigger_add_handler (plugin->stop_trigger, + (ply_trigger_handler_t) + on_animation_stopped, + plugin); + start_end_animation (plugin, plugin->stop_trigger); + } else { + ply_trace ("already waiting for plugin to stop"); + } +} + +static void +hide_prompt (ply_boot_splash_plugin_t *plugin) +{ + ply_list_node_t *node; + view_t *view; + + ply_trace ("hiding prompt"); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + view_hide_prompt (view); + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +view_show_message (view_t *view, + const char *message) +{ + ply_boot_splash_plugin_t *plugin = view->plugin; + int x, y, width, height; + + if (plugin->message_below_animation) + ply_label_set_alignment (view->message_label, PLY_LABEL_ALIGN_CENTER); + + ply_label_set_text (view->message_label, message); + width = ply_label_get_width (view->message_label); + height = ply_label_get_height (view->message_label); + + if (plugin->message_below_animation) { + x = (ply_pixel_display_get_width (view->display) - width) * 0.5; + y = view->animation_bottom + 10; + } else { + x = 10; + y = 10; + } + + ply_label_show (view->message_label, view->display, x, y); + ply_pixel_display_draw_area (view->display, x, y, width, height); +} + +static void +show_message (ply_boot_splash_plugin_t *plugin, + const char *message) +{ + ply_list_node_t *node; + view_t *view; + + if (plugin->mode_settings[plugin->mode].suppress_messages) { + ply_trace ("Suppressing message '%s'", message); + return; + } + ply_trace ("Showing message '%s'", message); + node = ply_list_get_first_node (plugin->views); + while (node != NULL) { + view = ply_list_node_get_data (node); + view_show_message (view, message); + node = ply_list_get_next_node (plugin->views, node); + } +} + +static void +system_update (ply_boot_splash_plugin_t *plugin, + int progress) +{ + if (plugin->mode != PLY_BOOT_SPLASH_MODE_UPDATES && + plugin->mode != PLY_BOOT_SPLASH_MODE_SYSTEM_UPGRADE && + plugin->mode != PLY_BOOT_SPLASH_MODE_FIRMWARE_UPGRADE) + return; + + update_progress_animation (plugin, progress / 100.0); +} + +static void +display_normal (ply_boot_splash_plugin_t *plugin) +{ + pause_views (plugin); + if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL) + hide_prompt (plugin); + + plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL; + start_progress_animation (plugin); + redraw_views (plugin); + unpause_views (plugin); +} + +static void +display_password (ply_boot_splash_plugin_t *plugin, + const char *prompt, + int bullets) +{ + pause_views (plugin); + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + stop_animation (plugin); + + plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY; + show_prompt (plugin, prompt, NULL, bullets); + redraw_views (plugin); + unpause_views (plugin); +} + +static void +display_question (ply_boot_splash_plugin_t *plugin, + const char *prompt, + const char *entry_text) +{ + pause_views (plugin); + if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) + stop_animation (plugin); + + plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY; + show_prompt (plugin, prompt, entry_text, -1); + redraw_views (plugin); + unpause_views (plugin); +} + +static void +display_message (ply_boot_splash_plugin_t *plugin, + const char *message) +{ + show_message (plugin, message); +} + +ply_boot_splash_plugin_interface_t * +ply_boot_splash_plugin_get_interface (void) +{ + static ply_boot_splash_plugin_interface_t plugin_interface = + { + .create_plugin = create_plugin, + .destroy_plugin = destroy_plugin, + .add_pixel_display = add_pixel_display, + .remove_pixel_display = remove_pixel_display, + .show_splash_screen = show_splash_screen, + .update_status = update_status, + .on_boot_progress = on_boot_progress, + .hide_splash_screen = hide_splash_screen, + .on_root_mounted = on_root_mounted, + .become_idle = become_idle, + .display_normal = display_normal, + .display_password = display_password, + .display_question = display_question, + .display_message = display_message, + .system_update = system_update, + }; + + return &plugin_interface; +} + +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/sys-boot/plymouth-calculate-plugin/plymouth-calculate-plugin-0.9.5.ebuild b/sys-boot/plymouth-calculate-plugin/plymouth-calculate-plugin-0.9.5.ebuild new file mode 100644 index 000000000..5ac8a4c87 --- /dev/null +++ b/sys-boot/plymouth-calculate-plugin/plymouth-calculate-plugin-0.9.5.ebuild @@ -0,0 +1,98 @@ +# Copyright 1999-2018 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +inherit flag-o-matic + +MY_P=plymouth-${PV} + +if [[ ${PV} == 9999 ]]; then + inherit git-r3 + EGIT_REPO_URI="https://anongit.freedesktop.org/git/plymouth" +else + SRC_URI="${SRC_URI} https://www.freedesktop.org/software/plymouth/releases/${MY_P}.tar.xz" + KEYWORDS="~alpha amd64 ~arm ~ia64 ~ppc ~ppc64 ~sparc x86" +fi + +inherit autotools readme.gentoo-r1 systemd toolchain-funcs + +DESCRIPTION="Calculate plugin for plymouth" +HOMEPAGE="https://www.calculate-linux.org" + +LICENSE="GPL-2" +SLOT="0" +IUSE="debug gdm +gtk +libkms +pango +split-usr static-libs +udev" + +CDEPEND=" + ~sys-boot/${MY_P}[debug?,udev?,gtk?,libkms?,pango?,split-usr?,static-libs?] +" +DEPEND="${CDEPEND} + app-text/docbook-xsl-stylesheets + dev-libs/libxslt + virtual/pkgconfig +" +RDEPEND="${CDEPEND} + virtual/udev + ! Date: Wed, 2 Dec 2020 18:16:38 +0300 Subject: [PATCH 3/6] =?UTF-8?q?sys-boot/plymouth-calculate-plugin:=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=88?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D1=8B=20=D0=B4=D0=BB=D1=8F=200.9?= =?UTF-8?q?.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calculate.plymouth | 48 +++++++++++++------ .../calculate.plymouth-0.9.4 | 33 +++++++++++++ .../calculate.plymouth | 24 ++++++++-- .../calculate.plymouth-0.9.4 | 12 +++++ 4 files changed, 97 insertions(+), 20 deletions(-) create mode 100644 profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 create mode 100644 profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 diff --git a/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth index febb52a9f..dd0099715 100644 --- a/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth +++ b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth @@ -1,33 +1,51 @@ -# Calculate format=kde path=/usr/share/plymouth/themes/calculate +# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)>=0.9.5 [Plymouth Theme] Name=Calculate -Description=Simple theme that shows progressbar, image and text for shutdown +Description=Calculate spinner theme ModuleName=calculate [calculate] ImageDir=/usr/share/plymouth/themes/calculate -BootBackgroundStartColor=0x#-ini(theme.splash-silent-background-color-begin)-# -BootBackgroundEndColor=0x#-ini(theme.splash-silent-background-color-end)-# -ShutdownBackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-# -ShutdownBackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-# -!ShutdownProgressbarColor= -!BootProgressbarColor= + +[boot-up] +BackgroundStartColor=0x#-ini(theme.splash-silent-background-color-begin)-# +BackgroundEndColor=0x#-ini(theme.splash-silent-background-color-end)-# #?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==background# -BootImage=/usr/share/plymouth/themes/calculate/boot +WatermarkImage=/usr/share/plymouth/themes/calculate/boot #ini# #?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==logo# -BootImage=/usr/share/plymouth/themes/calculate/boot.png +WatermarkImage=/usr/share/plymouth/themes/calculate/boot.png #ini# #?ini(theme.splash-silent-picture)==||exists(#-ini(theme.splash-silent-picture)-#)==# -!BootImage= +!WatermarkImage #ini# + +[shutdown] +BackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-# +BackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-# +#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==background# +WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown +#ini# +#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==logo# +WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown.png +#ini# +#?ini(theme.splash-shutdown-picture)==||exists(#-ini(theme.splash-shutdown-picture)-#)==# +!WatermarkImage= +#ini# +TitleColor=0x#-ini(theme.splash-shutdown-text-color)-# +Title=S h u t t i n g d o w n + +[reboot] +BackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-# +BackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-# #?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==background# -ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown +WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown #ini# #?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==logo# -ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown.png +WatermarkImage=/usr/share/plymouth/themes/calculate/.shutdown.png #ini# #?ini(theme.splash-shutdown-picture)==||exists(#-ini(theme.splash-shutdown-picture)-#)==# -!ShutdownImage= +!WatermarkImage= #ini# -ShutdownTextColor=0x#-ini(theme.splash-shutdown-text-color)-# +TitleColor=0x#-ini(theme.splash-shutdown-text-color)-# +Title=S h u t t i n g d o w n diff --git a/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 new file mode 100644 index 000000000..bcebbb8a1 --- /dev/null +++ b/profiles/templates/3.6/2_ac_install_merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 @@ -0,0 +1,33 @@ +# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)<0.9.5 name=calculate.plymouth +[Plymouth Theme] +Name=Calculate +Description=Simple theme that shows progressbar, image and text for shutdown +ModuleName=calculate + +[calculate] +ImageDir=/usr/share/plymouth/themes/calculate +BootBackgroundStartColor=0x#-ini(theme.splash-silent-background-color-begin)-# +BootBackgroundEndColor=0x#-ini(theme.splash-silent-background-color-end)-# +ShutdownBackgroundStartColor=0x#-ini(theme.splash-shutdown-background-color-begin)-# +ShutdownBackgroundEndColor=0x#-ini(theme.splash-shutdown-background-color-end)-# +!ShutdownProgressbarColor= +!BootProgressbarColor= +#?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==background# +BootImage=/usr/share/plymouth/themes/calculate/boot +#ini# +#?ini(theme.splash-silent-picture)!=&&ini(theme.splash-silent-type)==logo# +BootImage=/usr/share/plymouth/themes/calculate/boot.png +#ini# +#?ini(theme.splash-silent-picture)==||exists(#-ini(theme.splash-silent-picture)-#)==# +!BootImage= +#ini# +#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==background# +ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown +#ini# +#?ini(theme.splash-shutdown-picture)!=&&ini(theme.splash-shutdown-type)==logo# +ShutdownImage=/usr/share/plymouth/themes/calculate/.shutdown.png +#ini# +#?ini(theme.splash-shutdown-picture)==||exists(#-ini(theme.splash-shutdown-picture)-#)==# +!ShutdownImage= +#ini# +ShutdownTextColor=0x#-ini(theme.splash-shutdown-text-color)-# diff --git a/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth index 415d6b40b..0150e927c 100644 --- a/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth +++ b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth @@ -1,12 +1,26 @@ -# Calculate format=kde path=/usr/share/plymouth/themes/calculate +# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)>=0.9.5 name=calculate.plymouth [calculate] +Font=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*16/1080,km)-# +TitleFont=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*20/1080,km)-# + +[shutdown] #?os_install_locale_lang==ru_RU# -ShutdownText=З а в е р ш е н и е р а б о т ы +Title=З а в е р ш е н и е р а б о т ы #os_install_locale_lang# #?os_install_locale_lang==fr_FR# -ShutdownText=A r r ê t e n c o u r s +Title=A r r ê t e n c o u r s #os_install_locale_lang# #?os_install_locale_lang!=ru_RU&&os_install_locale_lang!=fr_FR# -ShutdownText=S h u t t i n g d o w n +Title=S h u t t i n g d o w n +#os_install_locale_lang# + +[reboot] +#?os_install_locale_lang==ru_RU# +Title=З а в е р ш е н и е р а б о т ы +#os_install_locale_lang# +#?os_install_locale_lang==fr_FR# +Title=A r r ê t e n c o u r s +#os_install_locale_lang# +#?os_install_locale_lang!=ru_RU&&os_install_locale_lang!=fr_FR# +Title=S h u t t i n g d o w n #os_install_locale_lang# -ShutdownFont=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*20/1080,km)-# diff --git a/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 new file mode 100644 index 000000000..df6e32177 --- /dev/null +++ b/profiles/templates/3.6/3_ac_install_live/1-merge/sys-boot/plymouth-calculate-plugin/calculate.plymouth-0.9.4 @@ -0,0 +1,12 @@ +# Calculate format=kde path=/usr/share/plymouth/themes/calculate pkg(sys-boot/plymouth-calculate-plugin)<0.9.5 name=calculate.plymouth +[calculate] +#?os_install_locale_lang==ru_RU# +ShutdownText=З а в е р ш е н и е р а б о т ы +#os_install_locale_lang# +#?os_install_locale_lang==fr_FR# +ShutdownText=A r r ê t e n c o u r s +#os_install_locale_lang# +#?os_install_locale_lang!=ru_RU&&os_install_locale_lang!=fr_FR# +ShutdownText=S h u t t i n g d o w n +#os_install_locale_lang# +ShutdownFont=DroidSans #-sum(yres,,#-cut(1,x,#-list(cl_resolutions,0)-#)-#)-##-sum(km,yres*20/1080,km)-# From 92aa1248a512ce73fa6ae88c556580a762478f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=88=D0=B5=20=D0=98=D0=BC=D1=8F?= Date: Wed, 2 Dec 2020 22:23:32 +0300 Subject: [PATCH 4/6] sys-kernel/calculate-sources: Version bump to 5.9.12, 5.4.81, 4.19.161. --- sys-kernel/calculate-sources/Manifest | 8 +++---- .../calculate-sources-4.19.160.ebuild | 24 ------------------- ...uild => calculate-sources-4.19.161.ebuild} | 0 .../calculate-sources-5.4.80.ebuild | 24 ------------------- ...ebuild => calculate-sources-5.4.81.ebuild} | 0 ...ebuild => calculate-sources-5.9.12.ebuild} | 0 6 files changed, 3 insertions(+), 53 deletions(-) delete mode 100644 sys-kernel/calculate-sources/calculate-sources-4.19.160.ebuild rename sys-kernel/calculate-sources/{calculate-sources-4.19.139.ebuild => calculate-sources-4.19.161.ebuild} (100%) delete mode 100644 sys-kernel/calculate-sources/calculate-sources-5.4.80.ebuild rename sys-kernel/calculate-sources/{calculate-sources-5.4.57.ebuild => calculate-sources-5.4.81.ebuild} (100%) rename sys-kernel/calculate-sources/{calculate-sources-5.9.11.ebuild => calculate-sources-5.9.12.ebuild} (100%) diff --git a/sys-kernel/calculate-sources/Manifest b/sys-kernel/calculate-sources/Manifest index 915302bb4..98a4b6304 100644 --- a/sys-kernel/calculate-sources/Manifest +++ b/sys-kernel/calculate-sources/Manifest @@ -2,9 +2,7 @@ DIST linux-4.19.tar.xz 103117552 BLAKE2B 1dbf16cf410867412d17568fe42bc1e90c03418 DIST linux-5.4.tar.xz 109441440 BLAKE2B 193bc4a3147e147d5529956164ec4912fad5d5c6fb07f909ff1056e57235834173194afc686993ccd785c1ff15804de0961b625f3008cca0e27493efc8f27b13 SHA512 9f60f77e8ab972b9438ac648bed17551c8491d6585a5e85f694b2eaa4c623fbc61eb18419b2656b6795eac5deec0edaa04547fc6723fbda52256bd7f3486898f DIST linux-5.8.tar.xz 114459324 BLAKE2B 7bd97f8fa4527840754434414c07283e89731dc8ebb1e95fa5bc1469a60af1122582c0d3b6e262e77882f023190068df3537bd8b65964b3caa820bb2c8e579c7 SHA512 45a53ecf351096ef6e98242cca4228b8da9b9139ecc6963695791ea6fb7a9484a4e1c19dcca7ce7cbfdfa49de0451b70973bb078f12bdae9cbaddbc3f8092556 DIST linux-5.9.tar.xz 115507140 BLAKE2B e8d11472d63a9f8409ca12a2e8c97c6963a3d4516b5a398b627d6ece565584526f9b5a1377a2fa4bd184c09c7db94c987428bc5d52df0c788464a67e9e8d6dcb SHA512 d3d92ce4246bad74c9a784212f160d98449b1e8793970c2c308276568d852b8effe0528686bdb87d55d691f09a826abf7938d69bdd4759ce65ddd5c05ffe4eca -DIST patch-4.19.139.xz 3287912 BLAKE2B 15af2c1ff765a3a00e6f3a7ef108bcc54ce10603666df655c92f3c7da48cf25054f7b1624e363e96fbc56a39ce021e28bb647552daebf8dcdc69db630dedb500 SHA512 b68fab236291799721977e7874b5b995eee6e4ee11d06e827a65af3610cbff11ef823831264050f96fecce2c0f7d186c03e881c025234ad8c8072a5eb0c1e44b -DIST patch-4.19.160.xz 3638736 BLAKE2B 8a31b8f6b4edcd42d1947e7f04dc8da0447b0568e9beae767c446b0aa5c0bd1f335a5feabc31de5ac659560a61aba91e77e6a243bea037bf83f5b4c25aeb52c4 SHA512 beb8fcc81a595c50bf2168624aed651c2d7b30c7ada6ddfc8585db1e5d477c336e7c5334e137350405f2aa1e3d4e21950d0e47de4fc58ee5542eae942c7ffb55 -DIST patch-5.4.57.xz 1752516 BLAKE2B 7a78abafd1de8580b91738461f4f44461a7582cdf10b9eb45485f6b7ac66939e44edbdc778b8c3d81dd939155607b0e4f6245426feeb3762cd379548a839e125 SHA512 79d2e85bd35222651959c9ed6b9c711d6cad2e23a57acfe92a5f01c5bb2f39fdd75d6c8a402f1341e13979ada4cd522bd4d3f2493be61f75e8a92a95b15776f9 -DIST patch-5.4.80.xz 2376300 BLAKE2B 19bf6c247c3577a61fa0de17407ab4158c06f770fcbe80e0f233e71350da4b68500f27e91eec582552789e5753bc910d863a64ea776055259574adc38b49de82 SHA512 2dd24c1ff86ff325b8c426dd3f8cc2cc97b9d8b213c3b014ae33429f85d56f2bfe8e540771104c0eafb09a96fa3ecf4be820536dc0baa9859099e537310f8622 +DIST patch-4.19.161.xz 3649928 BLAKE2B d9208f6b07a59c14e9f46acca1b1456bc02e8afd64b2c634a8376d28bdd5df61de66e7cfd42a9482e986d8fb822518b3dbbac9bde4f2e0257fa73b4dba59c51d SHA512 6483da5d53e4660515fd053c3e6ee3083b222db199d8de3b00a80fe7d2414f61e4bfc2abb88d8186943c8aa01e16bf29ef38e352c32e0ccac29ba6555523ae00 +DIST patch-5.4.81.xz 2396180 BLAKE2B 3a42b28cb5fb9cdc83171df46854805cc39e83f122f47b00eb823a05c0663880e688d7c44dfd2c21875fdbb0f02e494396df69ce07cc4ca76d03cee521d48ece SHA512 f97b6d8d58d43449491d543dd0c3afe8e4c7f7ea4527c4712b0bb6b7a4817daba61f507e8518a4f72254042472d7b5f8095e5df1c131fd010f4c0453c9d8cde5 DIST patch-5.8.18.xz 753276 BLAKE2B cc4ab6db80f14cd22f6409c4eb1f344822b79cdbccbae65d53aba444f957ed320719acf0f448e08cc9f1341dafee90527fd035f13a268289c2dc3bf317107142 SHA512 e161e534bcf842de5b2a605f153e6d581030593e99185a5d3c341b40c2c9e6e4a6b3bac38647156f1974768cf730073c0ca34295d847e0dd114de4ca52d72039 -DIST patch-5.9.11.xz 567176 BLAKE2B d818fd153cf276f2f20360cdd6786bb22506a9d2dcd1c46da39c4f35eb27514e71df46ea66458881d8485c75d34b6048f688f031b082f07330db0cdc17ba0440 SHA512 1509a98ef46e00297e2e2fed24cde5ce70d05432ee276320e708cbdde7205683efd857c5aee3367df9ee0ac02010fd553ae999db796ab5ba16c6c3f1a6b0ee92 +DIST patch-5.9.12.xz 612468 BLAKE2B babdf390cba9ede83b9056c90f769b98d58d86b168b8666035bf17e3e7d5f942d45a7392e56b6acd0423d0a4e8a1b3fa629a40ba12ba4a8ced4719b7218cef70 SHA512 eef914d5124dae25d0d5c6162cf0d19cfe6adabd3da5594609275527ac7bca9b8b3c9bdd8ae5cbc061cb93a4559c30daed3f104f789b31caa2596f3da371f2aa diff --git a/sys-kernel/calculate-sources/calculate-sources-4.19.160.ebuild b/sys-kernel/calculate-sources/calculate-sources-4.19.160.ebuild deleted file mode 100644 index 2a47ced20..000000000 --- a/sys-kernel/calculate-sources/calculate-sources-4.19.160.ebuild +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 1999-2015 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -EAPI=5 -ETYPE="sources" - -inherit calculate-kernel-7 eutils - -DESCRIPTION="Calculate Linux kernel image" -KEYWORDS="~amd64" -HOMEPAGE="http://www.calculate-linux.org" - -SRC_URI="${KERNEL_URI} ${ARCH_URI}" - -IUSE="uksm" - -src_unpack() { - calculate-kernel-7_src_unpack -} - -pkg_postinst() { - calculate-kernel-7_pkg_postinst -} diff --git a/sys-kernel/calculate-sources/calculate-sources-4.19.139.ebuild b/sys-kernel/calculate-sources/calculate-sources-4.19.161.ebuild similarity index 100% rename from sys-kernel/calculate-sources/calculate-sources-4.19.139.ebuild rename to sys-kernel/calculate-sources/calculate-sources-4.19.161.ebuild diff --git a/sys-kernel/calculate-sources/calculate-sources-5.4.80.ebuild b/sys-kernel/calculate-sources/calculate-sources-5.4.80.ebuild deleted file mode 100644 index 1210fed76..000000000 --- a/sys-kernel/calculate-sources/calculate-sources-5.4.80.ebuild +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 1999-2015 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -EAPI=5 -ETYPE="sources" - -inherit calculate-kernel-8 eutils - -DESCRIPTION="Calculate Linux kernel image" -KEYWORDS="~amd64" -HOMEPAGE="http://www.calculate-linux.org" - -SRC_URI="${KERNEL_URI} ${ARCH_URI}" - -IUSE="fsync muqss uksm" - -src_unpack() { - calculate-kernel-8_src_unpack -} - -pkg_postinst() { - calculate-kernel-8_pkg_postinst -} diff --git a/sys-kernel/calculate-sources/calculate-sources-5.4.57.ebuild b/sys-kernel/calculate-sources/calculate-sources-5.4.81.ebuild similarity index 100% rename from sys-kernel/calculate-sources/calculate-sources-5.4.57.ebuild rename to sys-kernel/calculate-sources/calculate-sources-5.4.81.ebuild diff --git a/sys-kernel/calculate-sources/calculate-sources-5.9.11.ebuild b/sys-kernel/calculate-sources/calculate-sources-5.9.12.ebuild similarity index 100% rename from sys-kernel/calculate-sources/calculate-sources-5.9.11.ebuild rename to sys-kernel/calculate-sources/calculate-sources-5.9.12.ebuild From e7e235c023c05f77d34cdf6457eadef4af63a154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=88=D0=B5=20=D0=98=D0=BC=D1=8F?= Date: Wed, 2 Dec 2020 22:25:38 +0300 Subject: [PATCH 5/6] sys-kernel/calculate-sources: delete 5.8 --- .../5.8/.calculate_directory | 1 - .../calculate-sources/5.8/10-calculate-x86_64 | 4618 ----------- .../calculate-sources/5.8/11-update-01 | 10 - .../calculate-sources/5.8/30-server | 14 - .../calculate-sources/5.8/4500_uksm.patch | 6935 ----------------- .../5.8/4502_futex-wait-multiple.patch | 326 - sys-kernel/calculate-sources/Manifest | 2 - .../calculate-sources-5.8.18.ebuild | 24 - 8 files changed, 11930 deletions(-) delete mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/.calculate_directory delete mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/10-calculate-x86_64 delete mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/11-update-01 delete mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/30-server delete mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4500_uksm.patch delete mode 100644 profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4502_futex-wait-multiple.patch delete mode 100644 sys-kernel/calculate-sources/calculate-sources-5.8.18.ebuild diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/.calculate_directory b/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/.calculate_directory deleted file mode 100644 index 23dad36eb..000000000 --- a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/.calculate_directory +++ /dev/null @@ -1 +0,0 @@ -# Calculate append=skip merge(sys-kernel/calculate-sources)=>5.8,5.9 diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/10-calculate-x86_64 b/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/10-calculate-x86_64 deleted file mode 100644 index e44cd4a81..000000000 --- a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/10-calculate-x86_64 +++ /dev/null @@ -1,4618 +0,0 @@ -# Calculate format=kernel name=.config os_install_arch_machine==x86_64 -CONFIG_60XX_WDT=m -CONFIG_8139CP=m -CONFIG_8139_OLD_RX_RESET=y -CONFIG_8139TOO_8129=y -CONFIG_8139TOO=m -CONFIG_8139TOO_TUNE_TWISTER=y -CONFIG_842_COMPRESS=m -CONFIG_842_DECOMPRESS=m -CONFIG_88EU_AP_MODE=y -# CONFIG_ABP060MG is not set -CONFIG_AC97_BUS=m -CONFIG_ACENIC=m -CONFIG_ACENIC_OMIT_TIGON_I=y -CONFIG_ACERHDF=m -CONFIG_ACER_WIRELESS=m -CONFIG_ACER_WMI=m -# CONFIG_ACORN_PARTITION is not set -CONFIG_ACPI_AC=m -CONFIG_ACPI_ALS=m -CONFIG_ACPI_BATTERY=m -# CONFIG_ACPI_BGRT is not set -CONFIG_ACPI_BUTTON=m -CONFIG_ACPI_CMPC=m -CONFIG_ACPI_FAN=m -# CONFIG_ACPI_IPMI is not set -CONFIG_ACPI_PROCESSOR_AGGREGATOR=m -# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set -CONFIG_ACPI_SBS=m -CONFIG_ACPI_TAD=m -CONFIG_ACPI_THERMAL=m -CONFIG_ACPI_THERMAL_REL=m -# CONFIG_ACPI_TINY_POWER_BUTTON is not set -CONFIG_ACPI_TOSHIBA=m -CONFIG_ACPI_VIDEO=m -CONFIG_ACPI_WMI=m -CONFIG_ACQUIRE_WDT=m -# CONFIG_ACRN_GUEST is not set -# CONFIG_AD5064 is not set -# CONFIG_AD5272 is not set -# CONFIG_AD5380 is not set -# CONFIG_AD5446 is not set -# CONFIG_AD5593R is not set -# CONFIG_AD5696_I2C is not set -# CONFIG_AD5933 is not set -# CONFIG_AD7091R5 is not set -# CONFIG_AD7150 is not set -# CONFIG_AD7291 is not set -# CONFIG_AD7606_IFACE_PARALLEL is not set -# CONFIG_AD7746 is not set -# CONFIG_AD799X is not set -CONFIG_ADAPTEC_STARFIRE=m -# CONFIG_ADE7854 is not set -# CONFIG_ADI_AXI_ADC is not set -# CONFIG_ADJD_S311 is not set -CONFIG_ADM8211=m -# CONFIG_ADT7316 is not set -# CONFIG_ADUX1020 is not set -CONFIG_ADVANTECH_WDT=m -# CONFIG_ADXL345_I2C is not set -# CONFIG_ADXL372_I2C is not set -# CONFIG_AFE4404 is not set -CONFIG_AGP_AMD64=m -CONFIG_AGP_INTEL=m -CONFIG_AGP_SIS=m -CONFIG_AGP_VIA=m -CONFIG_AIC79XX_CMDS_PER_DEVICE=32 -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -CONFIG_AIC79XX_REG_PRETTY_PRINT=y -CONFIG_AIC79XX_RESET_DELAY_MS=5000 -CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 -# CONFIG_AIC7XXX_DEBUG_ENABLE is not set -CONFIG_AIC7XXX_DEBUG_MASK=0 -# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set -CONFIG_AIC7XXX_RESET_DELAY_MS=5000 -# CONFIG_AIC94XX_DEBUG is not set -CONFIG_AIRO_CS=m -CONFIG_AIRO=m -# CONFIG_AIX_PARTITION is not set -# CONFIG_AK09911 is not set -# CONFIG_AK8975 is not set -# CONFIG_AL3010 is not set -# CONFIG_AL3320A is not set -CONFIG_ALIENWARE_WMI=m -CONFIG_ALIM1535_WDT=m -CONFIG_ALIM7101_WDT=m -CONFIG_ALTERA_MSGDMA=m -CONFIG_ALTERA_STAPL=m -CONFIG_ALTERA_TSE=m -CONFIG_ALX=m -CONFIG_AM2315=m -CONFIG_AMD8111_ETH=m -CONFIG_AMD_IOMMU_V2=m -# CONFIG_AMD_NUMA is not set -CONFIG_AMD_PHY=m -CONFIG_AMD_XGBE_HAVE_ECC=y -CONFIG_AMD_XGBE=m -# CONFIG_AMIGA_PARTITION is not set -CONFIG_AMILO_RFKILL=m -# CONFIG_APDS9300 is not set -# CONFIG_APDS9960 is not set -CONFIG_APPLE_GMUX=m -CONFIG_APPLE_PROPERTIES=y -CONFIG_AQTION=m -CONFIG_AR5523=m -CONFIG_ARCH_CPUIDLE_HALTPOLL=y -CONFIG_ASUS_LAPTOP=m -CONFIG_ASUS_NB_WMI=m -CONFIG_ASUS_WIRELESS=m -CONFIG_ASUS_WMI=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m -# CONFIG_ASYNC_RAID6_TEST is not set -CONFIG_ASYNC_XOR=m -CONFIG_AT76C50X_USB=m -CONFIG_AT803X_PHY=m -CONFIG_ATA_GENERIC=m -CONFIG_ATA_PIIX=m -# CONFIG_ATARI_PARTITION is not set -# CONFIG_ATA_VERBOSE_ERROR is not set -CONFIG_ATH10K_CE=y -# CONFIG_ATH10K_DEBUGFS is not set -# CONFIG_ATH10K_DEBUG is not set -CONFIG_ATH10K=m -CONFIG_ATH10K_PCI=m -CONFIG_ATH10K_SDIO=m -CONFIG_ATH10K_USB=m -# CONFIG_ATH5K_DEBUG is not set -CONFIG_ATH5K=m -CONFIG_ATH5K_PCI=y -# CONFIG_ATH6KL_DEBUG is not set -CONFIG_ATH6KL=m -CONFIG_ATH6KL_SDIO=m -CONFIG_ATH6KL_USB=m -CONFIG_ATH9K_AHB=y -CONFIG_ATH9K_BTCOEX_SUPPORT=y -CONFIG_ATH9K_CHANNEL_CONTEXT=y -CONFIG_ATH9K_COMMON=m -# CONFIG_ATH9K_DEBUGFS is not set -CONFIG_ATH9K_DYNACK=y -# CONFIG_ATH9K_HTC_DEBUGFS is not set -CONFIG_ATH9K_HTC=m -CONFIG_ATH9K_HW=m -CONFIG_ATH9K_HWRNG=y -CONFIG_ATH9K=m -CONFIG_ATH9K_PCI_NO_EEPROM=m -CONFIG_ATH9K_PCI=y -CONFIG_ATH9K_PCOEM=y -CONFIG_ATH9K_RFKILL=y -# CONFIG_ATH9K_WOW is not set -CONFIG_ATH_COMMON=m -CONFIG_ATL1C=m -CONFIG_ATL1E=m -CONFIG_ATL1=m -CONFIG_ATL2=m -# CONFIG_ATLAS_EZO_SENSOR is not set -# CONFIG_ATLAS_PH_SENSOR is not set -CONFIG_ATMEL=m -CONFIG_ATP=m -CONFIG_AURORA_NB8800=m -# CONFIG_AXP20X_ADC is not set -# CONFIG_AXP20X_POWER is not set -CONFIG_AXP288_ADC=m -# CONFIG_AXP288_CHARGER is not set -# CONFIG_AXP288_FUEL_GAUGE is not set -CONFIG_B43_BCMA_PIO=y -CONFIG_B43_BCMA=y -CONFIG_B43_BUSES_BCMA_AND_SSB=y -# CONFIG_B43_BUSES_BCMA is not set -# CONFIG_B43_BUSES_SSB is not set -# CONFIG_B43_DEBUG is not set -CONFIG_B43_HWRNG=y -CONFIG_B43_LEDS=y -CONFIG_B43LEGACY_DEBUG=y -CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y -# CONFIG_B43LEGACY_DMA_MODE is not set -CONFIG_B43LEGACY_DMA=y -CONFIG_B43LEGACY_HWRNG=y -CONFIG_B43LEGACY_LEDS=y -CONFIG_B43LEGACY=m -CONFIG_B43LEGACY_PCI_AUTOSELECT=y -CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y -# CONFIG_B43LEGACY_PIO_MODE is not set -CONFIG_B43LEGACY_PIO=y -CONFIG_B43=m -CONFIG_B43_PCI_AUTOSELECT=y -CONFIG_B43_PCICORE_AUTOSELECT=y -CONFIG_B43_PHY_G=y -CONFIG_B43_PHY_HT=y -CONFIG_B43_PHY_LP=y -CONFIG_B43_PHY_N=y -CONFIG_B43_PIO=y -CONFIG_B43_SDIO=y -CONFIG_B43_SSB=y -CONFIG_B44=m -CONFIG_B44_PCI_AUTOSELECT=y -CONFIG_B44_PCICORE_AUTOSELECT=y -CONFIG_B44_PCI=y -CONFIG_B53=m -CONFIG_B53_MDIO_DRIVER=m -CONFIG_B53_MMAP_DRIVER=m -CONFIG_B53_SERDES=m -CONFIG_B53_SRAB_DRIVER=m -# CONFIG_BACKLIGHT_GENERIC is not set -# CONFIG_BACKLIGHT_GPIO is not set -CONFIG_BAREUDP=m -CONFIG_BATMAN_ADV_BATMAN_V=y -CONFIG_BATMAN_ADV_BLA=y -CONFIG_BATMAN_ADV_DAT=y -# CONFIG_BATMAN_ADV_DEBUGFS is not set -# CONFIG_BATMAN_ADV_DEBUG is not set -CONFIG_BATMAN_ADV=m -# CONFIG_BATMAN_ADV_MCAST is not set -CONFIG_BATMAN_ADV_NC=y -CONFIG_BATMAN_ADV_SYSFS=y -# CONFIG_BATTERY_DA9150 is not set -# CONFIG_BATTERY_RT5033 is not set -# CONFIG_BCACHE_ASYNC_REGISTRAION is not set -# CONFIG_BCACHE_CLOSURES_DEBUG is not set -# CONFIG_BCACHE_DEBUG is not set -CONFIG_BCACHE=m -CONFIG_BCM54140_PHY=m -CONFIG_BCM7XXX_PHY=m -CONFIG_BCM84881_PHY=m -CONFIG_BCM87XX_PHY=m -CONFIG_BCMA_BLOCKIO=y -# CONFIG_BCMA_DEBUG is not set -# CONFIG_BCMA_DRIVER_GMAC_CMN is not set -# CONFIG_BCMA_DRIVER_GPIO is not set -CONFIG_BCMA_DRIVER_PCI=y -CONFIG_BCMA_HOST_PCI_POSSIBLE=y -CONFIG_BCMA_HOST_PCI=y -CONFIG_BCMA_HOST_SOC=y -CONFIG_BCMA=m -CONFIG_BCMA_SFLASH=y -CONFIG_BCMGENET=m -CONFIG_BCM_NET_PHYLIB=m -CONFIG_BE2ISCSI=m -CONFIG_BE2NET_BE2=y -CONFIG_BE2NET_BE3=y -CONFIG_BE2NET_HWMON=y -CONFIG_BE2NET_LANCER=y -CONFIG_BE2NET=m -CONFIG_BE2NET_SKYHAWK=y -# CONFIG_BFQ_CGROUP_DEBUG is not set -CONFIG_BFQ_GROUP_IOSCHED=y -CONFIG_BH1750=m -CONFIG_BH1780=m -CONFIG_BLK_CGROUP_IOCOST=y -CONFIG_BLK_CGROUP_IOLATENCY=y -CONFIG_BLK_CGROUP_RWSTAT=y -CONFIG_BLK_CGROUP=y -CONFIG_BLK_DEV_3W_XXXX_RAID=m -CONFIG_BLK_DEV_BSGLIB=y -CONFIG_BLK_DEV_DM=m -CONFIG_BLK_DEV_INTEGRITY_T10=y -CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_BLK_DEV_MD=m -CONFIG_BLK_DEV_NVME=y -CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m -CONFIG_BLK_DEV_PMEM=m -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM=m -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RSXX=m -CONFIG_BLK_DEV_SX8=m -# CONFIG_BLK_DEV_THROTTLING_LOW is not set -CONFIG_BLK_DEV_THROTTLING=y -CONFIG_BLK_MQ_VIRTIO=y -CONFIG_BLK_RQ_ALLOC_TIME=y -CONFIG_BLK_WBT_MQ=y -CONFIG_BLK_WBT=y -# CONFIG_BMA400 is not set -# CONFIG_BMC150_ACCEL is not set -# CONFIG_BMC150_MAGN_I2C is not set -# CONFIG_BME680 is not set -# CONFIG_BMG160 is not set -# CONFIG_BMI160_I2C is not set -# CONFIG_BMP280 is not set -CONFIG_BNA=m -CONFIG_BNX2=m -CONFIG_BNX2X=m -CONFIG_BNX2X_SRIOV=y -CONFIG_BNXT_FLOWER_OFFLOAD=y -CONFIG_BNXT_HWMON=y -CONFIG_BNXT=m -CONFIG_BNXT_SRIOV=y -CONFIG_BONDING=m -CONFIG_BOOT_CONFIG=y -CONFIG_BPFILTER_UMH=m -CONFIG_BPFILTER=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set -CONFIG_BPF_JIT_DEFAULT_ON=y -CONFIG_BPF_JIT=y -# CONFIG_BPF_STREAM_PARSER is not set -CONFIG_BPF_SYSCALL=y -# CONFIG_BRCMDBG is not set -CONFIG_BRCMFMAC=m -CONFIG_BRCMFMAC_PCIE=y -CONFIG_BRCMFMAC_PROTO_BCDC=y -CONFIG_BRCMFMAC_PROTO_MSGBUF=y -CONFIG_BRCMFMAC_SDIO=y -CONFIG_BRCMFMAC_USB=y -CONFIG_BRCMSMAC=m -# CONFIG_BRCM_TRACING is not set -CONFIG_BRCMUTIL=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_IP6=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_MARK_T=m -CONFIG_BRIDGE_EBT_NFLOG=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_IGMP_SNOOPING=y -CONFIG_BRIDGE=m -CONFIG_BRIDGE_MRP=y -CONFIG_BRIDGE_NETFILTER=m -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_VLAN_FILTERING=y -CONFIG_BROADCOM_PHY=m -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_BT_ATH3K=m -CONFIG_BT_BCM=m -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_BREDR=y -CONFIG_BT_DEBUGFS=y -# CONFIG_BT_FEATURE_DEBUG is not set -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIBLUECARD=m -CONFIG_BT_HCIBPA10X=m -CONFIG_BT_HCIBT3C=m -# CONFIG_BT_HCIBTSDIO is not set -# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set -CONFIG_BT_HCIBTUSB_BCM=y -CONFIG_BT_HCIBTUSB=m -CONFIG_BT_HCIBTUSB_MTK=y -CONFIG_BT_HCIBTUSB_RTL=y -CONFIG_BT_HCIDTL1=m -CONFIG_BT_HCIRSI=m -# CONFIG_BT_HCIUART is not set -# CONFIG_BT_HCIVHCI is not set -CONFIG_BT_HIDP=m -CONFIG_BT_HS=y -CONFIG_BT_INTEL=m -CONFIG_BT_LEDS=y -CONFIG_BT_LE=y -CONFIG_BT=m -CONFIG_BT_MRVL=m -CONFIG_BT_MRVL_SDIO=m -CONFIG_BT_MSFTEXT=y -CONFIG_BT_MTKSDIO=m -CONFIG_BT_MTKUART=m -CONFIG_BTREE=y -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -# CONFIG_BTRFS_ASSERT is not set -# CONFIG_BTRFS_DEBUG is not set -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set -CONFIG_BTRFS_FS=m -CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_BTRFS_FS_REF_VERIFY is not set -# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set -CONFIG_BT_RTL=m -# CONFIG_BT_SELFTEST is not set -CONFIG_BTT=y -# CONFIG_CACHEFILES_DEBUG is not set -# CONFIG_CACHEFILES_HISTOGRAM is not set -CONFIG_CACHEFILES=m -CONFIG_CADENCE_WATCHDOG=m -CONFIG_CASSINI=m -CONFIG_CAVIUM_PTP=y -CONFIG_CB710_CORE=m -CONFIG_CB710_DEBUG_ASSUMPTIONS=y -# CONFIG_CB710_DEBUG is not set -# CONFIG_CC10001_ADC is not set -# CONFIG_CCS811 is not set -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -CONFIG_CDROM_PKTCDVD=m -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_CEC_CORE=m -CONFIG_CEC_NOTIFIER=y -# CONFIG_CFG80211_CERTIFICATION_ONUS is not set -CONFIG_CFG80211=m -CONFIG_CFG80211_WEXT_EXPORT=y -CONFIG_CFG80211_WEXT=y -CONFIG_CFS_BANDWIDTH=y -CONFIG_CGROUP_BPF=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CGROUP_HUGETLB=y -CONFIG_CGROUP_NET_CLASSID=y -CONFIG_CGROUP_NET_PRIO=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_PIDS=y -CONFIG_CGROUP_WRITEBACK=y -# CONFIG_CHARGER_BQ24190 is not set -# CONFIG_CHARGER_BQ24257 is not set -# CONFIG_CHARGER_BQ24735 is not set -# CONFIG_CHARGER_BQ25890 is not set -# CONFIG_CHARGER_GPIO is not set -CONFIG_CHARGER_ISP1704=m -# CONFIG_CHARGER_LT3651 is not set -# CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_MAX14577 is not set -# CONFIG_CHARGER_MAX77693 is not set -# CONFIG_CHARGER_RT9455 is not set -CONFIG_CHECKPOINT_RESTORE=y -CONFIG_CHELSIO_IPSEC_INLINE=y -CONFIG_CHELSIO_LIB=m -CONFIG_CHELSIO_T1_1G=y -CONFIG_CHELSIO_T1=m -CONFIG_CHELSIO_T3=m -CONFIG_CHELSIO_T4=m -CONFIG_CHELSIO_T4VF=m -CONFIG_CHELSIO_TLS_DEVICE=y -CONFIG_CHR_DEV_SG=m -CONFIG_CHR_DEV_ST=m -CONFIG_CICADA_PHY=m -CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_DEBUG is not set -CONFIG_CIFS_DFS_UPCALL=y -# CONFIG_CIFS_FSCACHE is not set -CONFIG_CIFS=m -CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_STATS2 is not set -CONFIG_CIFS_UPCALL=y -# CONFIG_CIFS_WEAK_PW_HASH is not set -CONFIG_CIFS_XATTR=y -CONFIG_CLEANCACHE=y -CONFIG_CLOCK_THERMAL=y -CONFIG_CLS_U32_MARK=y -CONFIG_CLS_U32_PERF=y -# CONFIG_CM32181 is not set -# CONFIG_CM3232 is not set -# CONFIG_CM3323 is not set -# CONFIG_CM36651 is not set -# CONFIG_CMDLINE_PARTITION is not set -CONFIG_CNIC=m -# CONFIG_COMEDI is not set -CONFIG_COMMON_CLK_SI5341=m -# CONFIG_COMPACTION is not set -CONFIG_COMPAL_LAPTOP=m -CONFIG_COMPAT_NETLINK_MESSAGES=y -CONFIG_CONFIGFS_FS=m -CONFIG_CORDIC=m -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_CORTINA_PHY=m -CONFIG_CPU5_WDT=m -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m -CONFIG_CPU_FREQ_GOV_POWERSAVE=m -CONFIG_CPU_FREQ_GOV_USERSPACE=m -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_IDLE_GOV_HALTPOLL=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_TEO=y -# CONFIG_CRASH_DUMP is not set -CONFIG_CRC16=m -CONFIG_CRC64=m -CONFIG_CRC7=m -CONFIG_CRC8=m -CONFIG_CRC_CCITT=m -CONFIG_CRC_ITU_T=m -CONFIG_CRC_T10DIF=y -CONFIG_CRYPTO_842=m -CONFIG_CRYPTO_ADIANTUM=m -CONFIG_CRYPTO_AEGIS128_AESNI_SSE2=m -CONFIG_CRYPTO_AEGIS128=m -CONFIG_CRYPTO_AES_NI_INTEL=m -CONFIG_CRYPTO_AES_TI=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m -CONFIG_CRYPTO_AUTHENC=m -CONFIG_CRYPTO_BLAKE2B=m -CONFIG_CRYPTO_BLAKE2S=m -CONFIG_CRYPTO_BLAKE2S_X86=m -CONFIG_CRYPTO_BLOWFISH_COMMON=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_BLOWFISH_X86_64=m -CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m -CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAMELLIA_X86_64=m -CONFIG_CRYPTO_CAST5_AVX_X86_64=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6_AVX_X86_64=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_CAST_COMMON=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_CFB=m -CONFIG_CRYPTO_CHACHA20=m -CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CHACHA20_X86_64=m -CONFIG_CRYPTO_CMAC=m -CONFIG_CRYPTO_CRC32C_INTEL=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CRC32=m -CONFIG_CRYPTO_CRC32_PCLMUL=m -CONFIG_CRYPTO_CRCT10DIF_PCLMUL=m -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_CTS=m -CONFIG_CRYPTO_CURVE25519=m -CONFIG_CRYPTO_CURVE25519_X86=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_DES3_EDE_X86_64=m -CONFIG_CRYPTO_DES=m -# CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG is not set -CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m -CONFIG_CRYPTO_DEV_ATMEL_ECC=m -CONFIG_CRYPTO_DEV_ATMEL_I2C=m -CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m -CONFIG_CRYPTO_DEV_CCP_CRYPTO=m -CONFIG_CRYPTO_DEV_CCP_DD=m -# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set -CONFIG_CRYPTO_DEV_CCP=y -CONFIG_CRYPTO_DEV_CHELSIO=m -CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m -CONFIG_CRYPTO_DEV_NITROX=m -CONFIG_CRYPTO_DEV_QAT_C3XXX=m -CONFIG_CRYPTO_DEV_QAT_C3XXXVF=m -CONFIG_CRYPTO_DEV_QAT_C62X=m -CONFIG_CRYPTO_DEV_QAT_C62XVF=m -CONFIG_CRYPTO_DEV_QAT_DH895xCC=m -CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m -CONFIG_CRYPTO_DEV_QAT=m -CONFIG_CRYPTO_DEV_SAFEXCEL=m -CONFIG_CRYPTO_DEV_SP_CCP=y -CONFIG_CRYPTO_DEV_SP_PSP=y -CONFIG_CRYPTO_DEV_VIRTIO=m -CONFIG_CRYPTO_DH=m -CONFIG_CRYPTO_DRBG_CTR=y -CONFIG_CRYPTO_DRBG_HASH=y -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_ECC=m -CONFIG_CRYPTO_ECDH=m -CONFIG_CRYPTO_ECHAINIV=m -CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_ENGINE=m -CONFIG_CRYPTO_ESSIV=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_GLUE_HELPER_X86=m -CONFIG_CRYPTO_KEYWRAP=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_KPP=m -CONFIG_CRYPTO_LIB_ARC4=m -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m -CONFIG_CRYPTO_LIB_BLAKE2S=m -CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m -CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m -CONFIG_CRYPTO_LIB_CHACHA=m -CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m -CONFIG_CRYPTO_LIB_CURVE25519=m -CONFIG_CRYPTO_LIB_DES=m -CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m -CONFIG_CRYPTO_LIB_POLY1305=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_LZ4HC=m -CONFIG_CRYPTO_LZ4=m -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_NHPOLY1305_AVX2=m -CONFIG_CRYPTO_NHPOLY1305=m -CONFIG_CRYPTO_NHPOLY1305_SSE2=m -CONFIG_CRYPTO_OFB=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_PCRYPT=m -CONFIG_CRYPTO_POLY1305=m -CONFIG_CRYPTO_POLY1305_X86_64=m -CONFIG_CRYPTO_RMD128=m -CONFIG_CRYPTO_RMD160=m -CONFIG_CRYPTO_RMD256=m -CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SEED=m -CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m -CONFIG_CRYPTO_SERPENT_AVX_X86_64=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m -CONFIG_CRYPTO_SHA1_SSSE3=m -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256_SSSE3=m -CONFIG_CRYPTO_SHA3=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_SHA512_SSSE3=m -CONFIG_CRYPTO_SIMD=m -CONFIG_CRYPTO_SM3=m -CONFIG_CRYPTO_SM4=m -# CONFIG_CRYPTO_STATS is not set -CONFIG_CRYPTO_STREEBOG=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m -CONFIG_CRYPTO_TWOFISH_X86_64=m -CONFIG_CRYPTO_USER_API_AEAD=m -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API=m -CONFIG_CRYPTO_USER_API_RNG=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_USER=m -CONFIG_CRYPTO_VMAC=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_XTS=m -CONFIG_CRYPTO_XXHASH=m -CONFIG_CRYPTO_ZSTD=y -# CONFIG_CUSE is not set -CONFIG_CW1200=m -CONFIG_CW1200_WLAN_SDIO=m -CONFIG_CX_ECAT=m -CONFIG_CYPRESS_FIRMWARE=m -# CONFIG_DA280 is not set -# CONFIG_DA311 is not set -# CONFIG_DA9062_WATCHDOG is not set -# CONFIG_DA9063_WATCHDOG is not set -# CONFIG_DA9150_GPADC is not set -CONFIG_DAVICOM_PHY=m -CONFIG_DAX_DRIVER=y -CONFIG_DAX=y -CONFIG_DCA=m -CONFIG_DCDBAS=m -CONFIG_DE2104X_DSL=0 -CONFIG_DE2104X=m -CONFIG_DE4X5=m -# CONFIG_DEBUG_BOOT_PARAMS is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_DEBUG_GPIO is not set -# CONFIG_DEBUG_KERNEL_DC is not set -# CONFIG_DEBUG_PINCTRL is not set -# CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_RODATA_TEST=y -# CONFIG_DEBUG_RSEQ is not set -CONFIG_DEBUG_SECTION_MISMATCH=y -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEFAULT_HOSTNAME="calculate" -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DELL_LAPTOP=m -CONFIG_DELL_RBTN=m -CONFIG_DELL_RBU=m -CONFIG_DELL_SMBIOS=m -CONFIG_DELL_SMBIOS_SMM=y -CONFIG_DELL_SMBIOS_WMI=y -CONFIG_DELL_SMO8800=m -CONFIG_DELL_WMI_AIO=m -CONFIG_DELL_WMI_DESCRIPTOR=m -CONFIG_DELL_WMI_LED=m -CONFIG_DELL_WMI=m -CONFIG_DEV_COREDUMP=y -# CONFIG_DEVFREQ_GOV_PASSIVE is not set -# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set -# CONFIG_DEVFREQ_GOV_POWERSAVE is not set -CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m -# CONFIG_DEVFREQ_GOV_USERSPACE is not set -CONFIG_DEVFREQ_THERMAL=y -CONFIG_DEVKMEM=y -# CONFIG_DHT11 is not set -CONFIG_DIMLIB=y -CONFIG_DL2K=m -# CONFIG_DLHL60D is not set -# CONFIG_DLM_DEBUG is not set -CONFIG_DLM=m -# CONFIG_DLN2_ADC is not set -CONFIG_DM9102=m -CONFIG_DMA_ENGINE_RAID=y -# CONFIG_DMARD09 is not set -# CONFIG_DMARD10 is not set -CONFIG_DM_BIO_PRISON=m -CONFIG_DM_BUFIO=m -CONFIG_DM_CACHE=m -CONFIG_DM_CACHE_SMQ=m -CONFIG_DM_CLONE=m -CONFIG_DM_CRYPT=m -# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set -CONFIG_DM_ERA=m -CONFIG_DM_MIRROR=m -CONFIG_DM_PERSISTENT_DATA=m -CONFIG_DM_RAID=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_THIN_PROVISIONING=m -CONFIG_DM_WRITECACHE=m -# CONFIG_DM_ZERO is not set -CONFIG_DNET=m -CONFIG_DP83822_PHY=m -CONFIG_DP83848_PHY=m -CONFIG_DP83867_PHY=m -CONFIG_DP83869_PHY=m -CONFIG_DP83TC811_PHY=m -# CONFIG_DPS310 is not set -CONFIG_DRAGONRISE_FF=y -CONFIG_DRM_AMD_ACP=y -CONFIG_DRM_AMD_DC_DCN=y -# CONFIG_DRM_AMD_DC_HDCP is not set -CONFIG_DRM_AMD_DC=y -CONFIG_DRM_AMDGPU_CIK=y -# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set -CONFIG_DRM_AMDGPU=m -CONFIG_DRM_AMDGPU_SI=y -CONFIG_DRM_AMDGPU_USERPTR=y -CONFIG_DRM_ANALOGIX_ANX78XX=m -CONFIG_DRM_ANALOGIX_DP=m -# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set -CONFIG_DRM_DEBUG_SELFTEST=m -CONFIG_DRM_DP_AUX_CHARDEV=y -CONFIG_DRM_EXPORT_FOR_TESTS=y -# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set -CONFIG_DRM_GEM_SHMEM_HELPER=y -CONFIG_DRM_GMA3600=y -CONFIG_DRM_GMA500=m -CONFIG_DRM_GMA600=y -CONFIG_DRM_I2C_CH7006=m -CONFIG_DRM_I2C_NXP_TDA9950=m -CONFIG_DRM_I2C_NXP_TDA998X=m -CONFIG_DRM_I2C_SIL164=m -# CONFIG_DRM_I915_DEBUG_GUC is not set -# CONFIG_DRM_I915_DEBUG is not set -# CONFIG_DRM_I915_DEBUG_MMIO is not set -# CONFIG_DRM_I915_DEBUG_RUNTIME_PM is not set -# CONFIG_DRM_I915_DEBUG_VBLANK_EVADE is not set -CONFIG_DRM_I915_FORCE_PROBE="*" -CONFIG_DRM_I915_GVT_KVMGT=m -CONFIG_DRM_I915_GVT=y -# CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS is not set -CONFIG_DRM_I915=m -# CONFIG_DRM_I915_SELFTEST is not set -# CONFIG_DRM_I915_SW_FENCE_CHECK_DAG is not set -# CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS is not set -# CONFIG_DRM_I915_WERROR is not set -CONFIG_DRM_KMS_HELPER=m -CONFIG_DRM_LEGACY=y -CONFIG_DRM_LIB_RANDOM=y -CONFIG_DRM=m -CONFIG_DRM_MGA=m -CONFIG_DRM_NOUVEAU_BACKLIGHT=y -CONFIG_DRM_NOUVEAU=m -CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -CONFIG_DRM_RADEON_USERPTR=y -CONFIG_DRM_SAVAGE=m -CONFIG_DRM_SCHED=m -CONFIG_DRM_SIS=m -CONFIG_DRM_TDFX=m -CONFIG_DRM_TTM_DMA_PAGE_POOL=y -CONFIG_DRM_TTM=m -CONFIG_DRM_UDL=m -CONFIG_DRM_VGEM=m -CONFIG_DRM_VIA=m -CONFIG_DRM_VIRTIO_GPU=m -CONFIG_DRM_VKMS=m -CONFIG_DRM_VMWGFX_FBCON=y -CONFIG_DRM_VMWGFX=m -CONFIG_DRM_VM=y -# CONFIG_DS1803 is not set -# CONFIG_DS4424 is not set -CONFIG_DUMMY=m -CONFIG_DVB_A8293=m -CONFIG_DVB_AF9013=m -CONFIG_DVB_AF9033=m -CONFIG_DVB_AS102_FE=m -CONFIG_DVB_AS102=m -CONFIG_DVB_ASCOT2E=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_AU8522_DTV=m -CONFIG_DVB_AU8522=m -CONFIG_DVB_AU8522_V4L=m -CONFIG_DVB_AV7110_IR=y -CONFIG_DVB_AV7110=m -CONFIG_DVB_AV7110_OSD=y -CONFIG_DVB_B2C2_FLEXCOP=m -# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set -CONFIG_DVB_B2C2_FLEXCOP_PCI=m -# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set -CONFIG_DVB_B2C2_FLEXCOP_USB=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_BT8XX=m -CONFIG_DVB_BUDGET_AV=m -CONFIG_DVB_BUDGET_CI=m -CONFIG_DVB_BUDGET_CORE=m -CONFIG_DVB_BUDGET=m -CONFIG_DVB_BUDGET_PATCH=m -CONFIG_DVB_CORE=m -CONFIG_DVB_CX22700=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_CX24110=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_CX24117=m -CONFIG_DVB_CX24120=m -CONFIG_DVB_CX24123=m -CONFIG_DVB_CXD2099=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_CXD2841ER=m -CONFIG_DVB_DDBRIDGE=m -# CONFIG_DVB_DDBRIDGE_MSIENABLE is not set -# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_DIB9000=m -CONFIG_DVB_DM1105=m -CONFIG_DVB_DRX39XYJ=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_DRXK=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_DUMMY_FE=m -# CONFIG_DVB_DYNAMIC_MINORS is not set -CONFIG_DVB_EC100=m -# CONFIG_DVB_FIREDTV is not set -CONFIG_DVB_GP8PSK_FE=m -CONFIG_DVB_HELENE=m -CONFIG_DVB_HOPPER=m -CONFIG_DVB_HORUS3A=m -CONFIG_DVB_ISL6405=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_ISL6423=m -CONFIG_DVB_IX2505V=m -CONFIG_DVB_L64781=m -CONFIG_DVB_LG2160=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_LGDT3306A=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGS8GL5=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_LNBH25=m -CONFIG_DVB_LNBH29=m -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m -CONFIG_DVB_M88DS3103=m -CONFIG_DVB_M88RS2000=m -CONFIG_DVB_MANTIS=m -CONFIG_DVB_MAX_ADAPTERS=8 -CONFIG_DVB_MB86A16=m -CONFIG_DVB_MB86A20S=m -# CONFIG_DVB_MMAP is not set -CONFIG_DVB_MN88443X=m -CONFIG_DVB_MN88472=m -CONFIG_DVB_MN88473=m -CONFIG_DVB_MT312=m -CONFIG_DVB_MT352=m -CONFIG_DVB_MXL5XX=m -CONFIG_DVB_NET=y -CONFIG_DVB_NGENE=m -CONFIG_DVB_NXT200X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_OR51132=m -CONFIG_DVB_OR51211=m -CONFIG_DVB_PLATFORM_DRIVERS=y -CONFIG_DVB_PLL=m -CONFIG_DVB_PLUTO2=m -CONFIG_DVB_PT1=m -CONFIG_DVB_PT3=m -CONFIG_DVB_RTL2830=m -CONFIG_DVB_RTL2832=m -CONFIG_DVB_RTL2832_SDR=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_S5H1411=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_S5H1432=m -CONFIG_DVB_S921=m -CONFIG_DVB_SI2165=m -CONFIG_DVB_SI2168=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_SMIPCIE=m -CONFIG_DVB_SP2=m -CONFIG_DVB_SP8870=m -CONFIG_DVB_SP887X=m -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STV0297=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV0367=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV0910=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV6110x=m -CONFIG_DVB_STV6111=m -CONFIG_DVB_TC90522=m -CONFIG_DVB_TDA10021=m -CONFIG_DVB_TDA10023=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_TDA10071=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA18271C2DD=m -CONFIG_DVB_TDA665x=m -CONFIG_DVB_TDA8083=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TS2020=m -CONFIG_DVB_TTUSB_BUDGET=m -CONFIG_DVB_TTUSB_DEC=m -CONFIG_DVB_TUA6100=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m -CONFIG_DVB_TUNER_ITD1000=m -# CONFIG_DVB_ULE_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_AF9035=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_CINERGY_T2=m -# CONFIG_DVB_USB_CXUSB_ANALOG is not set -CONFIG_DVB_USB_CXUSB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_DIB3000MC=m -# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_DVBSKY=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_V2=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_ZD1301=m -CONFIG_DVB_VES1820=m -CONFIG_DVB_VES1X93=m -CONFIG_DVB_ZD1301_DEMOD=m -CONFIG_DVB_ZL10036=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_ZL10353=m -CONFIG_DWC_XLGMAC=m -CONFIG_DWC_XLGMAC_PCI=m -CONFIG_DW_DMAC=m -CONFIG_DW_DMAC_PCI=y -CONFIG_DW_EDMA=m -CONFIG_DW_EDMA_PCIE=m -CONFIG_DWMAC_GENERIC=m -CONFIG_DWMAC_INTEL=m -CONFIG_DW_WATCHDOG=m -CONFIG_E1000E=m -CONFIG_E1000=m -CONFIG_E100=m -# CONFIG_EARLY_PRINTK_DBGP is not set -CONFIG_EBC_C384_WDT=m -CONFIG_ECRYPT_FS=m -# CONFIG_ECRYPT_FS_MESSAGING is not set -# CONFIG_EDAC is not set -CONFIG_EEEPC_LAPTOP=m -CONFIG_EEEPC_WMI=m -CONFIG_EEPROM_93CX6=m -CONFIG_EEPROM_IDT_89HPESX=m -CONFIG_EFI_DEV_PATH_PARSER=y -CONFIG_EFI_FAKE_MEMMAP=y -CONFIG_EFI_MAX_FAKE_MEM=8 -CONFIG_EFI_PGT_DUMP=y -CONFIG_EFI_VARS=m -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_ENA_ETHERNET=m -CONFIG_ENCLOSURE_SERVICES=m -CONFIG_ENCRYPTED_KEYS=m -CONFIG_ENERGY_MODEL=y -CONFIG_ENIC=m -CONFIG_EPIC100=m -CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=1 -# CONFIG_EROFS_FS_DEBUG is not set -CONFIG_EROFS_FS=m -CONFIG_EROFS_FS_POSIX_ACL=y -CONFIG_EROFS_FS_SECURITY=y -CONFIG_EROFS_FS_XATTR=y -CONFIG_EROFS_FS_ZIP=y -CONFIG_ETHOC=m -CONFIG_EUROTECH_WDT=m -CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" -CONFIG_EXFAT_FS=m -CONFIG_EXPERT=y -CONFIG_EXT2_FS=m -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT3_FS=m -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4_FS=m -CONFIG_EXTCON_ADC_JACK=m -CONFIG_EXTCON_AXP288=m -CONFIG_EXTCON_FSA9480=m -CONFIG_EXTCON_GPIO=m -CONFIG_EXTCON_INTEL_INT3496=m -CONFIG_EXTCON_INTEL_MRFLD=m -CONFIG_EXTCON_MAX14577=m -# CONFIG_EXTCON_MAX3355 is not set -CONFIG_EXTCON_MAX77693=m -CONFIG_EXTCON_PTN5150=m -CONFIG_EXTCON_RT8973A=m -CONFIG_EXTCON_SM5502=m -CONFIG_EXTCON_USB_GPIO=m -CONFIG_EXTCON=y -# CONFIG_F2FS_CHECK_FS is not set -# CONFIG_F2FS_FAULT_INJECTION is not set -CONFIG_F2FS_FS_COMPRESSION=y -CONFIG_F2FS_FS_LZ4=y -CONFIG_F2FS_FS_LZORLE=y -CONFIG_F2FS_FS_LZO=y -CONFIG_F2FS_FS=m -CONFIG_F2FS_FS_POSIX_ACL=y -CONFIG_F2FS_FS_SECURITY=y -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_FS_ZSTD=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FAILOVER=m -CONFIG_FANOTIFY=y -CONFIG_FAT_DEFAULT_CODEPAGE=866 -CONFIG_FAT_DEFAULT_IOCHARSET="utf8" -CONFIG_FAT_DEFAULT_UTF8=y -CONFIG_FAT_FS=m -CONFIG_FB_BOOT_VESA_SUPPORT=y -CONFIG_FB_HYPERV=m -# CONFIG_FB_INTEL is not set -CONFIG_FB_SIMPLE=y -# CONFIG_FB_SM750 is not set -CONFIG_FB_SYS_COPYAREA=m -CONFIG_FB_SYS_FILLRECT=m -CONFIG_FB_SYS_FOPS=m -CONFIG_FB_SYS_IMAGEBLIT=m -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_VESA=y -# CONFIG_FB_VIA is not set -CONFIG_FCOE_FNIC=m -CONFIG_FCOE=m -CONFIG_FEALNX=m -# CONFIG_FIELDBUS_DEV is not set -CONFIG_FIREWIRE=m -# CONFIG_FIREWIRE_NET is not set -CONFIG_FIREWIRE_OHCI=m -CONFIG_FIREWIRE_SBP2=m -# CONFIG_FIREWIRE_SERIAL is not set -CONFIG_FIRMWARE_EDID=y -CONFIG_FIXED_PHY=m -CONFIG_FM10K=m -CONFIG_FORCEDETH=m -CONFIG_FRAME_VECTOR=y -CONFIG_FRAME_WARN=1024 -CONFIG_FRONTSWAP=y -# CONFIG_FSCACHE_DEBUG is not set -# CONFIG_FSCACHE_HISTOGRAM is not set -CONFIG_FSCACHE=m -# CONFIG_FSCACHE_OBJECT_LIST is not set -CONFIG_FSCACHE_STATS=y -CONFIG_FS_DAX=y -CONFIG_FS_MBCACHE=m -# CONFIG_FTRACE is not set -CONFIG_FUJITSU_ES=m -CONFIG_FUJITSU_LAPTOP=m -CONFIG_FUJITSU_TABLET=m -CONFIG_FUSE_FS=m -CONFIG_FUSION_CTL=m -CONFIG_FUSION_FC=m -# CONFIG_FUSION_LOGGING is not set -CONFIG_FUSION_MAX_SGE=128 -CONFIG_FUSION_SAS=m -CONFIG_FUSION_SPI=m -CONFIG_FUSION=y -CONFIG_FW_CFG_SYSFS_CMDLINE=y -CONFIG_FW_CFG_SYSFS=m -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -CONFIG_FW_LOADER_USER_HELPER=y -# CONFIG_FXAS21002C is not set -# CONFIG_FXOS8700_I2C is not set -CONFIG_GACT_PROB=y -CONFIG_GAMEPORT_EMU10K1=m -# CONFIG_GAMEPORT_FM801 is not set -# CONFIG_GAMEPORT_L4 is not set -CONFIG_GAMEPORT=m -# CONFIG_GAMEPORT_NS558 is not set -CONFIG_GART_IOMMU=y -# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set -# CONFIG_GENERIC_ADC_BATTERY is not set -CONFIG_GENERIC_ADC_THERMAL=m -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENEVE=m -CONFIG_GENWQE=m -CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=0 -CONFIG_GFS2_FS_LOCKING_DLM=y -CONFIG_GFS2_FS=m -# CONFIG_GP2AP002 is not set -# CONFIG_GP2AP020A00F is not set -CONFIG_GPD_POCKET_FAN=m -CONFIG_GPIO_ACPI=y -# CONFIG_GPIO_ADP5588 is not set -# CONFIG_GPIO_AGGREGATOR is not set -# CONFIG_GPIO_AMD8111 is not set -CONFIG_GPIO_AMD_FCH=m -# CONFIG_GPIO_AMDPT is not set -# CONFIG_GPIO_DLN2 is not set -# CONFIG_GPIO_DWAPB is not set -# CONFIG_GPIO_EXAR is not set -# CONFIG_GPIO_F7188X is not set -# CONFIG_GPIO_GENERIC_PLATFORM is not set -# CONFIG_GPIO_ICH is not set -# CONFIG_GPIO_IT87 is not set -CONFIG_GPIOLIB_FASTPATH_LIMIT=512 -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIOLIB=y -# CONFIG_GPIO_LP873X is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_MB86S7X is not set -# CONFIG_GPIO_ML_IOH is not set -# CONFIG_GPIO_MOCKUP is not set -# CONFIG_GPIO_MSIC is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_PCIE_IDIO_24 is not set -# CONFIG_GPIO_PCI_IDIO_16 is not set -# CONFIG_GPIO_RDC321X is not set -# CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_SCH is not set -# CONFIG_GPIO_SYSFS is not set -# CONFIG_GPIO_TPIC2810 is not set -# CONFIG_GPIO_TPS65086 is not set -# CONFIG_GPIO_TPS65912 is not set -# CONFIG_GPIO_TQMX86 is not set -# CONFIG_GPIO_VIPERBOARD is not set -# CONFIG_GPIO_VX855 is not set -# CONFIG_GPIO_WHISKEY_COVE is not set -# CONFIG_GPIO_WINBOND is not set -# CONFIG_GPIO_WS16C48 is not set -# CONFIG_GPIO_XILINX is not set -CONFIG_GRACE_PERIOD=m -CONFIG_GREENASIA_FF=y -# CONFIG_GS_FPGABOOT is not set -CONFIG_GTP=m -CONFIG_GVE=m -CONFIG_HABANA_AI=m -CONFIG_HALTPOLL_CPUIDLE=y -CONFIG_HAMACHI=m -CONFIG_HAPPYMEAL=m -CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y -CONFIG_HAVE_KVM_EVENTFD=y -CONFIG_HAVE_KVM_IRQ_BYPASS=y -CONFIG_HAVE_KVM_IRQCHIP=y -CONFIG_HAVE_KVM_IRQFD=y -CONFIG_HAVE_KVM_IRQ_ROUTING=y -CONFIG_HAVE_KVM_MSI=y -CONFIG_HAVE_KVM_NO_POLL=y -# CONFIG_HDC100X is not set -CONFIG_HDMI_LPE_AUDIO=m -CONFIG_HERMES_CACHE_FW_ON_INIT=y -CONFIG_HERMES=m -CONFIG_HERMES_PRISM=y -CONFIG_HFSPLUS_FS=m -CONFIG_HID_ACCUTOUCH=m -CONFIG_HID_ACRUX_FF=y -CONFIG_HID_ACRUX=m -CONFIG_HID_ALPS=m -CONFIG_HID_ASUS=m -CONFIG_HID_CMEDIA=m -CONFIG_HID_CORSAIR=y -CONFIG_HID_COUGAR=m -# CONFIG_HID_CP2112 is not set -CONFIG_HID_CREATIVE_SB0540=m -CONFIG_HID_DRAGONRISE=m -CONFIG_HID_ELAN=m -CONFIG_HID_ELECOM=m -CONFIG_HID_ELO=m -CONFIG_HID_EMS_FF=m -CONFIG_HID_GFRM=m -CONFIG_HID_GLORIOUS=m -CONFIG_HID_GREENASIA=m -CONFIG_HID_GT683R=m -CONFIG_HID_GYRATION=m -CONFIG_HID_HOLTEK=m -CONFIG_HID_HYPERV_MOUSE=m -CONFIG_HID_ICADE=m -CONFIG_HID_ITE=m -CONFIG_HID_KEYTOUCH=m -CONFIG_HID_KYE=y -CONFIG_HID_LCPOWER=m -CONFIG_HID_LED=m -CONFIG_HID_LENOVO=m -CONFIG_HID_LOGITECH_DJ=m -CONFIG_HID_LOGITECH_HIDPP=m -CONFIG_HID_MACALLY=m -CONFIG_HID_MAGICMOUSE=m -CONFIG_HID_MALTRON=m -CONFIG_HID_MAYFLASH=m -CONFIG_HID_MCP2221=m -CONFIG_HID_MULTITOUCH=m -CONFIG_HID_NTI=m -CONFIG_HID_NTRIG=m -CONFIG_HID_ORTEK=m -CONFIG_HID_PANTHERLORD=m -CONFIG_HID_PENMOUNT=m -CONFIG_HID_PETALYNX=m -CONFIG_HID_PICOLCD_BACKLIGHT=y -CONFIG_HID_PICOLCD_CIR=y -CONFIG_HID_PICOLCD_FB=y -CONFIG_HID_PICOLCD_LCD=y -CONFIG_HID_PICOLCD_LEDS=y -CONFIG_HID_PICOLCD=m -CONFIG_HID_PLANTRONICS=y -CONFIG_HID_PRIMAX=m -CONFIG_HID_PRODIKEYS=m -CONFIG_HID_REDRAGON=m -CONFIG_HID_RETRODE=m -CONFIG_HID_RMI=m -CONFIG_HID_ROCCAT=m -CONFIG_HID_SAITEK=m -CONFIG_HID_SAMSUNG=m -# CONFIG_HID_SENSOR_ACCEL_3D is not set -# CONFIG_HID_SENSOR_ALS is not set -CONFIG_HID_SENSOR_CUSTOM_SENSOR=m -# CONFIG_HID_SENSOR_DEVICE_ROTATION is not set -# CONFIG_HID_SENSOR_GYRO_3D is not set -CONFIG_HID_SENSOR_HUB=m -# CONFIG_HID_SENSOR_HUMIDITY is not set -CONFIG_HID_SENSOR_IIO_COMMON=m -CONFIG_HID_SENSOR_IIO_TRIGGER=m -# CONFIG_HID_SENSOR_INCLINOMETER_3D is not set -# CONFIG_HID_SENSOR_MAGNETOMETER_3D is not set -# CONFIG_HID_SENSOR_PRESS is not set -# CONFIG_HID_SENSOR_PROX is not set -CONFIG_HID_SENSOR_TEMP=m -CONFIG_HID_SMARTJOYPLUS=y -CONFIG_HID_SONY=m -CONFIG_HID_SPEEDLINK=m -CONFIG_HID_STEAM=m -CONFIG_HID_STEELSERIES=m -CONFIG_HID_SUNPLUS=m -CONFIG_HID_THINGM=m -CONFIG_HID_THRUSTMASTER=y -CONFIG_HID_TIVO=m -CONFIG_HID_TWINHAN=m -CONFIG_HID_U2FZERO=m -CONFIG_HID_UCLOGIC=m -CONFIG_HID_UDRAW_PS3=m -CONFIG_HID_VIEWSONIC=m -CONFIG_HID_WACOM=m -CONFIG_HID_WALTOP=m -CONFIG_HID_WIIMOTE=m -CONFIG_HID_XINMO=m -CONFIG_HID_ZEROPLUS=y -CONFIG_HID_ZYDACRON=m -# CONFIG_HMC425 is not set -CONFIG_HMM_MIRROR=y -CONFIG_HOLTEK_FF=y -CONFIG_HOSTAP_CS=m -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP=m -CONFIG_HOSTAP_PCI=m -CONFIG_HOSTAP_PLX=m -CONFIG_HOTPLUG_PCI_ACPI_IBM=m -CONFIG_HOTPLUG_PCI_ACPI=y -CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m -CONFIG_HOTPLUG_PCI_CPCI=y -CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m -CONFIG_HOTPLUG_PCI_SHPC=y -# CONFIG_HP03 is not set -# CONFIG_HP206C is not set -CONFIG_HP_ACCEL=m -# CONFIG_HPET is not set -CONFIG_HP_WATCHDOG=m -# CONFIG_HPWDT_NMI_DECODING is not set -CONFIG_HP_WIRELESS=m -CONFIG_HP_WMI=m -CONFIG_HSA_AMD=y -CONFIG_HSR=m -# CONFIG_HTS221 is not set -# CONFIG_HTU21 is not set -CONFIG_HUAWEI_WMI=m -CONFIG_HVC_DRIVER=y -CONFIG_HWMON=m -CONFIG_HWMON_VID=m -CONFIG_HW_RANDOM_AMD=m -CONFIG_HW_RANDOM_INTEL=m -CONFIG_HW_RANDOM=m -CONFIG_HW_RANDOM_VIA=m -# CONFIG_HW_RANDOM_VIRTIO is not set -# CONFIG_HX711 is not set -CONFIG_HYPERV_BALLOON=m -CONFIG_HYPERV_IOMMU=y -CONFIG_HYPERVISOR_GUEST=y -CONFIG_HYPERV_KEYBOARD=m -CONFIG_HYPERV=m -CONFIG_HYPERV_NET=m -CONFIG_HYPERV_STORAGE=m -# CONFIG_HYPERV_TESTING is not set -CONFIG_HYPERV_TIMER=y -CONFIG_HYPERV_UTILS=m -CONFIG_HYPERV_VSOCKETS=m -CONFIG_I2C_ALGOBIT=m -CONFIG_I2C_ALGOPCA=m -CONFIG_I2C_ALI1535=m -CONFIG_I2C_ALI1563=m -CONFIG_I2C_ALI15X3=m -CONFIG_I2C_AMD756=m -CONFIG_I2C_AMD756_S4882=m -CONFIG_I2C_AMD8111=m -CONFIG_I2C_AMD_MP2=m -# CONFIG_I2C_CBUS_GPIO is not set -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_DESIGNWARE_BAYTRAIL=y -CONFIG_I2C_DESIGNWARE_CORE=m -CONFIG_I2C_DESIGNWARE_PCI=m -CONFIG_I2C_DESIGNWARE_PLATFORM=m -CONFIG_I2C_DESIGNWARE_SLAVE=y -CONFIG_I2C_DIOLAN_U2C=m -CONFIG_I2C_DLN2=m -CONFIG_I2C_EMEV2=m -# CONFIG_I2C_GPIO is not set -CONFIG_I2C_HID=m -CONFIG_I2C_I801=m -CONFIG_I2C_ISCH=m -CONFIG_I2C_ISMT=m -CONFIG_I2C=m -CONFIG_I2C_MLXCPLD=m -CONFIG_I2C_MULTI_INSTANTIATE=m -CONFIG_I2C_MUX_GPIO=m -CONFIG_I2C_MUX_LTC4306=m -CONFIG_I2C_MUX=m -CONFIG_I2C_MUX_MLXCPLD=m -CONFIG_I2C_MUX_PCA9541=m -CONFIG_I2C_MUX_PCA954x=m -CONFIG_I2C_MUX_REG=m -CONFIG_I2C_NFORCE2=m -CONFIG_I2C_NFORCE2_S4985=m -CONFIG_I2C_NVIDIA_GPU=m -CONFIG_I2C_OCORES=m -CONFIG_I2C_PARPORT=m -CONFIG_I2C_PCA_PLATFORM=m -CONFIG_I2C_PIIX4=m -CONFIG_I2C_ROBOTFUZZ_OSIF=m -CONFIG_I2C_SCMI=m -CONFIG_I2C_SI470X=m -CONFIG_I2C_SI4713=m -CONFIG_I2C_SIMTEC=m -CONFIG_I2C_SIS5595=m -CONFIG_I2C_SIS630=m -CONFIG_I2C_SIS96X=m -CONFIG_I2C_SLAVE_EEPROM=m -CONFIG_I2C_SLAVE=y -CONFIG_I2C_SMBUS=m -CONFIG_I2C_STUB=m -CONFIG_I2C_TAOS_EVM=m -CONFIG_I2C_TINY_USB=m -CONFIG_I2C_VIA=m -CONFIG_I2C_VIAPRO=m -CONFIG_I2C_VIPERBOARD=m -CONFIG_I2C_XILINX=m -CONFIG_I40E=m -CONFIG_I40EVF=m -CONFIG_I6300ESB_WDT=m -CONFIG_I82092=m -CONFIG_I8K=m -# CONFIG_IAQCORE is not set -CONFIG_IAVF=m -CONFIG_IB700_WDT=m -CONFIG_IBM_ASM=m -CONFIG_IBMASR=m -CONFIG_IBM_RTL=m -CONFIG_ICE=m -# CONFIG_ICP10100 is not set -CONFIG_ICPLUS_PHY=m -CONFIG_IDEAPAD_LAPTOP=m -CONFIG_IE6XX_WDT=m -CONFIG_IFB=m -CONFIG_IGB_DCA=y -CONFIG_IGB_HWMON=y -CONFIG_IGB=m -CONFIG_IGBVF=m -CONFIG_IGC=m -CONFIG_IIO_BUFFER_CB=m -# CONFIG_IIO_BUFFER_HW_CONSUMER is not set -CONFIG_IIO_BUFFER=y -CONFIG_IIO_CONFIGFS=m -CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -# CONFIG_IIO_HRTIMER_TRIGGER is not set -CONFIG_IIO_INTERRUPT_TRIGGER=m -CONFIG_IIO_KFIFO_BUF=m -CONFIG_IIO=m -# CONFIG_IIO_SIMPLE_DUMMY is not set -# CONFIG_IIO_ST_ACCEL_3AXIS is not set -# CONFIG_IIO_ST_GYRO_3AXIS is not set -# CONFIG_IIO_ST_LSM6DSX is not set -# CONFIG_IIO_ST_MAGN_3AXIS is not set -# CONFIG_IIO_ST_PRESS is not set -CONFIG_IIO_SW_DEVICE=m -CONFIG_IIO_SW_TRIGGER=m -CONFIG_IIO_SYSFS_TRIGGER=m -CONFIG_IIO_TIGHTLOOP_TRIGGER=m -CONFIG_IIO_TRIGGERED_BUFFER=m -CONFIG_IIO_TRIGGER=y -CONFIG_IKCONFIG_PROC=y -CONFIG_IKCONFIG=y -# CONFIG_INA2XX_ADC is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESPINTCP=y -CONFIG_INET6_ESP=m -CONFIG_INET6_ESP_OFFLOAD=m -CONFIG_INET6_IPCOMP=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET_AH=m -# CONFIG_INET_DIAG_DESTROY is not set -CONFIG_INET_DIAG=m -# CONFIG_INET_ESPINTCP is not set -CONFIG_INET_ESP=m -CONFIG_INET_ESP_OFFLOAD=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_RAW_DIAG=m -CONFIG_INET_SCTP_DIAG=m -CONFIG_INET_TCP_DIAG=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_UDP_DIAG=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INPUT_88PM80X_ONKEY=m -# CONFIG_INPUT_AXP20X_PEK is not set -CONFIG_INPUT_BMA150=m -# CONFIG_INPUT_DA9063_ONKEY is not set -# CONFIG_INPUT_DRV260X_HAPTICS is not set -# CONFIG_INPUT_GPIO_BEEPER is not set -# CONFIG_INPUT_GPIO_DECODER is not set -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -# CONFIG_INPUT_GPIO_VIBRA is not set -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_MATRIXKMAP=m -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_PCSPKR=m -CONFIG_INPUT_POLLDEV=m -# CONFIG_INPUT_REGULATOR_HAPTIC is not set -# CONFIG_INPUT_RETU_PWRBUTTON is not set -CONFIG_INPUT_SPARSEKMAP=m -CONFIG_INPUT_UINPUT=m -CONFIG_INPUT_YEALINK=m -CONFIG_INT3406_THERMAL=m -CONFIG_INT340X_THERMAL=m -CONFIG_INTEL_ATOMISP2_PM=m -CONFIG_INTEL_BXT_PMIC_THERMAL=m -CONFIG_INTEL_BXTWC_PMIC_TMU=m -CONFIG_INTEL_GTT=m -CONFIG_INTEL_HID_EVENT=m -CONFIG_INTEL_IDLE=y -CONFIG_INTEL_IDMA64=m -CONFIG_INTEL_IDXD=m -CONFIG_INTEL_INT0002_VGPIO=m -CONFIG_INTEL_IOATDMA=m -CONFIG_INTEL_IOMMU_DEFAULT_ON=y -CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON=y -CONFIG_INTEL_IOMMU_SVM=y -CONFIG_INTEL_IPS=m -CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER=m -CONFIG_INTEL_ISH_HID=m -CONFIG_INTEL_MEI_HDCP=m -CONFIG_INTEL_MEI=m -CONFIG_INTEL_MEI_ME=m -CONFIG_INTEL_MEI_TXE=m -CONFIG_INTEL_MEI_WDT=m -CONFIG_INTEL_MENLOW=m -CONFIG_INTEL_MFLD_THERMAL=m -CONFIG_INTEL_MIC_BUS=m -# CONFIG_INTEL_MIC_X100_DMA is not set -CONFIG_INTEL_MID_POWER_BUTTON=m -# CONFIG_INTEL_MRFLD_ADC is not set -CONFIG_INTEL_MRFLD_PWRBTN=m -CONFIG_INTEL_OAKTRAIL=m -CONFIG_INTEL_PCH_THERMAL=m -CONFIG_INTEL_PMC_CORE=y -CONFIG_INTEL_POWERCLAMP=m -CONFIG_INTEL_PUNIT_IPC=m -CONFIG_INTEL_RST=m -CONFIG_INTEL_SCU_IPC_UTIL=m -CONFIG_INTEL_SCU_IPC=y -CONFIG_INTEL_SCU_PCI=y -CONFIG_INTEL_SCU_PLATFORM=m -CONFIG_INTEL_SCU=y -CONFIG_INTEL_SMARTCONNECT=m -CONFIG_INTEL_SOC_DTS_IOSF_CORE=m -CONFIG_INTEL_SOC_DTS_THERMAL=m -CONFIG_INTEL_SOC_PMIC_BXTWC=m -# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set -CONFIG_INTEL_SOC_PMIC_MRFLD=m -CONFIG_INTEL_SPEED_SELECT_INTERFACE=m -CONFIG_INTEL_TELEMETRY=m -CONFIG_INTEL_TURBO_MAX_3=y -CONFIG_INTEL_UNCORE_FREQ_CONTROL=m -CONFIG_INTEL_VBTN=m -CONFIG_INTEL_WMI_SBL_FW_UPDATE=m -CONFIG_INTEL_WMI_THUNDERBOLT=m -CONFIG_INTEL_XWAY_PHY=m -# CONFIG_INV_MPU6050_I2C is not set -# CONFIG_IOMMU_DEBUG is not set -CONFIG_IOMMU_HELPER=y -CONFIG_IONIC=m -CONFIG_IOSCHED_BFQ=y -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_RPFILTER=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m -CONFIG_IP6_NF_TARGET_NPT=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP_FIB_TRIE_STATS=y -# CONFIG_IPMB_DEVICE_INTERFACE is not set -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_DMI_DECODE=y -CONFIG_IPMI_HANDLER=m -# CONFIG_IPMI_PANIC_EVENT is not set -CONFIG_IPMI_PLAT_DATA=y -# CONFIG_IPMI_POWEROFF is not set -CONFIG_IPMI_SI=m -# CONFIG_IPMI_SSIF is not set -# CONFIG_IPMI_WATCHDOG is not set -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_RPFILTER=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_TARGET_TTL=m -# CONFIG_IP_PIMSM_V1 is not set -# CONFIG_IP_PIMSM_V2 is not set -# CONFIG_IP_PNP is not set -CONFIG_IP_ROUTE_CLASSID=y -CONFIG_IP_SCTP=m -CONFIG_IP_SET_BITMAP_IP=m -CONFIG_IP_SET_BITMAP_IPMAC=m -CONFIG_IP_SET_BITMAP_PORT=m -CONFIG_IP_SET_HASH_IP=m -CONFIG_IP_SET_HASH_IPMAC=m -CONFIG_IP_SET_HASH_IPMARK=m -CONFIG_IP_SET_HASH_IPPORTIP=m -CONFIG_IP_SET_HASH_IPPORT=m -CONFIG_IP_SET_HASH_IPPORTNET=m -CONFIG_IP_SET_HASH_MAC=m -CONFIG_IP_SET_HASH_NETIFACE=m -CONFIG_IP_SET_HASH_NET=m -CONFIG_IP_SET_HASH_NETNET=m -CONFIG_IP_SET_HASH_NETPORT=m -CONFIG_IP_SET_HASH_NETPORTNET=m -CONFIG_IP_SET_LIST_SET=m -CONFIG_IP_SET=m -CONFIG_IP_SET_MAX=256 -CONFIG_IPV6_GRE=m -CONFIG_IPV6_ILA=m -CONFIG_IPV6_MIP6=m -CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_ROUTE_INFO is not set -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_RPL_LWTUNNEL=y -CONFIG_IPV6_SEG6_BPF=y -CONFIG_IPV6_SEG6_HMAC=y -CONFIG_IPV6_SEG6_LWTUNNEL=y -CONFIG_IPV6_SIT=m -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_VTI=m -CONFIG_IPVLAN_L3S=y -CONFIG_IPVLAN=m -# CONFIG_IP_VS_DEBUG is not set -# CONFIG_IP_VS_DH is not set -# CONFIG_IP_VS_FO is not set -# CONFIG_IP_VS_FTP is not set -# CONFIG_IP_VS_IPV6 is not set -# CONFIG_IP_VS_LBLC is not set -# CONFIG_IP_VS_LBLCR is not set -# CONFIG_IP_VS_LC is not set -CONFIG_IP_VS=m -# CONFIG_IP_VS_MH is not set -CONFIG_IP_VS_MH_TAB_INDEX=12 -CONFIG_IP_VS_NFCT=y -# CONFIG_IP_VS_NQ is not set -# CONFIG_IP_VS_OVF is not set -# CONFIG_IP_VS_PE_SIP is not set -# CONFIG_IP_VS_PROTO_AH is not set -# CONFIG_IP_VS_PROTO_ESP is not set -# CONFIG_IP_VS_PROTO_SCTP is not set -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_RR=m -# CONFIG_IP_VS_SED is not set -# CONFIG_IP_VS_SH is not set -CONFIG_IP_VS_SH_TAB_BITS=8 -CONFIG_IP_VS_TAB_BITS=12 -# CONFIG_IP_VS_WLC is not set -# CONFIG_IP_VS_WRR is not set -CONFIG_IPVTAP=m -# CONFIG_IPW2100_DEBUG is not set -CONFIG_IPW2100=m -CONFIG_IPW2100_MONITOR=y -# CONFIG_IPW2200_DEBUG is not set -CONFIG_IPW2200=m -CONFIG_IPW2200_MONITOR=y -CONFIG_IPW2200_PROMISCUOUS=y -CONFIG_IPW2200_QOS=y -CONFIG_IPW2200_RADIOTAP=y -# CONFIG_IQS620AT_TEMP is not set -# CONFIG_IQS621_ALS is not set -# CONFIG_IQS624_POS is not set -CONFIG_IRQ_BYPASS_MANAGER=m -CONFIG_IRQ_POLL=y -CONFIG_IRQ_REMAP=y -CONFIG_ISA_BUS_API=y -# CONFIG_ISA_BUS is not set -CONFIG_ISCSI_BOOT_SYSFS=m -# CONFIG_ISCSI_IBFT is not set -CONFIG_ISCSI_TCP=m -# CONFIG_ISL29125 is not set -# CONFIG_ISL29501 is not set -CONFIG_ISO9660_FS=m -CONFIG_IT8712F_WDT=m -CONFIG_IT87_WDT=m -CONFIG_ITCO_VENDOR_SUPPORT=y -CONFIG_ITCO_WDT=m -# CONFIG_ITG3200 is not set -CONFIG_IWL3945=m -CONFIG_IWL4965=m -CONFIG_IWLDVM=m -# CONFIG_IWLEGACY_DEBUG is not set -CONFIG_IWLEGACY=m -CONFIG_IWLMVM=m -CONFIG_IWLWIFI_BCAST_FILTERING=y -# CONFIG_IWLWIFI_DEBUG is not set -CONFIG_IWLWIFI_LEDS=y -CONFIG_IWLWIFI=m -CONFIG_IWLWIFI_OPMODE_MODULAR=y -CONFIG_IXGBE_DCA=y -CONFIG_IXGBE_HWMON=y -CONFIG_IXGBE_IPSEC=y -CONFIG_IXGBE=m -CONFIG_IXGBEVF_IPSEC=y -CONFIG_IXGBEVF=m -CONFIG_IXGB=m -# CONFIG_JAILHOUSE_GUEST is not set -CONFIG_JBD2=m -# CONFIG_JFS_DEBUG is not set -CONFIG_JFS_FS=m -CONFIG_JFS_POSIX_ACL=y -CONFIG_JFS_SECURITY=y -CONFIG_JFS_STATISTICS=y -CONFIG_JME=m -CONFIG_JOYSTICK_A3D=m -CONFIG_JOYSTICK_ADI=m -CONFIG_JOYSTICK_ANALOG=m -CONFIG_JOYSTICK_AS5011=m -CONFIG_JOYSTICK_COBRA=m -CONFIG_JOYSTICK_DB9=m -CONFIG_JOYSTICK_FSIA6B=m -CONFIG_JOYSTICK_GAMECON=m -CONFIG_JOYSTICK_GF2K=m -CONFIG_JOYSTICK_GRIP=m -CONFIG_JOYSTICK_GRIP_MP=m -CONFIG_JOYSTICK_GUILLEMOT=m -CONFIG_JOYSTICK_IFORCE_232=m -CONFIG_JOYSTICK_IFORCE=m -CONFIG_JOYSTICK_IFORCE_USB=m -CONFIG_JOYSTICK_INTERACT=m -CONFIG_JOYSTICK_JOYDUMP=m -CONFIG_JOYSTICK_MAGELLAN=m -CONFIG_JOYSTICK_PXRC=m -CONFIG_JOYSTICK_SIDEWINDER=m -CONFIG_JOYSTICK_SPACEBALL=m -CONFIG_JOYSTICK_SPACEORB=m -CONFIG_JOYSTICK_STINGER=m -CONFIG_JOYSTICK_TMDC=m -CONFIG_JOYSTICK_TURBOGRAFX=m -CONFIG_JOYSTICK_TWIDJOY=m -# CONFIG_JOYSTICK_WALKERA0701 is not set -CONFIG_JOYSTICK_WARRIOR=m -CONFIG_JOYSTICK_XPAD_FF=y -CONFIG_JOYSTICK_XPAD_LEDS=y -CONFIG_JOYSTICK_XPAD=m -CONFIG_JOYSTICK_ZHENHUA=m -# CONFIG_JSA1212 is not set -# CONFIG_JUMP_LABEL is not set -# CONFIG_KARMA_PARTITION is not set -CONFIG_KEYBOARD_ADC=m -# CONFIG_KEYBOARD_GPIO is not set -CONFIG_KEYBOARD_GPIO_POLLED=m -# CONFIG_KEYBOARD_IQS62X is not set -# CONFIG_KEYBOARD_MATRIX is not set -CONFIG_KEYBOARD_QT1050=m -CONFIG_KEYBOARD_TM2_TOUCHKEY=m -# CONFIG_KMX61 is not set -# CONFIG_KPC2000 is not set -# CONFIG_KPROBES is not set -# CONFIG_KS7010 is not set -CONFIG_KS8842=m -CONFIG_KS8851_MLL=m -CONFIG_KSM=y -CONFIG_KSZ884X_PCI=m -CONFIG_KVM_AMD=m -CONFIG_KVM_AMD_SEV=y -CONFIG_KVM_ASYNC_PF=y -CONFIG_KVM_COMPAT=y -CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y -CONFIG_KVM_GUEST=y -CONFIG_KVM_INTEL=m -CONFIG_KVM=m -CONFIG_KVM_MMIO=y -CONFIG_KVM_VFIO=y -CONFIG_KVM_WERROR=y -# CONFIG_KXCJK1013 is not set -# CONFIG_KXSD9 is not set -CONFIG_LAN743X=m -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_PLATFORM is not set -# CONFIG_LDM_PARTITION is not set -CONFIG_LEDS_BD2802=m -CONFIG_LEDS_BLINKM=m -CONFIG_LEDS_CLEVO_MAIL=m -CONFIG_LEDS_GPIO=m -CONFIG_LEDS_INTEL_SS4200=m -CONFIG_LEDS_LM3530=m -CONFIG_LEDS_LM3532=m -CONFIG_LEDS_LM355x=m -CONFIG_LEDS_LP3944=m -# CONFIG_LEDS_LP3952 is not set -CONFIG_LEDS_LP5521=m -CONFIG_LEDS_LP5523=m -CONFIG_LEDS_LP5562=m -CONFIG_LEDS_LP55XX_COMMON=m -CONFIG_LEDS_LP8501=m -CONFIG_LEDS_MLXREG=m -CONFIG_LEDS_NIC78BX=m -# CONFIG_LEDS_PCA9532_GPIO is not set -CONFIG_LEDS_PCA9532=m -# CONFIG_LEDS_PCA955X_GPIO is not set -CONFIG_LEDS_PCA955X=m -CONFIG_LEDS_PCA963X=m -CONFIG_LEDS_REGULATOR=m -CONFIG_LEDS_TCA6507=m -CONFIG_LEDS_TLC591XX=m -CONFIG_LEDS_TRIGGER_AUDIO=m -CONFIG_LEDS_TRIGGER_BACKLIGHT=m -CONFIG_LEDS_TRIGGER_CAMERA=m -CONFIG_LEDS_TRIGGER_DEFAULT_ON=m -# CONFIG_LEDS_TRIGGER_GPIO is not set -CONFIG_LEDS_TRIGGER_HEARTBEAT=m -CONFIG_LEDS_TRIGGER_ONESHOT=m -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_TRANSIENT=m -CONFIG_LEDS_USER=m -CONFIG_LEGACY_VSYSCALL_EMULATE=y -# CONFIG_LEGACY_VSYSCALL_XONLY is not set -CONFIG_LG_LAPTOP=m -CONFIG_LIB80211_CRYPT_CCMP=m -CONFIG_LIB80211_CRYPT_TKIP=m -CONFIG_LIB80211_CRYPT_WEP=m -# CONFIG_LIB80211_DEBUG is not set -CONFIG_LIB80211=m -CONFIG_LIBCRC32C=m -CONFIG_LIBERTAS_CS=m -# CONFIG_LIBERTAS_DEBUG is not set -CONFIG_LIBERTAS=m -# CONFIG_LIBERTAS_MESH is not set -CONFIG_LIBERTAS_SDIO=m -# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set -CONFIG_LIBERTAS_THINFIRM=m -CONFIG_LIBERTAS_THINFIRM_USB=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBFC=m -CONFIG_LIBFCOE=m -# CONFIG_LIBIPW_DEBUG is not set -CONFIG_LIBIPW=m -CONFIG_LIBNVDIMM=y -# CONFIG_LIDAR_LITE_V2 is not set -CONFIG_LINEAR_RANGES=y -CONFIG_LIQUIDIO=m -CONFIG_LIQUIDIO_VF=m -# CONFIG_LIRC is not set -CONFIG_LLC=m -# CONFIG_LMP91000 is not set -CONFIG_LOCKD=m -CONFIG_LOG_BUF_SHIFT=15 -CONFIG_LOGIG940_FF=y -CONFIG_LOGIRUMBLEPAD2_FF=y -# CONFIG_LOGO is not set -CONFIG_LPC_ICH=m -# CONFIG_LP_CONSOLE is not set -CONFIG_LPC_SCH=m -CONFIG_LSI_ET1011C_PHY=m -CONFIG_LSM="yama,loadpin,safesetid,integrity" -# CONFIG_LTC2471 is not set -# CONFIG_LTC2485 is not set -# CONFIG_LTC2497 is not set -CONFIG_LTE_GDM724X=m -# CONFIG_LTR501 is not set -# CONFIG_LV0104CS is not set -CONFIG_LWTUNNEL_BPF=y -CONFIG_LWTUNNEL=y -CONFIG_LXT_PHY=m -CONFIG_LZ4_COMPRESS=y -CONFIG_LZ4HC_COMPRESS=m -# CONFIG_M62332 is not set -CONFIG_MAC80211_HWSIM=m -CONFIG_MAC80211=m -CONFIG_MAC80211_MESH=y -CONFIG_MACB=m -CONFIG_MACB_PCI=m -CONFIG_MACB_USE_HWSTAMP=y -CONFIG_MACHZ_WDT=m -# CONFIG_MAC_PARTITION is not set -CONFIG_MACSEC=m -CONFIG_MACVLAN=m -CONFIG_MACVTAP=m -# CONFIG_MAG3110 is not set -# CONFIG_MANAGER_SBS is not set -CONFIG_MANTIS_CORE=m -CONFIG_MAPPING_DIRTY_HELPERS=y -CONFIG_MARVELL_10G_PHY=m -CONFIG_MARVELL_PHY=m -# CONFIG_MAX1363 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set -# CONFIG_MAX44000 is not set -# CONFIG_MAX44009 is not set -# CONFIG_MAX517 is not set -# CONFIG_MAX5432 is not set -CONFIG_MAX63XX_WATCHDOG=m -# CONFIG_MAX9611 is not set -# CONFIG_MB1232 is not set -# CONFIG_MC3230 is not set -# CONFIG_MCP3422 is not set -# CONFIG_MCP4018 is not set -# CONFIG_MCP4531 is not set -# CONFIG_MCP4725 is not set -# CONFIG_MD_CLUSTER is not set -CONFIG_MDIO_BCM_UNIMAC=m -CONFIG_MDIO_BITBANG=m -CONFIG_MDIO_BUS=m -CONFIG_MDIO_CAVIUM=m -CONFIG_MDIO_DEVICE=m -# CONFIG_MDIO_GPIO is not set -CONFIG_MDIO_I2C=m -CONFIG_MDIO=m -CONFIG_MDIO_MVUSB=m -CONFIG_MDIO_THUNDER=m -CONFIG_MDIO_XPCS=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID456=m -CONFIG_MEDIA_ALTERA_CI=m -CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_CAMERA_SUPPORT=y -# CONFIG_MEDIA_CEC_RC is not set -CONFIG_MEDIA_COMMON_OPTIONS=y -CONFIG_MEDIA_CONTROLLER_DVB=y -CONFIG_MEDIA_CONTROLLER=y -CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -CONFIG_MEDIA_PCI_SUPPORT=y -CONFIG_MEDIA_PLATFORM_SUPPORT=y -CONFIG_MEDIA_RADIO_SUPPORT=y -CONFIG_MEDIA_SDR_SUPPORT=y -CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -# CONFIG_MEDIA_SUPPORT_FILTER is not set -CONFIG_MEDIA_SUPPORT=m -CONFIG_MEDIA_TEST_SUPPORT=y -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=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_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_TUA9001=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC4000=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_USB_SUPPORT=y -CONFIG_MEGARAID_LEGACY=m -CONFIG_MEGARAID_MAILBOX=m -CONFIG_MEGARAID_MM=m -CONFIG_MEGARAID_NEWGEN=y -CONFIG_MEGARAID_SAS=m -CONFIG_MEMCG_KMEM=y -CONFIG_MEMCG_SWAP=y -CONFIG_MEMCG=y -CONFIG_MEMORY_BALLOON=y -CONFIG_MEMREGION=y -# CONFIG_MEM_SOFT_DIRTY is not set -# CONFIG_MEMSTICK_DEBUG is not set -CONFIG_MEMSTICK_JMICRON_38X=m -CONFIG_MEMSTICK=m -CONFIG_MEMSTICK_R592=m -CONFIG_MEMSTICK_REALTEK_PCI=m -CONFIG_MEMSTICK_REALTEK_USB=m -CONFIG_MEMSTICK_TIFM_MS=m -# CONFIG_MEMSTICK_UNSAFE_RESUME is not set -# CONFIG_MEN_A21_WDT is not set -CONFIG_MFD_88PM800=m -CONFIG_MFD_88PM805=m -CONFIG_MFD_AXP20X_I2C=m -CONFIG_MFD_AXP20X=m -CONFIG_MFD_BCM590XX=m -CONFIG_MFD_CORE=y -CONFIG_MFD_DA9062=m -CONFIG_MFD_DA9063=m -CONFIG_MFD_DA9150=m -CONFIG_MFD_DLN2=m -CONFIG_MFD_INTEL_LPSS_ACPI=m -CONFIG_MFD_INTEL_LPSS=m -CONFIG_MFD_INTEL_LPSS_PCI=m -CONFIG_MFD_INTEL_MSIC=y -CONFIG_MFD_INTEL_PMC_BXT=m -CONFIG_MFD_IQS62X=m -CONFIG_MFD_MAX14577=m -CONFIG_MFD_MAX77693=m -CONFIG_MFD_MAX8907=m -CONFIG_MFD_MP2629=m -CONFIG_MFD_MT6360=m -CONFIG_MFD_RETU=m -CONFIG_MFD_RT5033=m -CONFIG_MFD_SYSCON=y -CONFIG_MFD_TI_LP873X=m -CONFIG_MFD_TPS65086=m -CONFIG_MFD_TPS65912_I2C=m -CONFIG_MFD_TPS65912=m -CONFIG_MFD_TQMX86=m -CONFIG_MFD_VIPERBOARD=m -CONFIG_MFD_WL1273_CORE=m -CONFIG_MICREL_PHY=m -CONFIG_MICROCHIP_PHY=m -CONFIG_MICROCHIP_T1_PHY=m -CONFIG_MICROCODE_OLD_INTERFACE=y -CONFIG_MICROSEMI_PHY=m -CONFIG_MII=m -# CONFIG_MINIX_SUBPARTITION is not set -CONFIG_MISC_RTSX=m -CONFIG_MISC_RTSX_PCI=m -CONFIG_MISC_RTSX_USB=m -CONFIG_MLX4_CORE_GEN2=y -CONFIG_MLX4_CORE=m -CONFIG_MLX4_DEBUG=y -CONFIG_MLX4_EN=m -# CONFIG_MLX90614 is not set -# CONFIG_MLX90632 is not set -CONFIG_MLXFW=m -CONFIG_MLX_PLATFORM=m -CONFIG_MLXSW_CORE_HWMON=y -CONFIG_MLXSW_CORE=m -CONFIG_MLXSW_CORE_THERMAL=y -CONFIG_MLXSW_I2C=m -CONFIG_MLXSW_MINIMAL=m -CONFIG_MLXSW_PCI=m -CONFIG_MLXSW_SPECTRUM=m -CONFIG_MLXSW_SWITCHIB=m -CONFIG_MLXSW_SWITCHX2=m -# CONFIG_MMA7455_I2C is not set -# CONFIG_MMA7660 is not set -# CONFIG_MMA8452 is not set -# CONFIG_MMA9551 is not set -# CONFIG_MMA9553 is not set -# CONFIG_MMC35240 is not set -CONFIG_MMC_BLOCK=m -CONFIG_MMC_BLOCK_MINORS=8 -CONFIG_MMC_CB710=m -CONFIG_MMC_CQHCI=m -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_HSQ=m -CONFIG_MMC=m -CONFIG_MMC_MTK=m -CONFIG_MMC_REALTEK_PCI=m -CONFIG_MMC_REALTEK_USB=m -CONFIG_MMC_RICOH_MMC=y -CONFIG_MMC_SDHCI_ACPI=m -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI=m -CONFIG_MMC_SDHCI_PCI=m -# CONFIG_MMC_SDHCI_PLTFM is not set -CONFIG_MMC_SDRICOH_CS=m -# CONFIG_MMC_TEST is not set -CONFIG_MMC_TIFM_SD=m -CONFIG_MMC_TOSHIBA_PCI=m -CONFIG_MMC_USDHI6ROL0=m -CONFIG_MMC_USHC=m -CONFIG_MMC_VIA_SDMMC=m -CONFIG_MMC_VUB300=m -CONFIG_MMC_WBSD=m -CONFIG_MMU_GATHER_RCU_TABLE_FREE=y -CONFIG_MMU_GATHER_TABLE_FREE=y -# CONFIG_MODULE_COMPRESS_GZIP is not set -CONFIG_MODULE_COMPRESS_XZ=y -CONFIG_MODULE_COMPRESS=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MOST is not set -CONFIG_MOUSE_APPLETOUCH=m -CONFIG_MOUSE_BCM5974=m -CONFIG_MOUSE_CYAPA=m -CONFIG_MOUSE_ELAN_I2C_I2C=y -CONFIG_MOUSE_ELAN_I2C=m -CONFIG_MOUSE_ELAN_I2C_SMBUS=y -# CONFIG_MOUSE_GPIO is not set -CONFIG_MOUSE_PS2_ELANTECH=y -CONFIG_MOUSE_PS2_SENTELIC=y -CONFIG_MOUSE_PS2_TOUCHKIT=y -CONFIG_MOUSE_PS2_VMMOUSE=y -CONFIG_MOUSE_SYNAPTICS_USB=m -# CONFIG_MP2629_ADC is not set -# CONFIG_MPL115_I2C is not set -# CONFIG_MPL3115 is not set -CONFIG_MPLS_IPTUNNEL=m -CONFIG_MPLS_ROUTING=m -CONFIG_MPLS=y -# CONFIG_MPTCP_HMAC_TEST is not set -CONFIG_MPTCP_IPV6=y -CONFIG_MPTCP=y -# CONFIG_MPU3050_I2C is not set -# CONFIG_MS5611 is not set -# CONFIG_MS5637 is not set -CONFIG_MS_BLOCK=m -CONFIG_MSCC_OCELOT_SWITCH=m -CONFIG_MSDOS_FS=m -CONFIG_MSI_LAPTOP=m -CONFIG_MSI_WMI=m -CONFIG_MSPRO_BLOCK=m -CONFIG_MT7601U=m -CONFIG_MT7603E=m -CONFIG_MT7615_COMMON=m -CONFIG_MT7615E=m -CONFIG_MT7663U=m -CONFIG_MT76_CORE=m -CONFIG_MT76_LEDS=y -CONFIG_MT76_USB=m -CONFIG_MT76x02_LIB=m -CONFIG_MT76x02_USB=m -CONFIG_MT76x0_COMMON=m -CONFIG_MT76x0E=m -CONFIG_MT76x0U=m -CONFIG_MT76x2_COMMON=m -CONFIG_MT76x2E=m -CONFIG_MT76x2U=m -CONFIG_MT7915E=m -CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 -CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 -CONFIG_MTRR_SANITIZER=y -CONFIG_MUSB_PIO_ONLY=y -CONFIG_MVMDIO=m -CONFIG_MWAVE=m -CONFIG_MWIFIEX=m -CONFIG_MWIFIEX_PCIE=m -CONFIG_MWIFIEX_SDIO=m -CONFIG_MWIFIEX_USB=m -CONFIG_MWL8K=m -# CONFIG_MXC4005 is not set -# CONFIG_MXC6255 is not set -CONFIG_MXM_WMI=m -CONFIG_MYRI10GE_DCA=y -CONFIG_MYRI10GE=m -CONFIG_NATIONAL_PHY=m -CONFIG_NATSEMI=m -# CONFIG_NAU7802 is not set -CONFIG_ND_BLK=m -CONFIG_ND_BTT=m -CONFIG_ND_CLAIM=y -CONFIG_NE2K_PCI=m -CONFIG_NET_ACT_CONNMARK=m -CONFIG_NET_ACT_CSUM=m -CONFIG_NET_ACT_CTINFO=m -CONFIG_NET_ACT_CT=m -CONFIG_NET_ACT_GACT=m -CONFIG_NET_ACT_GATE=m -CONFIG_NET_ACT_IFE=m -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_MPLS=m -CONFIG_NET_ACT_NAT=m -CONFIG_NET_ACT_PEDIT=m -CONFIG_NET_ACT_POLICE=m -CONFIG_NET_ACT_SAMPLE=m -CONFIG_NET_ACT_SIMP=m -CONFIG_NET_ACT_SKBEDIT=m -CONFIG_NET_ACT_SKBMOD=m -CONFIG_NET_ACT_TUNNEL_KEY=m -CONFIG_NET_ACT_VLAN=m -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_BPF=m -CONFIG_NET_CLS_CGROUP=m -CONFIG_NET_CLS_FLOWER=m -CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_MATCHALL=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_U32=m -# CONFIG_NETCONSOLE is not set -CONFIG_NET_DEVLINK=y -CONFIG_NETDEVSIM=m -CONFIG_NET_DSA_AR9331=m -CONFIG_NET_DSA_BCM_SF2=m -CONFIG_NET_DSA_LANTIQ_GSWIP=m -CONFIG_NET_DSA_LOOP=m -CONFIG_NET_DSA=m -CONFIG_NET_DSA_MICROCHIP_KSZ8795=m -# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set -CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m -CONFIG_NET_DSA_MT7530=m -CONFIG_NET_DSA_MV88E6060=m -CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y -CONFIG_NET_DSA_MV88E6XXX=m -CONFIG_NET_DSA_MV88E6XXX_PTP=y -CONFIG_NET_DSA_QCA8K=m -CONFIG_NET_DSA_REALTEK_SMI=m -CONFIG_NET_DSA_SMSC_LAN9303_I2C=m -CONFIG_NET_DSA_SMSC_LAN9303=m -CONFIG_NET_DSA_SMSC_LAN9303_MDIO=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 -CONFIG_NET_DSA_TAG_BRCM_PREPEND=m -CONFIG_NET_DSA_TAG_DSA=m -CONFIG_NET_DSA_TAG_EDSA=m -CONFIG_NET_DSA_TAG_GSWIP=m -CONFIG_NET_DSA_TAG_KSZ=m -CONFIG_NET_DSA_TAG_LAN9303=m -CONFIG_NET_DSA_TAG_MTK=m -CONFIG_NET_DSA_TAG_OCELOT=m -CONFIG_NET_DSA_TAG_QCA=m -CONFIG_NET_DSA_TAG_SJA1105=m -CONFIG_NET_DSA_TAG_TRAILER=m -CONFIG_NET_DSA_VITESSE_VSC73XX=m -CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM=m -CONFIG_NET_EGRESS=y -CONFIG_NET_EMATCH_CMP=m -CONFIG_NET_EMATCH_IPSET=m -CONFIG_NET_EMATCH_IPT=m -CONFIG_NET_EMATCH_META=m -CONFIG_NET_EMATCH_NBYTE=m -CONFIG_NET_EMATCH_TEXT=m -CONFIG_NET_EMATCH_U32=m -CONFIG_NET_FAILOVER=m -CONFIG_NETFILTER_ADVANCED=y -CONFIG_NETFILTER_CONNCOUNT=m -CONFIG_NETFILTER_FAMILY_ARP=y -CONFIG_NETFILTER_FAMILY_BRIDGE=y -CONFIG_NETFILTER_NETLINK_ACCT=m -CONFIG_NETFILTER_NETLINK_GLUE_CT=y -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_OSF=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_SYNPROXY=m -CONFIG_NETFILTER_XTABLES=m -CONFIG_NETFILTER_XT_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_BPF=m -CONFIG_NETFILTER_XT_MATCH_CGROUP=m -CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_CPU=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ECN=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m -CONFIG_NETFILTER_XT_MATCH_IPCOMP=m -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_IPVS=m -CONFIG_NETFILTER_XT_MATCH_L2TP=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_NFACCT=m -CONFIG_NETFILTER_XT_MATCH_OSF=m -CONFIG_NETFILTER_XT_MATCH_OWNER=m -CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_RATEEST=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_SOCKET=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_TIME=m -CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_NETFILTER_XT_SET=m -CONFIG_NETFILTER_XT_TARGET_AUDIT=m -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_CT=m -CONFIG_NETFILTER_XT_TARGET_DSCP=m -CONFIG_NETFILTER_XT_TARGET_HL=m -CONFIG_NETFILTER_XT_TARGET_HMARK=m -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -CONFIG_NETFILTER_XT_TARGET_LED=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NETMAP=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -CONFIG_NETFILTER_XT_TARGET_RATEEST=m -CONFIG_NETFILTER_XT_TARGET_REDIRECT=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -CONFIG_NETFILTER_XT_TARGET_TEE=m -CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m -CONFIG_NET_IFE=m -CONFIG_NET_IFE_SKBMARK=m -CONFIG_NET_IFE_SKBPRIO=m -CONFIG_NET_IFE_SKBTCINDEX=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPIP=m -CONFIG_NET_IP_TUNNEL=m -CONFIG_NET_KEY=m -CONFIG_NET_KEY_MIGRATE=y -CONFIG_NET_L3_MASTER_DEV=y -CONFIG_NETLINK_DIAG=m -CONFIG_NET_MPLS_GSO=m -CONFIG_NET_NSH=m -CONFIG_NET_REDIRECT=y -CONFIG_NET_SCH_CAKE=m -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_CBS=m -CONFIG_NET_SCH_CHOKE=m -CONFIG_NET_SCH_CODEL=m -CONFIG_NET_SCH_DRR=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_ETF=m -CONFIG_NET_SCH_ETS=m -CONFIG_NET_SCH_FQ_CODEL=m -CONFIG_NET_SCH_FQ=m -CONFIG_NET_SCH_FQ_PIE=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_HHF=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_SCH_MQPRIO=m -CONFIG_NET_SCH_MULTIQ=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_PIE=m -CONFIG_NET_SCH_PLUG=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_QFQ=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFB=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_SKBPRIO=m -CONFIG_NET_SCH_TAPRIO=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SOCK_MSG=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NET_TEAM=m -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m -CONFIG_NET_TEAM_MODE_BROADCAST=m -CONFIG_NET_TEAM_MODE_LOADBALANCE=m -CONFIG_NET_TEAM_MODE_RANDOM=m -CONFIG_NET_TEAM_MODE_ROUNDROBIN=m -CONFIG_NET_UDP_TUNNEL=m -CONFIG_NET_VRF=m -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETXEN_NIC=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_BRIDGE=m -CONFIG_NF_CONNTRACK_BROADCAST=m -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_LABELS=y -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=m -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_SNMP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CONNTRACK_TIMEOUT=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CT_NETLINK_HELPER=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_DUP_IPV4=m -CONFIG_NF_DUP_IPV6=m -CONFIG_NF_DUP_NETDEV=m -CONFIG_NF_FLOW_TABLE_INET=m -CONFIG_NF_FLOW_TABLE_IPV4=m -CONFIG_NF_FLOW_TABLE_IPV6=m -CONFIG_NF_FLOW_TABLE=m -CONFIG_NF_LOG_BRIDGE=m -CONFIG_NF_LOG_NETDEV=m -CONFIG_NF_NAT_AMANDA=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_H323=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT=m -CONFIG_NF_NAT_PPTP=m -CONFIG_NF_NAT_REDIRECT=y -CONFIG_NF_NAT_SIP=m -CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_TFTP=m -CONFIG_NFP_APP_ABM_NIC=y -CONFIG_NFP_APP_FLOWER=y -# CONFIG_NFP_DEBUG is not set -CONFIG_NFP=m -CONFIG_NF_REJECT_IPV4=m -CONFIG_NF_REJECT_IPV6=m -CONFIG_NFS_ACL_SUPPORT=m -# CONFIG_NFSD_BLOCKLAYOUT is not set -CONFIG_NFSD_FLEXFILELAYOUT=y -CONFIG_NFSD=m -CONFIG_NFSD_PNFS=y -# CONFIG_NFSD_SCSILAYOUT is not set -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V4=y -CONFIG_NFS_FSCACHE=y -CONFIG_NFS_FS=m -CONFIG_NF_SOCKET_IPV4=m -CONFIG_NF_SOCKET_IPV6=m -CONFIG_NFS_V2=m -CONFIG_NFS_V3=m -CONFIG_NFS_V4=m -CONFIG_NF_TABLES_ARP=y -CONFIG_NF_TABLES_BRIDGE=m -CONFIG_NF_TABLES_INET=y -CONFIG_NF_TABLES_IPV4=y -CONFIG_NF_TABLES_IPV6=y -CONFIG_NF_TABLES=m -CONFIG_NF_TABLES_NETDEV=y -CONFIG_NFT_BRIDGE_META=m -CONFIG_NFT_BRIDGE_REJECT=m -CONFIG_NFT_COMPAT=m -CONFIG_NFT_CONNLIMIT=m -CONFIG_NFT_COUNTER=m -CONFIG_NFT_CT=m -CONFIG_NFT_DUP_IPV4=m -CONFIG_NFT_DUP_IPV6=m -CONFIG_NFT_DUP_NETDEV=m -CONFIG_NFT_FIB_INET=m -CONFIG_NFT_FIB_IPV4=m -CONFIG_NFT_FIB_IPV6=m -CONFIG_NFT_FIB=m -CONFIG_NFT_FIB_NETDEV=m -CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NFT_FWD_NETDEV=m -CONFIG_NFT_HASH=m -CONFIG_NFT_LIMIT=m -CONFIG_NFT_LOG=m -CONFIG_NFT_MASQ=m -CONFIG_NFT_NAT=m -CONFIG_NFT_NUMGEN=m -CONFIG_NFT_OBJREF=m -CONFIG_NFT_OSF=m -CONFIG_NF_TPROXY_IPV4=m -CONFIG_NF_TPROXY_IPV6=m -CONFIG_NFT_QUEUE=m -CONFIG_NFT_QUOTA=m -CONFIG_NFT_REDIR=m -CONFIG_NFT_REJECT_INET=m -CONFIG_NFT_REJECT_IPV4=m -CONFIG_NFT_REJECT_IPV6=m -CONFIG_NFT_REJECT=m -CONFIG_NFT_SOCKET=m -CONFIG_NFT_SYNPROXY=m -CONFIG_NFT_TPROXY=m -CONFIG_NFT_TUNNEL=m -CONFIG_NFT_XFRM=m -CONFIG_NI903X_WDT=m -CONFIG_NIC7018_WDT=m -CONFIG_NILFS2_FS=m -CONFIG_NIU=m -CONFIG_NI_XGE_MANAGEMENT_ENET=m -CONFIG_NLMON=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -# CONFIG_NOA1305 is not set -# CONFIG_NO_HZ is not set -CONFIG_NORTEL_HERMES=m -CONFIG_NOUVEAU_DEBUG=5 -CONFIG_NOUVEAU_DEBUG_DEFAULT=3 -# CONFIG_NOUVEAU_DEBUG_MMU is not set -CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT=y -CONFIG_NS83820=m -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_FS=m -CONFIG_NTFS_RW=y -CONFIG_NUMA_KEEP_MEMINFO=y -CONFIG_NVME_CORE=y -CONFIG_NVMEM_SPMI_SDAM=m -CONFIG_NVME_MULTIPATH=y -# CONFIG_NVME_TARGET is not set -# CONFIG_NVME_TCP is not set -# CONFIG_NVM_PBLK_DEBUG is not set -CONFIG_NVM_PBLK=m -CONFIG_NVM=y -CONFIG_NVRAM=m -CONFIG_NV_TCO=m -CONFIG_NXP_TJA11XX_PHY=m -CONFIG_OBJAGG=m -# CONFIG_OCFS2_DEBUG_FS is not set -CONFIG_OCFS2_DEBUG_MASKLOG=y -CONFIG_OCFS2_FS=m -CONFIG_OCFS2_FS_O2CB=m -CONFIG_OCFS2_FS_STATS=y -CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m -CONFIG_OPENVSWITCH_GENEVE=m -CONFIG_OPENVSWITCH_GRE=m -CONFIG_OPENVSWITCH=m -CONFIG_OPENVSWITCH_VXLAN=m -# CONFIG_OPT3001 is not set -CONFIG_ORANGEFS_FS=m -CONFIG_ORINOCO_USB=m -# CONFIG_OSF_PARTITION is not set -CONFIG_OVERLAY_FS_INDEX=y -CONFIG_OVERLAY_FS=m -CONFIG_OVERLAY_FS_METACOPY=y -CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y -CONFIG_OVERLAY_FS_REDIRECT_DIR=y -# CONFIG_OVERLAY_FS_XINO_AUTO is not set -CONFIG_P54_COMMON=m -CONFIG_P54_LEDS=y -CONFIG_P54_PCI=m -CONFIG_P54_USB=m -# CONFIG_PA12203001 is not set -CONFIG_PACKET_DIAG=m -CONFIG_PACKING=y -CONFIG_PADATA=y -CONFIG_PAGE_COUNTER=y -CONFIG_PAGE_POOL=y -CONFIG_PAGE_REPORTING=y -CONFIG_PANASONIC_LAPTOP=m -# CONFIG_PANEL is not set -CONFIG_PARAVIRT_CLOCK=y -# CONFIG_PARAVIRT_DEBUG is not set -CONFIG_PARAVIRT_SPINLOCKS=y -# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -CONFIG_PARAVIRT=y -# CONFIG_PARIDE is not set -CONFIG_PARMAN=m -CONFIG_PARPORT_1284=y -# CONFIG_PARPORT_AX88796 is not set -CONFIG_PARPORT_NOT_PC=y -# CONFIG_PARPORT_PC_FIFO is not set -CONFIG_PARPORT_PC=m -# CONFIG_PARPORT_PC_PCMCIA is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_SERIAL is not set -CONFIG_PARPORT=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_PATA_ACPI=m -CONFIG_PATA_ALI=m -CONFIG_PATA_AMD=m -CONFIG_PATA_ARTOP=m -CONFIG_PATA_ATIIXP=m -CONFIG_PATA_ATP867X=m -CONFIG_PATA_CMD640_PCI=m -CONFIG_PATA_CMD64X=m -CONFIG_PATA_CYPRESS=m -CONFIG_PATA_EFAR=m -CONFIG_PATA_HPT366=m -CONFIG_PATA_HPT37X=m -CONFIG_PATA_HPT3X2N=m -CONFIG_PATA_HPT3X3_DMA=y -CONFIG_PATA_HPT3X3=m -CONFIG_PATA_IT8213=m -CONFIG_PATA_IT821X=m -CONFIG_PATA_JMICRON=m -CONFIG_PATA_LEGACY=m -CONFIG_PATA_MARVELL=m -CONFIG_PATA_MPIIX=m -CONFIG_PATA_NETCELL=m -CONFIG_PATA_NINJA32=m -CONFIG_PATA_NS87410=m -CONFIG_PATA_NS87415=m -CONFIG_PATA_OLDPIIX=m -CONFIG_PATA_OPTIDMA=m -CONFIG_PATA_OPTI=m -CONFIG_PATA_PCMCIA=m -CONFIG_PATA_PDC2027X=m -CONFIG_PATA_PDC_OLD=m -CONFIG_PATA_PLATFORM=m -CONFIG_PATA_RADISYS=m -CONFIG_PATA_RDC=m -CONFIG_PATA_RZ1000=m -CONFIG_PATA_SCH=m -CONFIG_PATA_SERVERWORKS=m -CONFIG_PATA_SIL680=m -CONFIG_PATA_SIS=m -CONFIG_PATA_TOSHIBA=m -CONFIG_PATA_TRIFLEX=m -CONFIG_PATA_VIA=m -CONFIG_PATA_WINBOND=m -# CONFIG_PC104 is not set -CONFIG_PC87413_WDT=m -CONFIG_PCCARD=m -CONFIG_PCENGINES_APU2=m -CONFIG_PCI_ATMEL=m -CONFIG_PCI_CNB20LE_QUIRK=y -# CONFIG_PCIEAER_INJECT is not set -CONFIG_PCIEAER=y -# CONFIG_PCIE_DPC is not set -CONFIG_PCIE_ECRC=y -CONFIG_PCI_HERMES=m -# CONFIG_PCI_HYPERV_INTERFACE is not set -# CONFIG_PCI_HYPERV is not set -CONFIG_PCI_IOV=y -CONFIG_PCIPCWATCHDOG=m -CONFIG_PCI_PF_STUB=m -# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set -CONFIG_PCI_STUB=m -CONFIG_PCMCIA_3C574=m -CONFIG_PCMCIA_3C589=m -CONFIG_PCMCIA_AHA152X=m -CONFIG_PCMCIA_ATMEL=m -CONFIG_PCMCIA_AXNET=m -# CONFIG_PCMCIA_FDOMAIN is not set -CONFIG_PCMCIA_FMVJ18X=m -CONFIG_PCMCIA_HERMES=m -CONFIG_PCMCIA=m -CONFIG_PCMCIA_NMCLAN=m -CONFIG_PCMCIA_PCNET=m -CONFIG_PCMCIA_QLOGIC=m -CONFIG_PCMCIA_RAYCS=m -CONFIG_PCMCIA_SMC91C92=m -CONFIG_PCMCIA_SPECTRUM=m -CONFIG_PCMCIA_SYM53C500=m -CONFIG_PCMCIA_WL3501=m -CONFIG_PCMCIA_XIRC2PS=m -CONFIG_PCMCIA_XIRCOM=m -CONFIG_PCNET32=m -CONFIG_PD6729=m -CONFIG_PDC_ADMA=m -CONFIG_PEAQ_WMI=m -CONFIG_PERF_EVENTS_AMD_POWER=m -CONFIG_PGTABLE_LEVELS=4 -CONFIG_PHANTOM=m -# CONFIG_PHY_CPCAP_USB is not set -CONFIG_PHY_INTEL_EMMC=m -CONFIG_PHYLIB=m -CONFIG_PHYLINK=m -CONFIG_PHY_PXA_28NM_HSIC=m -CONFIG_PHY_PXA_28NM_USB2=m -CONFIG_PHY_QCOM_USB_HSIC=m -CONFIG_PHY_QCOM_USB_HS=m -CONFIG_PHYSICAL_ALIGN=0x1000000 -CONFIG_PHY_TUSB1210=m -CONFIG_PINCONF=y -# CONFIG_PINCTRL_AMD is not set -# CONFIG_PINCTRL_BAYTRAIL is not set -# CONFIG_PINCTRL_BROXTON is not set -# CONFIG_PINCTRL_CANNONLAKE is not set -# CONFIG_PINCTRL_CEDARFORK is not set -# CONFIG_PINCTRL_CHERRYVIEW is not set -# CONFIG_PINCTRL_DA9062 is not set -# CONFIG_PINCTRL_DENVERTON is not set -# CONFIG_PINCTRL_GEMINILAKE is not set -# CONFIG_PINCTRL_ICELAKE is not set -CONFIG_PINCTRL_INTEL=m -CONFIG_PINCTRL_JASPERLAKE=m -# CONFIG_PINCTRL_LEWISBURG is not set -# CONFIG_PINCTRL_LYNXPOINT is not set -# CONFIG_PINCTRL_MCP23S08 is not set -# CONFIG_PINCTRL_SUNRISEPOINT is not set -# CONFIG_PINCTRL_TIGERLAKE is not set -CONFIG_PINCTRL=y -# CONFIG_PING is not set -CONFIG_PINMUX=y -CONFIG_PKCS8_PRIVATE_KEY_PARSER=m -CONFIG_PLATFORM_SI4713=m -# CONFIG_PLIP is not set -CONFIG_PLX_HERMES=m -CONFIG_PM_ADVANCED_DEBUG=y -CONFIG_PMBUS=m -# CONFIG_PM_DEVFREQ_EVENT is not set -CONFIG_PM_DEVFREQ=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_OPP=y -# CONFIG_PMS7003 is not set -# CONFIG_PM_TRACE_RTC is not set -CONFIG_PPDEV=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOE=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP=y -# CONFIG_PPS_CLIENT_PARPORT is not set -CONFIG_PPTP=m -CONFIG_PREEMPT_COUNT=y -CONFIG_PREEMPTION=y -CONFIG_PREEMPT_NOTIFIERS=y -CONFIG_PREEMPT_RCU=y -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_PRIME_NUMBERS=m -CONFIG_PRINTER=y -# CONFIG_PRINTK_TIME is not set -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_PRISM2_USB is not set -CONFIG_PRISM54=m -CONFIG_PROC_CHILDREN=y -# CONFIG_PROCESSOR_SELECT is not set -# CONFIG_PROFILING is not set -# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set -CONFIG_PSAMPLE=m -CONFIG_PTDUMP_CORE=y -CONFIG_PTP_1588_CLOCK_IDT82P33=m -CONFIG_PTP_1588_CLOCK_IDTCM=m -CONFIG_PTP_1588_CLOCK_KVM=m -CONFIG_PTP_1588_CLOCK_VMW=m -# CONFIG_PVH is not set -CONFIG_PVPANIC=m -CONFIG_QCOM_EMAC=m -CONFIG_QCOM_HIDMA=m -CONFIG_QCOM_HIDMA_MGMT=m -# CONFIG_QCOM_SPMI_ADC5 is not set -# CONFIG_QCOM_SPMI_IADC is not set -# CONFIG_QCOM_SPMI_VADC is not set -CONFIG_QEDE=m -CONFIG_QED_FCOE=y -CONFIG_QEDF=m -CONFIG_QEDI=m -CONFIG_QED_ISCSI=y -CONFIG_QED_LL2=y -CONFIG_QED=m -CONFIG_QED_OOO=y -CONFIG_QED_SRIOV=y -# CONFIG_QFMT_V2 is not set -CONFIG_QLA3XXX=m -CONFIG_QLCNIC_HWMON=y -CONFIG_QLCNIC=m -CONFIG_QLCNIC_SRIOV=y -CONFIG_QLGE=m -CONFIG_QRTR=m -CONFIG_QRTR_TUN=m -CONFIG_QSEMI_PHY=m -CONFIG_QTNFMAC=m -CONFIG_QTNFMAC_PCIE=m -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -CONFIG_QUOTA_TREE=m -CONFIG_R6040=m -CONFIG_R8169=m -CONFIG_R8188EU=m -CONFIG_R8712U=m -CONFIG_RADIO_ADAPTERS=y -CONFIG_RADIO_MAXIRADIO=m -CONFIG_RADIO_SAA7706H=m -CONFIG_RADIO_SHARK2=m -CONFIG_RADIO_SHARK=m -CONFIG_RADIO_SI470X=m -CONFIG_RADIO_SI4713=m -CONFIG_RADIO_TEA575X=m -CONFIG_RADIO_TEA5764=m -CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m -CONFIG_RAID6_PQ_BENCHMARK=y -CONFIG_RAID6_PQ=m -CONFIG_RAID_ATTRS=m -# CONFIG_RANDOMIZE_BASE is not set -CONFIG_RANDOM_TRUST_BOOTLOADER=y -CONFIG_RANDOM_TRUST_CPU=y -CONFIG_RAS=y -# CONFIG_RAVE_SP_CORE is not set -CONFIG_RC_CORE=m -# CONFIG_RC_DECODERS is not set -# CONFIG_RC_DEVICES is not set -# CONFIG_RC_MAP is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_RCU_TRACE is not set -# CONFIG_RDS_DEBUG is not set -CONFIG_RDS=m -CONFIG_RDS_TCP=m -CONFIG_REALTEK_AUTOPM=y -CONFIG_REALTEK_PHY=m -CONFIG_REGMAP_I2C=m -CONFIG_REGMAP_IRQ=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SCCB=m -# CONFIG_REGULATOR_88PG86X is not set -# CONFIG_REGULATOR_88PM800 is not set -# CONFIG_REGULATOR_ACT8865 is not set -# CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_AXP20X is not set -# CONFIG_REGULATOR_BCM590XX is not set -# CONFIG_REGULATOR_DA9062 is not set -# CONFIG_REGULATOR_DA9210 is not set -# CONFIG_REGULATOR_DA9211 is not set -# CONFIG_REGULATOR_DEBUG is not set -# CONFIG_REGULATOR_FAN53555 is not set -# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -# CONFIG_REGULATOR_GPIO is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_ISL9305 is not set -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -# CONFIG_REGULATOR_LP872X is not set -# CONFIG_REGULATOR_LP8755 is not set -# CONFIG_REGULATOR_LTC3589 is not set -# CONFIG_REGULATOR_LTC3676 is not set -# CONFIG_REGULATOR_MAX14577 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX77693 is not set -CONFIG_REGULATOR_MAX77826=m -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8907 is not set -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MP8859 is not set -# CONFIG_REGULATOR_MT6311 is not set -# CONFIG_REGULATOR_PFUZE100 is not set -# CONFIG_REGULATOR_PV88060 is not set -# CONFIG_REGULATOR_PV88080 is not set -# CONFIG_REGULATOR_PV88090 is not set -# CONFIG_REGULATOR_QCOM_SPMI is not set -# CONFIG_REGULATOR_RT5033 is not set -# CONFIG_REGULATOR_SLG51000 is not set -# CONFIG_REGULATOR_TPS51632 is not set -# CONFIG_REGULATOR_TPS62360 is not set -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_TPS65086 is not set -# CONFIG_REGULATOR_TPS65132 is not set -# CONFIG_REGULATOR_TPS65912 is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -CONFIG_REGULATOR=y -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_FS=m -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_PROC_INFO=y -CONFIG_RENESAS_PHY=m -# CONFIG_RESET_BRCMSTB_RESCAL is not set -CONFIG_RESET_CONTROLLER=y -# CONFIG_RESET_TI_SYSCON is not set -CONFIG_RETU_WATCHDOG=m -# CONFIG_RFD77402 is not set -# CONFIG_RFKILL_GPIO is not set -CONFIG_RFKILL=m -CONFIG_RMI4_2D_SENSOR=y -CONFIG_RMI4_CORE=m -CONFIG_RMI4_F03_SERIO=m -CONFIG_RMI4_F03=y -CONFIG_RMI4_F11=y -CONFIG_RMI4_F12=y -CONFIG_RMI4_F30=y -# CONFIG_RMI4_F34 is not set -# CONFIG_RMI4_F54 is not set -# CONFIG_RMI4_F55 is not set -# CONFIG_RMI4_I2C is not set -# CONFIG_RMI4_SMB is not set -CONFIG_ROCKCHIP_PHY=m -CONFIG_ROCKER=m -CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_RPR0521 is not set -CONFIG_RSI_91X=m -CONFIG_RSI_COEX=y -# CONFIG_RSI_DEBUGFS is not set -CONFIG_RSI_SDIO=m -CONFIG_RSI_USB=m -CONFIG_RT2400PCI=m -CONFIG_RT2500PCI=m -CONFIG_RT2500USB=m -CONFIG_RT2800_LIB=m -CONFIG_RT2800_LIB_MMIO=m -CONFIG_RT2800PCI=m -CONFIG_RT2800PCI_RT3290=y -CONFIG_RT2800PCI_RT33XX=y -CONFIG_RT2800PCI_RT35XX=y -CONFIG_RT2800PCI_RT53XX=y -CONFIG_RT2800USB=m -CONFIG_RT2800USB_RT33XX=y -CONFIG_RT2800USB_RT3573=y -CONFIG_RT2800USB_RT35XX=y -CONFIG_RT2800USB_RT53XX=y -CONFIG_RT2800USB_RT55XX=y -CONFIG_RT2800USB_UNKNOWN=y -# CONFIG_RT2X00_DEBUG is not set -CONFIG_RT2X00_LIB_CRYPTO=y -CONFIG_RT2X00_LIB_FIRMWARE=y -CONFIG_RT2X00_LIB_LEDS=y -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_MMIO=m -CONFIG_RT2X00_LIB_PCI=m -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00=m -CONFIG_RT61PCI=m -CONFIG_RT73USB=m -CONFIG_RTC_DRV_88PM80X=m -CONFIG_RTC_DRV_ABEOZ9=m -# CONFIG_RTC_DRV_DA9063 is not set -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -CONFIG_RTC_DRV_MAX8907=m -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_I2C_AND_SPI=m -CONFIG_RT_GROUP_SCHED=y -CONFIG_RTL8180=m -CONFIG_RTL8187_LEDS=y -CONFIG_RTL8187=m -CONFIG_RTL8188EE=m -CONFIG_RTL8192C_COMMON=m -CONFIG_RTL8192CE=m -CONFIG_RTL8192CU=m -CONFIG_RTL8192DE=m -CONFIG_RTL8192EE=m -CONFIG_RTL8192E=m -CONFIG_RTL8192SE=m -CONFIG_RTL8192U=m -CONFIG_RTL8723AE=m -CONFIG_RTL8723BE=m -CONFIG_RTL8723BS=m -CONFIG_RTL8723_COMMON=m -CONFIG_RTL8821AE=m -CONFIG_RTLBTCOEXIST=m -CONFIG_RTL_CARDS=m -CONFIG_RTLLIB_CRYPTO_CCMP=m -CONFIG_RTLLIB_CRYPTO_TKIP=m -CONFIG_RTLLIB_CRYPTO_WEP=m -CONFIG_RTLLIB=m -# CONFIG_RTLWIFI_DEBUG is not set -CONFIG_RTLWIFI=m -CONFIG_RTLWIFI_PCI=m -CONFIG_RTLWIFI_USB=m -CONFIG_RTS5208=m -CONFIG_RTW88_8723DE=m -CONFIG_RTW88_8723D=m -CONFIG_RTW88_8822BE=m -CONFIG_RTW88_8822B=m -CONFIG_RTW88_8822CE=m -CONFIG_RTW88_8822C=m -CONFIG_RTW88_CORE=m -# CONFIG_RTW88_DEBUGFS is not set -# CONFIG_RTW88_DEBUG is not set -CONFIG_RTW88=m -CONFIG_RTW88_PCI=m -CONFIG_S2IO=m -CONFIG_SAMSUNG_LAPTOP=m -CONFIG_SAMSUNG_Q10=m -# CONFIG_SATA_DWC_DEBUG is not set -CONFIG_SATA_DWC=m -# CONFIG_SATA_DWC_OLD_DMA is not set -CONFIG_SATA_INIC162X=m -CONFIG_SATA_MV=m -CONFIG_SATA_NV=m -CONFIG_SATA_PROMISE=m -CONFIG_SATA_QSTOR=m -CONFIG_SATA_SIL24=m -CONFIG_SATA_SIL=m -CONFIG_SATA_SIS=m -CONFIG_SATA_SVW=m -CONFIG_SATA_SX4=m -CONFIG_SATA_ULI=m -CONFIG_SATA_VIA=m -CONFIG_SATA_VITESSE=m -CONFIG_SBC_EPX_C3_WATCHDOG=m -CONFIG_SBC_FITPC2_WATCHDOG=m -CONFIG_SC1200_WDT=m -CONFIG_SC92031=m -CONFIG_SCHED_AUTOGROUP=y -# CONFIG_SCHEDSTATS is not set -CONFIG_SCSI_3W_9XXX=m -CONFIG_SCSI_3W_SAS=m -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_ACARD=m -CONFIG_SCSI_ADVANSYS=m -CONFIG_SCSI_AIC79XX=m -CONFIG_SCSI_AIC7XXX=m -CONFIG_SCSI_AIC94XX=m -CONFIG_SCSI_AM53C974=m -CONFIG_SCSI_ARCMSR=m -CONFIG_SCSI_BFA_FC=m -CONFIG_SCSI_BNX2_ISCSI=m -CONFIG_SCSI_BNX2X_FCOE=m -CONFIG_SCSI_BUSLOGIC=m -CONFIG_SCSI_CHELSIO_FCOE=m -# CONFIG_SCSI_CONSTANTS is not set -CONFIG_SCSI_CXGB3_ISCSI=m -CONFIG_SCSI_CXGB4_ISCSI=m -CONFIG_SCSI_DC395x=m -CONFIG_SCSI_DEBUG=m -CONFIG_SCSI_DMX3191D=m -CONFIG_SCSI_DPT_I2O=m -# CONFIG_SCSI_ENCLOSURE is not set -CONFIG_SCSI_ESAS2R=m -CONFIG_SCSI_FC_ATTRS=m -CONFIG_SCSI_FDOMAIN=m -CONFIG_SCSI_FDOMAIN_PCI=m -CONFIG_SCSI_FLASHPOINT=y -CONFIG_SCSI_GDTH=m -CONFIG_SCSI_HPSA=m -CONFIG_SCSI_HPTIOP=m -CONFIG_SCSI_IMM=m -CONFIG_SCSI_INIA100=m -CONFIG_SCSI_INITIO=m -CONFIG_SCSI_IPR_DUMP=y -CONFIG_SCSI_IPR=m -CONFIG_SCSI_IPR_TRACE=y -CONFIG_SCSI_IPS=m -CONFIG_SCSI_ISCI=m -CONFIG_SCSI_ISCSI_ATTRS=m -CONFIG_SCSI_IZIP_EPP16=y -CONFIG_SCSI_IZIP_SLOW_CTR=y -CONFIG_SCSI_LOWLEVEL_PCMCIA=y -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_SCSI_LPFC_DEBUG_FS is not set -CONFIG_SCSI_LPFC=m -CONFIG_SCSI_MPT2SAS=m -CONFIG_SCSI_MPT2SAS_MAX_SGE=128 -CONFIG_SCSI_MPT3SAS=m -CONFIG_SCSI_MPT3SAS_MAX_SGE=128 -CONFIG_SCSI_MVSAS_DEBUG=y -CONFIG_SCSI_MVSAS=m -CONFIG_SCSI_MVSAS_TASKLET=y -CONFIG_SCSI_MVUMI=m -CONFIG_SCSI_MYRB=m -CONFIG_SCSI_MYRS=m -CONFIG_SCSI_NETLINK=y -CONFIG_SCSI_PM8001=m -CONFIG_SCSI_PMCRAID=m -CONFIG_SCSI_PPA=m -CONFIG_SCSI_QLA_FC=m -CONFIG_SCSI_QLA_ISCSI=m -CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_SAS_ATA=y -CONFIG_SCSI_SAS_ATTRS=m -CONFIG_SCSI_SAS_HOST_SMP=y -CONFIG_SCSI_SAS_LIBSAS=m -CONFIG_SCSI_SMARTPQI=m -# CONFIG_SCSI_SNIC_DEBUG_FS is not set -CONFIG_SCSI_SNIC=m -CONFIG_SCSI_SPI_ATTRS=m -CONFIG_SCSI_SRP_ATTRS=m -CONFIG_SCSI_STEX=m -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y -CONFIG_SCSI_UFS_BSG=y -CONFIG_SCSI_UFS_CDNS_PLATFORM=m -CONFIG_SCSI_UFS_DWC_TC_PCI=m -CONFIG_SCSI_UFS_DWC_TC_PLATFORM=m -CONFIG_SCSI_UFSHCD=m -CONFIG_SCSI_UFSHCD_PCI=m -CONFIG_SCSI_UFSHCD_PLATFORM=m -CONFIG_SCSI_VIRTIO=m -CONFIG_SCSI_WD719X=m -CONFIG_SCTP_COOKIE_HMAC_MD5=y -CONFIG_SCTP_COOKIE_HMAC_SHA1=y -# CONFIG_SCTP_DBG_OBJCNT is not set -CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y -# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set -# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set -CONFIG_SDIO_UART=m -CONFIG_SDR_MAX2175=m -# CONFIG_SDR_PLATFORM_DRIVERS is not set -# CONFIG_SECURITY is not set -# CONFIG_SENSIRION_SGP30 is not set -CONFIG_SENSORS_ABITUGURU3=m -CONFIG_SENSORS_ABITUGURU=m -CONFIG_SENSORS_ACPI_POWER=m -CONFIG_SENSORS_AD7414=m -CONFIG_SENSORS_AD7418=m -CONFIG_SENSORS_ADC128D818=m -CONFIG_SENSORS_ADM1021=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM1026=m -CONFIG_SENSORS_ADM1029=m -CONFIG_SENSORS_ADM1031=m -CONFIG_SENSORS_ADM1177=m -CONFIG_SENSORS_ADM1275=m -CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_ADS7828=m -CONFIG_SENSORS_ADT7410=m -CONFIG_SENSORS_ADT7411=m -CONFIG_SENSORS_ADT7462=m -CONFIG_SENSORS_ADT7470=m -CONFIG_SENSORS_ADT7475=m -CONFIG_SENSORS_ADT7X10=m -CONFIG_SENSORS_AMC6821=m -CONFIG_SENSORS_AMD_ENERGY=m -CONFIG_SENSORS_APPLESMC=m -CONFIG_SENSORS_AS370=m -CONFIG_SENSORS_ASB100=m -CONFIG_SENSORS_ASC7621=m -CONFIG_SENSORS_ASPEED=m -CONFIG_SENSORS_ATK0110=m -CONFIG_SENSORS_ATXP1=m -CONFIG_SENSORS_AXI_FAN_CONTROL=m -CONFIG_SENSORS_BEL_PFE=m -CONFIG_SENSORS_CORETEMP=m -CONFIG_SENSORS_DELL_SMM=m -CONFIG_SENSORS_DME1737=m -CONFIG_SENSORS_DRIVETEMP=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_DS620=m -CONFIG_SENSORS_EMC1403=m -CONFIG_SENSORS_EMC2103=m -CONFIG_SENSORS_EMC6W201=m -CONFIG_SENSORS_F71805F=m -CONFIG_SENSORS_F71882FG=m -CONFIG_SENSORS_F75375S=m -CONFIG_SENSORS_FAM15H_POWER=m -CONFIG_SENSORS_FSCHMD=m -CONFIG_SENSORS_FTSTEUTATES=m -CONFIG_SENSORS_G760A=m -CONFIG_SENSORS_G762=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_HDAPS=m -CONFIG_SENSORS_HIH6130=m -# CONFIG_SENSORS_HMC5843_I2C is not set -CONFIG_SENSORS_I5500=m -CONFIG_SENSORS_I5K_AMB=m -CONFIG_SENSORS_IBMAEM=m -CONFIG_SENSORS_IBM_CFFPS=m -CONFIG_SENSORS_IBMPEX=m -CONFIG_SENSORS_IIO_HWMON=m -CONFIG_SENSORS_INA209=m -CONFIG_SENSORS_INA2XX=m -CONFIG_SENSORS_INA3221=m -CONFIG_SENSORS_INSPUR_IPSPS=m -CONFIG_SENSORS_IR35221=m -CONFIG_SENSORS_IR38064=m -CONFIG_SENSORS_IRPS5401=m -# CONFIG_SENSORS_ISL29018 is not set -# CONFIG_SENSORS_ISL29028 is not set -CONFIG_SENSORS_ISL68137=m -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_JC42=m -CONFIG_SENSORS_K10TEMP=m -CONFIG_SENSORS_K8TEMP=m -CONFIG_SENSORS_LINEAGE=m -CONFIG_SENSORS_LIS3_I2C=m -CONFIG_SENSORS_LIS3LV02D=m -CONFIG_SENSORS_LM25066=m -CONFIG_SENSORS_LM63=m -CONFIG_SENSORS_LM73=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM77=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM83=m -CONFIG_SENSORS_LM85=m -CONFIG_SENSORS_LM87=m -CONFIG_SENSORS_LM90=m -CONFIG_SENSORS_LM92=m -CONFIG_SENSORS_LM93=m -CONFIG_SENSORS_LM95234=m -CONFIG_SENSORS_LM95241=m -CONFIG_SENSORS_LM95245=m -CONFIG_SENSORS_LTC2945=m -CONFIG_SENSORS_LTC2947_I2C=m -CONFIG_SENSORS_LTC2947=m -CONFIG_SENSORS_LTC2978=m -CONFIG_SENSORS_LTC2978_REGULATOR=y -CONFIG_SENSORS_LTC2990=m -CONFIG_SENSORS_LTC3815=m -CONFIG_SENSORS_LTC4151=m -CONFIG_SENSORS_LTC4215=m -CONFIG_SENSORS_LTC4222=m -CONFIG_SENSORS_LTC4245=m -CONFIG_SENSORS_LTC4260=m -CONFIG_SENSORS_LTC4261=m -CONFIG_SENSORS_MAX16064=m -CONFIG_SENSORS_MAX16065=m -CONFIG_SENSORS_MAX1619=m -CONFIG_SENSORS_MAX16601=m -CONFIG_SENSORS_MAX1668=m -CONFIG_SENSORS_MAX197=m -CONFIG_SENSORS_MAX20730=m -CONFIG_SENSORS_MAX20751=m -CONFIG_SENSORS_MAX31730=m -CONFIG_SENSORS_MAX31785=m -CONFIG_SENSORS_MAX31790=m -CONFIG_SENSORS_MAX34440=m -CONFIG_SENSORS_MAX6621=m -CONFIG_SENSORS_MAX6639=m -CONFIG_SENSORS_MAX6642=m -CONFIG_SENSORS_MAX6650=m -CONFIG_SENSORS_MAX6697=m -CONFIG_SENSORS_MAX8688=m -CONFIG_SENSORS_MCP3021=m -CONFIG_SENSORS_NCT6683=m -CONFIG_SENSORS_NCT6775=m -CONFIG_SENSORS_NCT7802=m -CONFIG_SENSORS_NCT7904=m -CONFIG_SENSORS_NPCM7XX=m -CONFIG_SENSORS_NTC_THERMISTOR=m -CONFIG_SENSORS_PC87360=m -CONFIG_SENSORS_PC87427=m -CONFIG_SENSORS_PCF8591=m -CONFIG_SENSORS_PMBUS=m -CONFIG_SENSORS_POWR1220=m -CONFIG_SENSORS_PXE1610=m -# CONFIG_SENSORS_RM3100_I2C is not set -CONFIG_SENSORS_SCH5627=m -CONFIG_SENSORS_SCH5636=m -CONFIG_SENSORS_SCH56XX_COMMON=m -CONFIG_SENSORS_SHT15=m -CONFIG_SENSORS_SHT21=m -CONFIG_SENSORS_SHT3x=m -CONFIG_SENSORS_SHTC1=m -CONFIG_SENSORS_SIS5595=m -CONFIG_SENSORS_SMM665=m -CONFIG_SENSORS_SMSC47B397=m -CONFIG_SENSORS_SMSC47M192=m -CONFIG_SENSORS_SMSC47M1=m -CONFIG_SENSORS_STTS751=m -CONFIG_SENSORS_TC654=m -CONFIG_SENSORS_TC74=m -CONFIG_SENSORS_THMC50=m -CONFIG_SENSORS_TMP102=m -CONFIG_SENSORS_TMP103=m -CONFIG_SENSORS_TMP108=m -CONFIG_SENSORS_TMP401=m -CONFIG_SENSORS_TMP421=m -CONFIG_SENSORS_TMP513=m -CONFIG_SENSORS_TPS40422=m -CONFIG_SENSORS_TPS53679=m -# CONFIG_SENSORS_TSL2563 is not set -CONFIG_SENSORS_UCD9000=m -CONFIG_SENSORS_UCD9200=m -CONFIG_SENSORS_VIA686A=m -CONFIG_SENSORS_VIA_CPUTEMP=m -CONFIG_SENSORS_VT1211=m -CONFIG_SENSORS_VT8231=m -CONFIG_SENSORS_W83627EHF=m -CONFIG_SENSORS_W83627HF=m -CONFIG_SENSORS_W83773G=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_W83791D=m -CONFIG_SENSORS_W83792D=m -CONFIG_SENSORS_W83793=m -CONFIG_SENSORS_W83795_FANCTRL=y -CONFIG_SENSORS_W83795=m -CONFIG_SENSORS_W83L785TS=m -CONFIG_SENSORS_W83L786NG=m -CONFIG_SENSORS_XDPE122=m -CONFIG_SENSORS_XGENE=m -CONFIG_SENSORS_ZL6100=m -CONFIG_SERIAL_8250_16550A_VARIANTS=y -# CONFIG_SERIAL_8250_CONSOLE is not set -CONFIG_SERIAL_8250_CS=m -# CONFIG_SERIAL_8250_EXTENDED is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_DEV_BUS=m -CONFIG_SERIAL_MCTRL_GPIO=y -# CONFIG_SERIO_GPIO_PS2 is not set -# CONFIG_SERIO_PARKBD is not set -CONFIG_SERIO_SERPORT=m -CONFIG_SFC_FALCON=m -CONFIG_SFC=m -CONFIG_SFC_MCDI_LOGGING=y -CONFIG_SFC_MCDI_MON=y -CONFIG_SFC_SRIOV=y -CONFIG_SFI=y -CONFIG_SF_PDMA=m -CONFIG_SFP=m -# CONFIG_SGI_PARTITION is not set -CONFIG_SHUFFLE_PAGE_ALLOCATOR=y -# CONFIG_SI1133 is not set -# CONFIG_SI1145 is not set -# CONFIG_SI7005 is not set -# CONFIG_SI7020 is not set -CONFIG_SIS190=m -CONFIG_SIS900=m -# CONFIG_SKGE_DEBUG is not set -CONFIG_SKGE_GENESIS=y -CONFIG_SKGE=m -CONFIG_SKY2=m -CONFIG_SLAB_FREELIST_RANDOM=y -CONFIG_SLHC=y -# CONFIG_SLIP_COMPRESSED is not set -CONFIG_SLIP=m -# CONFIG_SLIP_MODE_SLIP6 is not set -# CONFIG_SLIP_SMART is not set -# CONFIG_SLOB is not set -CONFIG_SLUB_MEMCG_SYSFS_ON=y -CONFIG_SMARTJOYPLUS_FF=y -CONFIG_SMSC37B787_WDT=m -CONFIG_SMSC911X=m -CONFIG_SMSC9420=m -CONFIG_SMSC_PHY=m -CONFIG_SMSC_SCH311X_WDT=m -CONFIG_SMS_SDIO_DRV=m -# CONFIG_SMS_SIANO_DEBUGFS is not set -CONFIG_SMS_SIANO_MDTV=m -CONFIG_SMS_SIANO_RC=y -CONFIG_SMS_USB_DRV=m -CONFIG_SND_AC97_CODEC=m -CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 -CONFIG_SND_AC97_POWER_SAVE=y -CONFIG_SND_AD1889=m -CONFIG_SND_ALI5451=m -CONFIG_SND_ALOOP=m -CONFIG_SND_ALS300=m -CONFIG_SND_ALS4000=m -CONFIG_SND_ASIHPI=m -CONFIG_SND_ATIIXP=m -CONFIG_SND_ATIIXP_MODEM=m -CONFIG_SND_AU8810=m -CONFIG_SND_AU8820=m -CONFIG_SND_AU8830=m -CONFIG_SND_AW2=m -CONFIG_SND_AZT3328=m -CONFIG_SND_BCD2000=m -CONFIG_SND_BEBOB=m -CONFIG_SND_BT87X=m -CONFIG_SND_BT87X_OVERCLOCK=y -CONFIG_SND_CA0106=m -CONFIG_SND_CMIPCI=m -CONFIG_SND_CS4281=m -CONFIG_SND_CS46XX=m -CONFIG_SND_CS46XX_NEW_DSP=y -CONFIG_SND_CTXFI=m -CONFIG_SND_DARLA20=m -CONFIG_SND_DARLA24=m -CONFIG_SND_DICE=m -CONFIG_SND_DYNAMIC_MINORS=y -CONFIG_SND_ECHO3G=m -CONFIG_SND_EMU10K1=m -CONFIG_SND_EMU10K1_SEQ=m -CONFIG_SND_EMU10K1X=m -CONFIG_SND_ENS1370=m -CONFIG_SND_ENS1371=m -CONFIG_SND_ES1938=m -CONFIG_SND_ES1968_INPUT=y -CONFIG_SND_ES1968=m -CONFIG_SND_ES1968_RADIO=y -CONFIG_SND_FIREFACE=m -CONFIG_SND_FIREWIRE_DIGI00X=m -CONFIG_SND_FIREWIRE_LIB=m -CONFIG_SND_FIREWIRE_MOTU=m -CONFIG_SND_FIREWIRE_TASCAM=m -CONFIG_SND_FIREWIRE=y -CONFIG_SND_FIREWORKS=m -CONFIG_SND_FM801=m -CONFIG_SND_FM801_TEA575X_BOOL=y -CONFIG_SND_GINA20=m -CONFIG_SND_GINA24=m -CONFIG_SND_HDA_CODEC_ANALOG=m -CONFIG_SND_HDA_CODEC_CA0110=m -CONFIG_SND_HDA_CODEC_CA0132_DSP=y -CONFIG_SND_HDA_CODEC_CA0132=m -CONFIG_SND_HDA_CODEC_CIRRUS=m -CONFIG_SND_HDA_CODEC_CMEDIA=m -CONFIG_SND_HDA_CODEC_CONEXANT=m -CONFIG_SND_HDA_CODEC_HDMI=m -CONFIG_SND_HDA_CODEC_REALTEK=m -CONFIG_SND_HDA_CODEC_SI3054=m -CONFIG_SND_HDA_CODEC_SIGMATEL=m -CONFIG_SND_HDA_CODEC_VIA=m -CONFIG_SND_HDA_CORE=m -CONFIG_SND_HDA_DSP_LOADER=y -CONFIG_SND_HDA_GENERIC=m -CONFIG_SND_HDA_INPUT_BEEP_MODE=1 -CONFIG_SND_HDA_INPUT_BEEP=y -CONFIG_SND_HDA_INTEL=m -CONFIG_SND_HDA=m -CONFIG_SND_HDA_PATCH_LOADER=y -CONFIG_SND_HDA_RECONFIG=y -CONFIG_SND_HDSP=m -CONFIG_SND_HDSPM=m -# CONFIG_SND_HRTIMER is not set -CONFIG_SND_HWDEP=m -CONFIG_SND_ICE1712=m -CONFIG_SND_ICE1724=m -CONFIG_SND_INDIGODJ=m -CONFIG_SND_INDIGODJX=m -CONFIG_SND_INDIGOIO=m -CONFIG_SND_INDIGOIOX=m -CONFIG_SND_INDIGO=m -CONFIG_SND_INTEL8X0=m -CONFIG_SND_INTEL8X0M=m -CONFIG_SND_INTEL_DSP_CONFIG=m -CONFIG_SND_ISIGHT=m -CONFIG_SND_KORG1212=m -CONFIG_SND_LAYLA20=m -CONFIG_SND_LAYLA24=m -CONFIG_SND_LOLA=m -CONFIG_SND_LX6464ES=m -CONFIG_SND=m -CONFIG_SND_MAESTRO3_INPUT=y -CONFIG_SND_MAESTRO3=m -CONFIG_SND_MAX_CARDS=32 -CONFIG_SND_MIA=m -CONFIG_SND_MIXART=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_MONA=m -CONFIG_SND_MPU401_UART=m -# CONFIG_SND_MTS64 is not set -CONFIG_SND_NM256=m -CONFIG_SND_OPL3_LIB=m -CONFIG_SND_OPL3_LIB_SEQ=m -CONFIG_SND_OSSEMUL=y -CONFIG_SND_OXFW=m -CONFIG_SND_OXYGEN_LIB=m -CONFIG_SND_OXYGEN=m -CONFIG_SND_PCM=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_PCM_OSS_PLUGINS=y -CONFIG_SND_PCXHR=m -# CONFIG_SND_PORTMAN2X4 is not set -CONFIG_SND_RAWMIDI=m -CONFIG_SND_RIPTIDE=m -CONFIG_SND_RME32=m -CONFIG_SND_RME9652=m -CONFIG_SND_RME96=m -CONFIG_SND_SB_COMMON=m -CONFIG_SND_SEQ_DEVICE=m -# CONFIG_SND_SEQ_DUMMY is not set -CONFIG_SND_SEQ_MIDI_EMUL=m -CONFIG_SND_SEQ_MIDI_EVENT=m -CONFIG_SND_SEQ_MIDI=m -CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQUENCER_OSS is not set -CONFIG_SND_SEQ_VIRMIDI=m -CONFIG_SND_SONICVIBES=m -# CONFIG_SND_SUPPORT_OLD_API is not set -CONFIG_SND_SYNTH_EMUX=m -CONFIG_SND_TIMER=m -CONFIG_SND_TRIDENT=m -CONFIG_SND_USB_6FIRE=m -CONFIG_SND_USB_AUDIO=m -CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y -CONFIG_SND_USB_CAIAQ_INPUT=y -CONFIG_SND_USB_CAIAQ=m -CONFIG_SND_USB_HIFACE=m -CONFIG_SND_USB_LINE6=m -CONFIG_SND_USB_PODHD=m -CONFIG_SND_USB_POD=m -CONFIG_SND_USB_TONEPORT=m -CONFIG_SND_USB_UA101=m -CONFIG_SND_USB_US122L=m -CONFIG_SND_USB_USX2Y=m -CONFIG_SND_USB_VARIAX=m -CONFIG_SND_VIA82XX=m -CONFIG_SND_VIA82XX_MODEM=m -CONFIG_SND_VIRTUOSO=m -CONFIG_SND_VX222=m -CONFIG_SND_VX_LIB=m -CONFIG_SND_YMFPCI=m -CONFIG_SOCK_CGROUP_DATA=y -CONFIG_SOCK_VALIDATE_XMIT=y -CONFIG_SOFT_WATCHDOG=m -# CONFIG_SOLARIS_X86_PARTITION is not set -CONFIG_SONY_LAPTOP=m -CONFIG_SONYPI_COMPAT=y -# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set -CONFIG_SOUND_OSS_CORE=y -CONFIG_SP5100_TCO=m -# CONFIG_SPEAKUP is not set -CONFIG_SPMI=m -# CONFIG_SPS30 is not set -CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y -# CONFIG_SQUASHFS_DECOMP_MULTI is not set -CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y -# CONFIG_SQUASHFS_DECOMP_SINGLE is not set -# CONFIG_SQUASHFS_EMBEDDED is not set -# CONFIG_SQUASHFS_FILE_CACHE is not set -CONFIG_SQUASHFS_FILE_DIRECT=y -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -CONFIG_SQUASHFS_LZ4=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS=m -CONFIG_SQUASHFS_XATTR=y -CONFIG_SQUASHFS_XZ=y -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SQUASHFS_ZSTD=y -# CONFIG_SRF04 is not set -# CONFIG_SRF08 is not set -CONFIG_SSB_B43_PCI_BRIDGE=y -CONFIG_SSB_BLOCKIO=y -# CONFIG_SSB_DRIVER_GPIO is not set -CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y -CONFIG_SSB_DRIVER_PCICORE=y -CONFIG_SSB=m -CONFIG_SSB_PCIHOST_POSSIBLE=y -CONFIG_SSB_PCIHOST=y -CONFIG_SSB_PCMCIAHOST_POSSIBLE=y -CONFIG_SSB_PCMCIAHOST=y -CONFIG_SSB_SDIOHOST_POSSIBLE=y -CONFIG_SSB_SDIOHOST=y -CONFIG_SSB_SPROM=y -# CONFIG_STACKTRACE is not set -# CONFIG_STAGING_GASKET_FRAMEWORK is not set -# CONFIG_STAGING_MEDIA is not set -CONFIG_STAGING=y -CONFIG_STE10XP=m -CONFIG_STK3310=m -# CONFIG_STK8312 is not set -# CONFIG_STK8BA50 is not set -CONFIG_STMMAC_ETH=m -CONFIG_STMMAC_PCI=m -CONFIG_STMMAC_PLATFORM=m -CONFIG_STMMAC_SELFTESTS=y -CONFIG_STP=m -CONFIG_STREAM_PARSER=y -# CONFIG_STRICT_DEVMEM is not set -CONFIG_ST_UVIS25_I2C=m -CONFIG_ST_UVIS25=m -CONFIG_SUNDANCE=m -CONFIG_SUNDANCE_MMIO=y -CONFIG_SUNGEM=m -CONFIG_SUNGEM_PHY=m -# CONFIG_SUN_PARTITION is not set -# CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES is not set -CONFIG_SUNRPC_GSS=m -CONFIG_SUNRPC=m -CONFIG_SURFACE_3_POWER_OPREGION=m -CONFIG_SURFACE_PRO3_BUTTON=m -# CONFIG_SUSPEND_SKIP_SYNC is not set -CONFIG_SWPHY=y -# CONFIG_SX9310 is not set -# CONFIG_SX9500 is not set -CONFIG_SXGBE_ETH=m -CONFIG_SYSTEM76_ACPI=m -CONFIG_SYSTEMPORT=m -# CONFIG_SYSV68_PARTITION is not set -# CONFIG_T5403 is not set -CONFIG_TABLET_SERIAL_WACOM4=m -CONFIG_TABLET_USB_ACECAD=m -CONFIG_TABLET_USB_AIPTEK=m -CONFIG_TABLET_USB_GTCO=m -CONFIG_TABLET_USB_KBTAB=m -CONFIG_TABLET_USB_PEGASUS=m -CONFIG_TAHVO_USB_HOST_BY_DEFAULT=y -CONFIG_TAHVO_USB=m -CONFIG_TAP=m -CONFIG_TASKS_RCU_GENERIC=y -CONFIG_TASKS_RCU=y -CONFIG_TCP_CONG_BBR=m -CONFIG_TCP_CONG_BIC=m -CONFIG_TCP_CONG_CDG=m -CONFIG_TCP_CONG_DCTCP=m -CONFIG_TCP_CONG_HSTCP=m -CONFIG_TCP_CONG_HTCP=m -CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_TCP_CONG_LP=m -CONFIG_TCP_CONG_NV=m -CONFIG_TCP_CONG_SCALABLE=m -CONFIG_TCP_CONG_VEGAS=m -CONFIG_TCP_CONG_VENO=m -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_YEAH=m -# CONFIG_TCP_MD5SIG is not set -# CONFIG_TCS3414 is not set -# CONFIG_TCS3472 is not set -CONFIG_TEHUTI=m -CONFIG_TERANETICS_PHY=m -# CONFIG_TEST_OBJAGG is not set -# CONFIG_TEST_PARMAN is not set -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH=y -# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set -CONFIG_THERMAL_GOV_BANG_BANG=y -CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y -CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y -# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set -# CONFIG_THINKPAD_ACPI_DEBUG is not set -CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y -CONFIG_THINKPAD_ACPI=m -CONFIG_THINKPAD_ACPI_UNSAFE_LEDS=y -CONFIG_THINKPAD_ACPI_VIDEO=y -CONFIG_THRUSTMASTER_FF=y -CONFIG_THUNDER_NIC_BGX=m -CONFIG_THUNDER_NIC_PF=m -CONFIG_THUNDER_NIC_RGX=m -CONFIG_THUNDER_NIC_VF=m -# CONFIG_TI_ADC081C is not set -# CONFIG_TI_ADS1015 is not set -# CONFIG_TI_DAC5571 is not set -CONFIG_TIFM_7XX1=m -CONFIG_TIFM_CORE=m -CONFIG_TIGON3=m -# CONFIG_TI_ST is not set -CONFIG_TLAN=m -CONFIG_TLS_DEVICE=y -CONFIG_TLS=m -# CONFIG_TLS_TOE is not set -CONFIG_TMD_HERMES=m -# CONFIG_TMP006 is not set -# CONFIG_TMP007 is not set -CONFIG_TOPSTAR_LAPTOP=m -CONFIG_TOSHIBA_BT_RFKILL=m -CONFIG_TOSHIBA_HAPS=m -CONFIG_TOSHIBA_WMI=m -CONFIG_TOUCHSCREEN_AD7879_I2C=m -CONFIG_TOUCHSCREEN_AD7879=m -CONFIG_TOUCHSCREEN_ADC=m -CONFIG_TOUCHSCREEN_ATMEL_MXT=m -CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y -CONFIG_TOUCHSCREEN_AUO_PIXCIR=m -CONFIG_TOUCHSCREEN_BU21013=m -CONFIG_TOUCHSCREEN_BU21029=m -CONFIG_TOUCHSCREEN_CHIPONE_ICN8505=m -CONFIG_TOUCHSCREEN_CY8CTMA140=m -CONFIG_TOUCHSCREEN_CY8CTMG110=m -CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m -CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m -CONFIG_TOUCHSCREEN_CYTTSP_CORE=m -CONFIG_TOUCHSCREEN_CYTTSP_I2C=m -CONFIG_TOUCHSCREEN_DYNAPRO=m -CONFIG_TOUCHSCREEN_EDT_FT5X06=m -CONFIG_TOUCHSCREEN_EETI=m -CONFIG_TOUCHSCREEN_EGALAX_SERIAL=m -CONFIG_TOUCHSCREEN_EKTF2127=m -CONFIG_TOUCHSCREEN_ELAN=m -CONFIG_TOUCHSCREEN_ELO=m -CONFIG_TOUCHSCREEN_EXC3000=m -CONFIG_TOUCHSCREEN_FUJITSU=m -CONFIG_TOUCHSCREEN_GOODIX=m -CONFIG_TOUCHSCREEN_GUNZE=m -CONFIG_TOUCHSCREEN_HAMPSHIRE=m -CONFIG_TOUCHSCREEN_HIDEEP=m -CONFIG_TOUCHSCREEN_ILI210X=m -CONFIG_TOUCHSCREEN_INEXIO=m -CONFIG_TOUCHSCREEN_IQS5XX=m -CONFIG_TOUCHSCREEN_MAX11801=m -CONFIG_TOUCHSCREEN_MCS5000=m -CONFIG_TOUCHSCREEN_MELFAS_MIP4=m -CONFIG_TOUCHSCREEN_MK712=m -CONFIG_TOUCHSCREEN_MMS114=m -CONFIG_TOUCHSCREEN_MTOUCH=m -CONFIG_TOUCHSCREEN_PENMOUNT=m -CONFIG_TOUCHSCREEN_PIXCIR=m -CONFIG_TOUCHSCREEN_RM_TS=m -CONFIG_TOUCHSCREEN_ROHM_BU21023=m -CONFIG_TOUCHSCREEN_S6SY761=m -CONFIG_TOUCHSCREEN_SILEAD=m -CONFIG_TOUCHSCREEN_SIS_I2C=m -CONFIG_TOUCHSCREEN_ST1232=m -CONFIG_TOUCHSCREEN_STMFTS=m -CONFIG_TOUCHSCREEN_SUR40=m -CONFIG_TOUCHSCREEN_SX8654=m -CONFIG_TOUCHSCREEN_TOUCHIT213=m -CONFIG_TOUCHSCREEN_TOUCHRIGHT=m -CONFIG_TOUCHSCREEN_TOUCHWIN=m -CONFIG_TOUCHSCREEN_TPS6507X=m -CONFIG_TOUCHSCREEN_TSC2004=m -CONFIG_TOUCHSCREEN_TSC2007_IIO=y -CONFIG_TOUCHSCREEN_TSC2007=m -CONFIG_TOUCHSCREEN_TSC200X_CORE=m -CONFIG_TOUCHSCREEN_TSC_SERIO=m -CONFIG_TOUCHSCREEN_USB_3M=y -CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y -CONFIG_TOUCHSCREEN_USB_E2I=y -CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y -CONFIG_TOUCHSCREEN_USB_EGALAX=y -CONFIG_TOUCHSCREEN_USB_ELO=y -CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y -CONFIG_TOUCHSCREEN_USB_ETURBO=y -CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y -CONFIG_TOUCHSCREEN_USB_GOTOP=y -CONFIG_TOUCHSCREEN_USB_GUNZE=y -CONFIG_TOUCHSCREEN_USB_IDEALTEK=y -CONFIG_TOUCHSCREEN_USB_IRTOUCH=y -CONFIG_TOUCHSCREEN_USB_ITM=y -CONFIG_TOUCHSCREEN_USB_JASTEC=y -CONFIG_TOUCHSCREEN_USB_NEXIO=y -CONFIG_TOUCHSCREEN_USB_PANJIT=y -CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y -CONFIG_TOUCHSCREEN_WACOM_I2C=m -CONFIG_TOUCHSCREEN_WACOM_W8001=m -CONFIG_TOUCHSCREEN_WDT87XX_I2C=m -CONFIG_TOUCHSCREEN_WM9705=y -CONFIG_TOUCHSCREEN_WM9712=y -CONFIG_TOUCHSCREEN_WM9713=y -CONFIG_TOUCHSCREEN_WM97XX=m -CONFIG_TOUCHSCREEN_ZET6223=m -CONFIG_TOUCHSCREEN_ZFORCE=m -# CONFIG_TPL0102 is not set -# CONFIG_TPS65010 is not set -CONFIG_TQMX86_WDT=m -# CONFIG_TSL2583 is not set -# CONFIG_TSL2772 is not set -# CONFIG_TSL4531 is not set -# CONFIG_TSYS01 is not set -# CONFIG_TSYS02D is not set -CONFIG_TTPCI_EEPROM=m -# CONFIG_TTY_PRINTK is not set -CONFIG_TULIP=m -CONFIG_TULIP_MMIO=y -CONFIG_TULIP_MWI=y -CONFIG_TULIP_NAPI_HW_MITIGATION=y -CONFIG_TULIP_NAPI=y -CONFIG_TUN=m -CONFIG_TUN_VNET_CROSS_LE=y -CONFIG_TYPEC_DP_ALTMODE=m -CONFIG_TYPEC_FUSB302=m -CONFIG_TYPEC_HD3SS3220=m -CONFIG_TYPEC=m -CONFIG_TYPEC_MUX_INTEL_PMC=m -CONFIG_TYPEC_MUX_PI3USB30532=m -CONFIG_TYPEC_NVIDIA_ALTMODE=m -CONFIG_TYPEC_RT1711H=m -CONFIG_TYPEC_TCPCI=m -CONFIG_TYPEC_TCPM=m -CONFIG_TYPEC_TPS6598X=m -CONFIG_TYPEC_UCSI=m -CONFIG_TYPHOON=m -CONFIG_UACCE=m -# CONFIG_UCB1400_CORE is not set -CONFIG_UCSI_ACPI=m -CONFIG_UCSI_CCG=m -CONFIG_UDF_FS=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_UEVENT_HELPER=y -CONFIG_UHID=m -# CONFIG_UIO_AEC is not set -# CONFIG_UIO_CIF is not set -# CONFIG_UIO_DMEM_GENIRQ is not set -# CONFIG_UIO_HV_GENERIC is not set -CONFIG_UIO=m -# CONFIG_UIO_MF624 is not set -# CONFIG_UIO_NETX is not set -CONFIG_UIO_PCI_GENERIC=m -# CONFIG_UIO_PDRV_GENIRQ is not set -# CONFIG_UIO_PRUSS is not set -# CONFIG_UIO_SERCOS3 is not set -CONFIG_ULI526X=m -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_UNICODE_NORMALIZATION_SELFTEST=m -CONFIG_UNICODE=y -CONFIG_UNINLINE_SPIN_UNLOCK=y -# CONFIG_UNISYSSPAR is not set -CONFIG_UNIX_DIAG=m -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_UNWINDER_GUESS is not set -# CONFIG_US5182D is not set -CONFIG_USB4=m -CONFIG_USB4_NET=m -CONFIG_USB_ACM=m -CONFIG_USB_AIRSPY=m -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AMD5536UDC=m -CONFIG_USB_AN2720=y -CONFIG_USB_ARMLINUX=y -# CONFIG_USB_AUDIO is not set -CONFIG_USB_BDC_PCI=m -CONFIG_USB_BDC_UDC=m -CONFIG_USB_BELKIN=y -CONFIG_USB_CATC=m -# CONFIG_USB_CDC_COMPOSITE is not set -CONFIG_USB_CDNS3_GADGET=y -CONFIG_USB_CDNS3_HOST=y -CONFIG_USB_CDNS3=m -CONFIG_USB_CDNS3_PCI_WRAP=m -CONFIG_USB_CHAOSKEY=m -CONFIG_USB_CHIPIDEA_GENERIC=m -CONFIG_USB_CHIPIDEA_HOST=y -CONFIG_USB_CHIPIDEA=m -CONFIG_USB_CHIPIDEA_MSM=m -CONFIG_USB_CHIPIDEA_UDC=y -# CONFIG_USB_CONFIGFS_ACM is not set -# CONFIG_USB_CONFIGFS_ECM is not set -# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -# CONFIG_USB_CONFIGFS_EEM is not set -# CONFIG_USB_CONFIGFS_F_FS is not set -# CONFIG_USB_CONFIGFS_F_HID is not set -# CONFIG_USB_CONFIGFS_F_LB_SS is not set -# CONFIG_USB_CONFIGFS_F_MIDI is not set -CONFIG_USB_CONFIGFS_F_PRINTER=y -# CONFIG_USB_CONFIGFS_F_UAC1 is not set -CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y -# CONFIG_USB_CONFIGFS_F_UAC2 is not set -# CONFIG_USB_CONFIGFS_F_UVC is not set -CONFIG_USB_CONFIGFS=m -# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set -# CONFIG_USB_CONFIGFS_NCM is not set -# CONFIG_USB_CONFIGFS_OBEX is not set -# CONFIG_USB_CONFIGFS_RNDIS is not set -# CONFIG_USB_CONFIGFS_SERIAL is not set -# CONFIG_USB_CONN_GPIO is not set -CONFIG_USB_DSBR=m -CONFIG_USB_DUMMY_HCD=m -CONFIG_USB_EG20T=m -CONFIG_USB_EHCI_FSL=m -CONFIG_USB_EHCI_HCD_PLATFORM=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_ETH_EEM=y -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -CONFIG_USB_EZUSB_FX2=m -CONFIG_USB_F_ECM=m -CONFIG_USB_F_EEM=m -CONFIG_USB_F_NCM=m -# CONFIG_USB_FOTG210_UDC is not set -CONFIG_USB_F_PRINTER=m -CONFIG_USB_F_RNDIS=m -CONFIG_USB_F_SUBSET=m -CONFIG_USB_F_UAC1_LEGACY=m -# CONFIG_USB_FUNCTIONFS is not set -# CONFIG_USB_G_ACM_MS is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGETFS is not set -CONFIG_USB_GADGET=m -CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -CONFIG_USB_GADGET_VBUS_DRAW=2 -# CONFIG_USB_G_DBGP is not set -# CONFIG_USB_G_HID is not set -CONFIG_USB_GL860=m -# CONFIG_USB_G_MULTI is not set -CONFIG_USB_G_NCM=m -CONFIG_USB_GOKU=m -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_G_PRINTER is not set -CONFIG_USB_GR_UDC=m -# CONFIG_USB_G_SERIAL is not set -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_DTCS033=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_JEILINJ=m -CONFIG_USB_GSPCA_JL2005BCD=m -CONFIG_USB_GSPCA_KINECT=m -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_MR97310A=m -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7302=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SE401=m -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_SQ905C=m -CONFIG_USB_GSPCA_SQ905=m -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_STK1135=m -CONFIG_USB_GSPCA_STV0680=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TOPRO=m -CONFIG_USB_GSPCA_TOUPTEK=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m -# CONFIG_USB_G_WEBCAM is not set -CONFIG_USB_HACKRF=m -CONFIG_USB_HCD_BCMA=m -CONFIG_USB_HCD_SSB=m -CONFIG_USB_HSIC_USB4604=m -CONFIG_USB_HSO=m -CONFIG_USB_HUB_USB251XB=m -CONFIG_USBIP_CORE=m -# CONFIG_USBIP_DEBUG is not set -CONFIG_USB_IPHETH=m -CONFIG_USBIP_HOST=m -CONFIG_USBIP_VHCI_HCD=m -CONFIG_USBIP_VHCI_HC_PORTS=8 -CONFIG_USBIP_VHCI_NR_HCS=1 -CONFIG_USBIP_VUDC=m -CONFIG_USB_ISP116X_HCD=m -CONFIG_USB_KAWETH=m -CONFIG_USB_KC2190=y -CONFIG_USB_KEENE=m -CONFIG_USB_LAN78XX=m -CONFIG_USB_LEDS_TRIGGER_USBPORT=m -CONFIG_USB_LED_TRIG=y -CONFIG_USB_LIBCOMPOSITE=m -CONFIG_USB_LINK_LAYER_TEST=m -CONFIG_USB_M5602=m -CONFIG_USB_M66592=m -CONFIG_USB_MA901=m -# CONFIG_USB_MASS_STORAGE is not set -# CONFIG_USB_MIDI_GADGET is not set -CONFIG_USB_MR800=m -CONFIG_USB_MUSB_DUAL_ROLE=y -# CONFIG_USB_MUSB_GADGET is not set -CONFIG_USB_MUSB_HDRC=m -# CONFIG_USB_MUSB_HOST is not set -CONFIG_USB_MV_U3D=m -CONFIG_USB_MV_UDC=m -CONFIG_USB_NET2272_DMA=y -CONFIG_USB_NET2272=m -CONFIG_USB_NET2280=m -CONFIG_USB_NET_AQC111=m -CONFIG_USB_NET_AX88179_178A=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_CDC_EEM=m -CONFIG_USB_NET_CDCETHER=m -CONFIG_USB_NET_CDC_MBIM=m -CONFIG_USB_NET_CDC_NCM=m -CONFIG_USB_NET_CDC_SUBSET_ENABLE=m -CONFIG_USB_NET_CDC_SUBSET=m -CONFIG_USB_NET_CH9200=m -# CONFIG_USB_NET_CX82310_ETH is not set -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_HUAWEI_CDC_NCM=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_NET_KALMIA=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_NET_NET1080=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_QMI_WWAN=m -CONFIG_USB_NET_RNDIS_HOST=m -CONFIG_USB_NET_RNDIS_WLAN=m -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=m -CONFIG_USB_NET_SR9700=m -CONFIG_USB_NET_SR9800=m -CONFIG_USB_NET_ZAURUS=m -CONFIG_USB_OHCI_HCD=m -CONFIG_USB_OHCI_HCD_PCI=m -CONFIG_USB_OHCI_HCD_PLATFORM=m -# CONFIG_USB_OHCI_HCD_SSB is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_OTG_FSM=m -CONFIG_USB_OTG_WHITELIST=y -CONFIG_USB_OTG=y -CONFIG_USBPCWATCHDOG=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_PHY=y -CONFIG_USB_PRINTER=m -# CONFIG_USB_PWC_DEBUG is not set -CONFIG_USB_PWC_INPUT_EVDEV=y -CONFIG_USB_PWC=m -CONFIG_USB_PXA27X=m -CONFIG_USB_R8A66597=m -CONFIG_USB_RAREMONO=m -# CONFIG_USB_RAW_GADGET is not set -CONFIG_USB_ROLES_INTEL_XHCI=m -CONFIG_USB_ROLE_SWITCH=m -CONFIG_USB_RTL8150=m -CONFIG_USB_RTL8152=m -CONFIG_USB_S2255=m -CONFIG_USB_SERIAL_AIRCABLE=m -CONFIG_USB_SERIAL_ARK3116=m -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_CH341=m -CONFIG_USB_SERIAL_CP210X=m -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_CYPRESS_M8=m -CONFIG_USB_SERIAL_DEBUG=m -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_F81232=m -CONFIG_USB_SERIAL_F8153X=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_GARMIN=m -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IPW=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_IUU=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL=m -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_METRO=m -CONFIG_USB_SERIAL_MOS7715_PARPORT=y -CONFIG_USB_SERIAL_MOS7720=m -CONFIG_USB_SERIAL_MOS7840=m -CONFIG_USB_SERIAL_MXUPORT=m -CONFIG_USB_SERIAL_NAVMAN=m -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_SERIAL_OPTICON=m -CONFIG_USB_SERIAL_OPTION=m -CONFIG_USB_SERIAL_OTI6858=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_QCAUX=m -CONFIG_USB_SERIAL_QT2=m -CONFIG_USB_SERIAL_QUALCOMM=m -CONFIG_USB_SERIAL_SAFE=m -CONFIG_USB_SERIAL_SAFE_PADDED=y -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -CONFIG_USB_SERIAL_SIMPLE=m -CONFIG_USB_SERIAL_SPCP8X5=m -CONFIG_USB_SERIAL_SSU100=m -CONFIG_USB_SERIAL_SYMBOL=m -CONFIG_USB_SERIAL_TI=m -CONFIG_USB_SERIAL_UPD78F0730=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_WHITEHEAT=m -CONFIG_USB_SERIAL_WISHBONE=m -CONFIG_USB_SERIAL_WWAN=m -CONFIG_USB_SERIAL_XIRCOM=m -CONFIG_USB_SERIAL_XSENS_MT=m -CONFIG_USB_SI470X=m -CONFIG_USB_SI4713=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_SNP_CORE=m -CONFIG_USB_STKWEBCAM=m -CONFIG_USB_STORAGE_ENE_UB6250=m -CONFIG_USB_STORAGE_REALTEK=m -CONFIG_USB_STV06XX=m -CONFIG_USB_U_ETHER=m -CONFIG_USB_UHCI_HCD=m -CONFIG_USB_ULPI_BUS=m -CONFIG_USB_USBNET=m -# CONFIG_USB_USS720 is not set -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VL600=m -CONFIG_USB_WDM=m -CONFIG_USB_XHCI_HCD=m -CONFIG_USB_XHCI_PCI=m -CONFIG_USB_XHCI_PLATFORM=m -CONFIG_USB_ZD1201=m -# CONFIG_USB_ZERO is not set -CONFIG_USB_ZR364XX=m -CONFIG_USERIO=m -CONFIG_USER_NS=y -CONFIG_USER_RETURN_NOTIFIER=y -CONFIG_V4L2_FWNODE=m -# CONFIG_V4L_MEM2MEM_DRIVERS is not set -# CONFIG_V4L_PLATFORM_DRIVERS is not set -# CONFIG_V4L_TEST_DRIVERS is not set -# CONFIG_VBOXGUEST is not set -# CONFIG_VCNL3020 is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VCNL4035 is not set -# CONFIG_VEML6030 is not set -# CONFIG_VEML6070 is not set -CONFIG_VETH=m -CONFIG_VFAT_FS=m -CONFIG_VFIO_IOMMU_TYPE1=m -CONFIG_VFIO=m -CONFIG_VFIO_MDEV_DEVICE=m -CONFIG_VFIO_MDEV=m -CONFIG_VFIO_NOIOMMU=y -CONFIG_VFIO_PCI_IGD=y -CONFIG_VFIO_PCI_INTX=y -CONFIG_VFIO_PCI=m -CONFIG_VFIO_PCI_MMAP=y -CONFIG_VFIO_PCI_VGA=y -CONFIG_VFIO_VIRQFD=m -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_VGA_SWITCHEROO=y -CONFIG_VHOST_IOTLB=m -CONFIG_VHOST=m -CONFIG_VHOST_NET=m -CONFIG_VHOST_VSOCK=m -CONFIG_VIA_RHINE=m -CONFIG_VIA_RHINE_MMIO=y -CONFIG_VIA_VELOCITY=m -CONFIG_VIA_WDT=m -CONFIG_VIDEO_AD5820=m -CONFIG_VIDEO_AD9389B=m -CONFIG_VIDEO_ADP1653=m -CONFIG_VIDEO_ADV7170=m -CONFIG_VIDEO_ADV7175=m -CONFIG_VIDEO_ADV7180=m -CONFIG_VIDEO_ADV7183=m -CONFIG_VIDEO_ADV7343=m -CONFIG_VIDEO_ADV7393=m -CONFIG_VIDEO_ADV7511_CEC=y -CONFIG_VIDEO_ADV7511=m -CONFIG_VIDEO_ADV7604_CEC=y -CONFIG_VIDEO_ADV7604=m -CONFIG_VIDEO_ADV7842_CEC=y -CONFIG_VIDEO_ADV7842=m -# CONFIG_VIDEO_ADV_DEBUG is not set -CONFIG_VIDEO_AK7375=m -CONFIG_VIDEO_AK881X=m -CONFIG_VIDEO_APTINA_PLL=m -CONFIG_VIDEO_AU0828=m -CONFIG_VIDEO_AU0828_RC=y -CONFIG_VIDEO_AU0828_V4L2=y -CONFIG_VIDEO_BT819=m -CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_BT856=m -CONFIG_VIDEO_BT866=m -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_DMA_CONTIG=m -CONFIG_VIDEOBUF2_DMA_SG=m -CONFIG_VIDEOBUF2_DVB=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_V4L2=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEOBUF_DMA_SG=m -CONFIG_VIDEOBUF_GEN=m -CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_VIDEO_CPIA2=m -CONFIG_VIDEO_CS3308=m -CONFIG_VIDEO_CS5345=m -CONFIG_VIDEO_CS53L32A=m -CONFIG_VIDEO_CX18_ALSA=m -CONFIG_VIDEO_CX18=m -CONFIG_VIDEO_CX231XX_ALSA=m -CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_VIDEO_CX231XX=m -CONFIG_VIDEO_CX231XX_RC=y -CONFIG_VIDEO_CX2341X=m -CONFIG_VIDEO_CX23885=m -CONFIG_VIDEO_CX25821_ALSA=m -CONFIG_VIDEO_CX25821=m -CONFIG_VIDEO_CX25840=m -CONFIG_VIDEO_CX88_ALSA=m -CONFIG_VIDEO_CX88_BLACKBIRD=m -CONFIG_VIDEO_CX88_DVB=m -CONFIG_VIDEO_CX88_ENABLE_VP3054=y -CONFIG_VIDEO_CX88=m -CONFIG_VIDEO_CX88_MPEG=m -CONFIG_VIDEO_CX88_VP3054=m -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_DT3155=m -CONFIG_VIDEO_DW9714=m -CONFIG_VIDEO_DW9807_VCM=m -CONFIG_VIDEO_EM28XX_ALSA=m -CONFIG_VIDEO_EM28XX_DVB=m -CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_RC=m -CONFIG_VIDEO_EM28XX_V4L2=m -CONFIG_VIDEO_ET8EK8=m -# CONFIG_VIDEO_FB_IVTV is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_GO7007_LOADER=m -CONFIG_VIDEO_GO7007=m -CONFIG_VIDEO_GO7007_USB=m -CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_HEXIUM_GEMINI=m -CONFIG_VIDEO_HEXIUM_ORION=m -CONFIG_VIDEO_HI556=m -CONFIG_VIDEO_I2C=m -CONFIG_VIDEO_IMX214=m -CONFIG_VIDEO_IMX219=m -CONFIG_VIDEO_IMX258=m -CONFIG_VIDEO_IMX274=m -CONFIG_VIDEO_IMX290=m -CONFIG_VIDEO_IMX319=m -CONFIG_VIDEO_IMX355=m -CONFIG_VIDEO_IPU3_CIO2=m -CONFIG_VIDEO_IR_I2C=m -CONFIG_VIDEO_IVTV_ALSA=m -# CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS is not set -CONFIG_VIDEO_IVTV=m -CONFIG_VIDEO_KS0127=m -CONFIG_VIDEO_LM3560=m -CONFIG_VIDEO_LM3646=m -CONFIG_VIDEO_M52790=m -CONFIG_VIDEO_M5MOLS=m -CONFIG_VIDEO_MEYE=m -CONFIG_VIDEO_ML86V7667=m -CONFIG_VIDEO_MSP3400=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_MXB=m -CONFIG_VIDEO_NOON010PC30=m -CONFIG_VIDEO_OV13858=m -CONFIG_VIDEO_OV2640=m -CONFIG_VIDEO_OV2659=m -CONFIG_VIDEO_OV2680=m -CONFIG_VIDEO_OV2685=m -CONFIG_VIDEO_OV2740=m -CONFIG_VIDEO_OV5647=m -CONFIG_VIDEO_OV5670=m -CONFIG_VIDEO_OV5675=m -CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV6650=m -CONFIG_VIDEO_OV7251=m -CONFIG_VIDEO_OV7640=m -CONFIG_VIDEO_OV7670=m -CONFIG_VIDEO_OV772X=m -CONFIG_VIDEO_OV7740=m -CONFIG_VIDEO_OV8856=m -CONFIG_VIDEO_OV9640=m -CONFIG_VIDEO_OV9650=m -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_PVRUSB2_DVB=y -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -CONFIG_VIDEO_RJ54N1=m -CONFIG_VIDEO_S5K4ECGX=m -CONFIG_VIDEO_S5K5BAF=m -CONFIG_VIDEO_S5K6A3=m -CONFIG_VIDEO_S5K6AA=m -CONFIG_VIDEO_SAA6588=m -CONFIG_VIDEO_SAA6752HS=m -CONFIG_VIDEO_SAA7110=m -CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_SAA7127=m -CONFIG_VIDEO_SAA7134_ALSA=m -CONFIG_VIDEO_SAA7134_DVB=m -CONFIG_VIDEO_SAA7134_GO7007=m -CONFIG_VIDEO_SAA7134=m -CONFIG_VIDEO_SAA7134_RC=y -CONFIG_VIDEO_SAA7146=m -CONFIG_VIDEO_SAA7146_VV=m -CONFIG_VIDEO_SAA7164=m -CONFIG_VIDEO_SAA717X=m -CONFIG_VIDEO_SAA7185=m -CONFIG_VIDEO_SMIAPP=m -CONFIG_VIDEO_SMIAPP_PLL=m -CONFIG_VIDEO_SOLO6X10=m -CONFIG_VIDEO_SONY_BTF_MPX=m -CONFIG_VIDEO_SR030PC30=m -CONFIG_VIDEO_STK1160_COMMON=m -CONFIG_VIDEO_STK1160=m -CONFIG_VIDEO_ST_MIPID02=m -CONFIG_VIDEO_TC358743_CEC=y -CONFIG_VIDEO_TC358743=m -CONFIG_VIDEO_TDA7432=m -CONFIG_VIDEO_TDA9840=m -CONFIG_VIDEO_TEA6415C=m -CONFIG_VIDEO_TEA6420=m -CONFIG_VIDEO_THS7303=m -CONFIG_VIDEO_THS8200=m -CONFIG_VIDEO_TLV320AIC23B=m -CONFIG_VIDEO_TM6000_ALSA=m -CONFIG_VIDEO_TM6000_DVB=m -CONFIG_VIDEO_TM6000=m -CONFIG_VIDEO_TUNER=m -CONFIG_VIDEO_TVAUDIO=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_VIDEO_TVP514X=m -CONFIG_VIDEO_TVP5150=m -CONFIG_VIDEO_TVP7002=m -CONFIG_VIDEO_TW2804=m -CONFIG_VIDEO_TW5864=m -CONFIG_VIDEO_TW686X=m -CONFIG_VIDEO_TW68=m -CONFIG_VIDEO_TW9903=m -CONFIG_VIDEO_TW9906=m -CONFIG_VIDEO_TW9910=m -CONFIG_VIDEO_UDA1342=m -CONFIG_VIDEO_UPD64031A=m -CONFIG_VIDEO_UPD64083=m -CONFIG_VIDEO_USBTV=m -CONFIG_VIDEO_V4L2_I2C=y -CONFIG_VIDEO_V4L2=m -CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_VIDEO_VP27SMPX=m -CONFIG_VIDEO_VPX3220=m -CONFIG_VIDEO_VS6624=m -CONFIG_VIDEO_WM8739=m -CONFIG_VIDEO_WM8775=m -# CONFIG_VIPERBOARD_ADC is not set -CONFIG_VIRT_DRIVERS=y -CONFIG_VIRTIO_BALLOON=m -CONFIG_VIRTIO_BLK=m -CONFIG_VIRTIO_CONSOLE=m -# CONFIG_VIRTIO_FS is not set -CONFIG_VIRTIO_INPUT=m -CONFIG_VIRTIO=m -# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set -CONFIG_VIRTIO_MMIO=m -CONFIG_VIRTIO_NET=m -CONFIG_VIRTIO_PCI_LEGACY=y -CONFIG_VIRTIO_PCI=m -CONFIG_VIRTIO_PMEM=m -CONFIG_VIRTIO_VSOCKETS_COMMON=m -CONFIG_VIRTIO_VSOCKETS=m -CONFIG_VIRT_WIFI=m -CONFIG_VITESSE_PHY=m -# CONFIG_VL53L0X_I2C is not set -# CONFIG_VL6180 is not set -# CONFIG_VLAN_8021Q_GVRP is not set -CONFIG_VLAN_8021Q=m -# CONFIG_VLAN_8021Q_MVRP is not set -CONFIG_VMD=y -CONFIG_VMWARE_PVSCSI=m -CONFIG_VMXNET3=m -CONFIG_VORTEX=m -CONFIG_VSOCKETS_DIAG=m -CONFIG_VSOCKETS_LOOPBACK=m -CONFIG_VSOCKETS=m -CONFIG_VSOCKMON=m -# CONFIG_VT6655 is not set -# CONFIG_VT6656 is not set -# CONFIG_VXGE_DEBUG_TRACE_ALL is not set -CONFIG_VXGE=m -CONFIG_VXLAN=m -# CONFIG_VZ89X is not set -CONFIG_W83627HF_WDT=m -CONFIG_W83877F_WDT=m -CONFIG_W83977F_WDT=m -CONFIG_WAFER_WDT=m -CONFIG_WANT_DEV_COREDUMP=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set -# CONFIG_WCN36XX_DEBUGFS is not set -CONFIG_WCN36XX=m -CONFIG_WDTPCI=m -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PRIV=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_SPY=y -CONFIG_WFX=m -CONFIG_WIL6210_DEBUGFS=y -CONFIG_WIL6210_ISR_COR=y -CONFIG_WIL6210=m -# CONFIG_WILC1000_HW_OOB_INTR is not set -CONFIG_WILC1000=m -CONFIG_WILC1000_SDIO=m -CONFIG_WILINK_PLATFORM_DATA=y -CONFIG_WIMAX_DEBUG_LEVEL=8 -CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 -CONFIG_WIMAX_I2400M=m -CONFIG_WIMAX_I2400M_USB=m -CONFIG_WIMAX=m -CONFIG_WINBOND_840=m -# CONFIG_WIREGUARD_DEBUG is not set -CONFIG_WIREGUARD=m -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_WDS=y -CONFIG_WIZNET_BUS_ANY=y -# CONFIG_WIZNET_BUS_DIRECT is not set -# CONFIG_WIZNET_BUS_INDIRECT is not set -CONFIG_WIZNET_W5100=m -CONFIG_WIZNET_W5300=m -CONFIG_WL1251=m -CONFIG_WL1251_SDIO=m -CONFIG_WL12XX=m -CONFIG_WL18XX=m -CONFIG_WLCORE=m -CONFIG_WLCORE_SDIO=m -CONFIG_WMI_BMOF=m -# CONFIG_X86_5LEVEL is not set -CONFIG_X86_ACPI_CPUFREQ=m -CONFIG_X86_AMD_FREQ_SENSITIVITY=m -# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set -CONFIG_X86_CPUID=m -# CONFIG_X86_DEBUG_FPU is not set -# CONFIG_X86_EXTENDED_PLATFORM is not set -CONFIG_X86_HV_CALLBACK_VECTOR=y -CONFIG_X86_INTEL_LPSS=y -CONFIG_X86_MSR=m -CONFIG_X86_P4_CLOCKMOD=m -CONFIG_X86_PCC_CPUFREQ=m -CONFIG_X86_PMEM_LEGACY_DEVICE=y -CONFIG_X86_PMEM_LEGACY=y -CONFIG_X86_POWERNOW_K8=m -# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set -CONFIG_X86_SPEEDSTEP_CENTRINO=m -CONFIG_X86_SPEEDSTEP_LIB=m -CONFIG_X86_X2APIC=y -CONFIG_X86_X32=y -# CONFIG_XDP_SOCKETS is not set -# CONFIG_XEN is not set -CONFIG_XFRM_AH=m -CONFIG_XFRM_ALGO=m -CONFIG_XFRM_ESPINTCP=y -CONFIG_XFRM_ESP=m -CONFIG_XFRM_INTERFACE=m -CONFIG_XFRM_IPCOMP=m -CONFIG_XFRM_MIGRATE=y -CONFIG_XFRM_OFFLOAD=y -CONFIG_XFRM_USER=m -# CONFIG_XFS_DEBUG is not set -CONFIG_XFS_FS=m -CONFIG_XFS_ONLINE_REPAIR=y -CONFIG_XFS_ONLINE_SCRUB=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_QUOTA=y -CONFIG_XFS_RT=y -# CONFIG_XFS_WARN is not set -CONFIG_XIAOMI_WMI=m -CONFIG_XILINX_AXI_EMAC=m -CONFIG_XILINX_GMII2RGMII=m -CONFIG_XILINX_LL_TEMAC=m -CONFIG_XILINX_WATCHDOG=m -# CONFIG_XILINX_XADC is not set -CONFIG_XOR_BLOCKS=m -CONFIG_XXHASH=y -CONFIG_YELLOWFIN=m -CONFIG_YENTA=m -CONFIG_Z3FOLD=y -CONFIG_ZBUD=y -# CONFIG_ZD1211RW_DEBUG is not set -CONFIG_ZD1211RW=m -CONFIG_ZEROPLUS_FF=y -CONFIG_ZIIRAVE_WATCHDOG=m -CONFIG_ZOPT2201=m -# CONFIG_ZPA2326 is not set -CONFIG_ZPOOL=y -CONFIG_ZRAM=m -# CONFIG_ZRAM_MEMORY_TRACKING is not set -CONFIG_ZRAM_WRITEBACK=y -# CONFIG_ZSMALLOC_PGTABLE_MAPPING is not set -# CONFIG_ZSMALLOC_STAT is not set -CONFIG_ZSMALLOC=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set -CONFIG_ZSWAP_COMPRESSOR_DEFAULT="zstd" -CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y -CONFIG_ZSWAP_DEFAULT_ON=y -CONFIG_ZSWAP=y -# CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD is not set -CONFIG_ZSWAP_ZPOOL_DEFAULT="zbud" -CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y -# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set -!CONFIG_ACPI_I2C_OPREGION= -!CONFIG_ARCH_USE_MEMREMAP_PROT= -!CONFIG_BINARY_PRINTF= -!CONFIG_BLK_DEV_IO_TRACE= -!CONFIG_BOOTTIME_TRACING= -!CONFIG_BRANCH_PROFILE_NONE= -!CONFIG_BSD_PROCESS_ACCT_V3= -!CONFIG_CONTEXT_SWITCH_TRACER= -!CONFIG_DEBUG_PAGE_REF= -!CONFIG_DEFAULT_SECURITY_SELINUX= -!CONFIG_DM_INIT= -!CONFIG_DRM_DEBUG_MM= -!CONFIG_DYNAMIC_EVENTS= -!CONFIG_DYNAMIC_MEMORY_LAYOUT= -!CONFIG_EARLY_PRINTK_USB= -!CONFIG_EFI_EARLYCON= -!CONFIG_ETHTOOL_NETLINK= -!CONFIG_EVENT_TRACING= -!CONFIG_EVM= -!CONFIG_EXT4_USE_FOR_EXT2= -!CONFIG_FTRACE_STARTUP_TEST= -!CONFIG_FTRACE_SYSCALLS= -!CONFIG_FUNCTION_ERROR_INJECTION= -!CONFIG_FUNCTION_TRACER= -!CONFIG_GENERIC_TRACER= -!CONFIG_HIST_TRIGGERS= -!CONFIG_HPET_MMAP= -!CONFIG_HWLAT_TRACER= -!CONFIG_IMA= -!CONFIG_INLINE_READ_UNLOCK= -!CONFIG_INLINE_READ_UNLOCK_IRQ= -!CONFIG_INLINE_SPIN_UNLOCK_IRQ= -!CONFIG_INLINE_WRITE_UNLOCK= -!CONFIG_INLINE_WRITE_UNLOCK_IRQ= -!CONFIG_INTEGRITY= -!CONFIG_INTEGRITY_AUDIT= -!CONFIG_INTEGRITY_SIGNATURE= -!CONFIG_IO_STRICT_DEVMEM= -!CONFIG_IP_PNP_BOOTP= -!CONFIG_IP_PNP_DHCP= -!CONFIG_IP_PNP_RARP= -!CONFIG_IRQSOFF_TRACER= -!CONFIG_KPROBE_EVENT_GEN_TEST= -!CONFIG_KPROBE_EVENTS= -!CONFIG_KPROBES_SANITY_TEST= -!CONFIG_KRETPROBES= -!CONFIG_LOGO_LINUX_CLUT224= -!CONFIG_LOGO_LINUX_MONO= -!CONFIG_LOGO_LINUX_VGA16= -!CONFIG_LSM_MMAP_MIN_ADDR= -!CONFIG_MD_AUTODETECT= -!CONFIG_MFD_88PM860X= -!CONFIG_MFD_AS3711= -!CONFIG_MFD_DA9052_I2C= -!CONFIG_MFD_DA9055= -!CONFIG_MFD_LP8788= -!CONFIG_MFD_MAX77843= -!CONFIG_MFD_MAX8925= -!CONFIG_MFD_MAX8997= -!CONFIG_MFD_MAX8998= -!CONFIG_MFD_PALMAS= -!CONFIG_MFD_RC5T583= -!CONFIG_MFD_SEC_CORE= -!CONFIG_MFD_SMSC= -!CONFIG_MFD_TPS65090= -!CONFIG_MFD_TPS6586X= -!CONFIG_MFD_TPS80031= -!CONFIG_MFD_WM831X_I2C= -!CONFIG_MFD_WM8350_I2C= -!CONFIG_MFD_WM8400= -!CONFIG_MMIOTRACE= -!CONFIG_MOUSE_PS2_SMBUS= -!CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS= -!CONFIG_NETFILTER_XT_TARGET_CONNSECMARK= -!CONFIG_NETFILTER_XT_TARGET_SECMARK= -!CONFIG_NETLABEL= -!CONFIG_NETPOLL= -!CONFIG_NET_POLL_CONTROLLER= -!CONFIG_NF_CONNTRACK_SECMARK= -!CONFIG_NOP_TRACER= -!CONFIG_OPROFILE= -!CONFIG_OPTPROBES= -!CONFIG_PMIC_ADP5520= -!CONFIG_PMIC_DA903X= -!CONFIG_PM_TRACE= -!CONFIG_POWER_SUPPLY_HWMON= -!CONFIG_PREEMPTIRQ_DELAY_TEST= -!CONFIG_PROBE_EVENTS= -!CONFIG_PROC_VMCORE= -!CONFIG_PROC_VMCORE_DEVICE_DUMP= -!CONFIG_PROFILE_ALL_BRANCHES= -!CONFIG_PROFILE_ANNOTATED_BRANCHES= -!CONFIG_RANDOMIZE_MEMORY= -!CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING= -!CONFIG_RING_BUFFER= -!CONFIG_RING_BUFFER_BENCHMARK= -!CONFIG_RING_BUFFER_STARTUP_TEST= -!CONFIG_ROOT_NFS= -!CONFIG_SCHED_TRACER= -!CONFIG_SECURITY_APPARMOR= -!CONFIG_SECURITY_LOADPIN= -!CONFIG_SECURITY_LOCKDOWN_LSM= -!CONFIG_SECURITY_NETWORK= -!CONFIG_SECURITY_NETWORK_XFRM= -!CONFIG_SECURITY_PATH= -!CONFIG_SECURITY_SAFESETID= -!CONFIG_SECURITY_SELINUX= -!CONFIG_SECURITY_SELINUX_AVC_STATS= -!CONFIG_SECURITY_SELINUX_BOOTPARAM= -!CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE= -!CONFIG_SECURITY_SELINUX_DEVELOP= -!CONFIG_SECURITY_SELINUX_DISABLE= -!CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE= -!CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS= -!CONFIG_SECURITY_SMACK= -!CONFIG_SECURITY_TOMOYO= -!CONFIG_SECURITY_WRITABLE_HOOKS= -!CONFIG_SECURITY_YAMA= -!CONFIG_SERIAL_8250_DETECT_IRQ= -!CONFIG_SERIAL_8250_MANY_PORTS= -!CONFIG_SERIAL_8250_RSA= -!CONFIG_SERIAL_8250_SHARE_IRQ= -!CONFIG_SERIAL_CORE_CONSOLE= -!CONFIG_SERIAL_EARLYCON= -!CONFIG_SND_SE6X= -!CONFIG_SND_SEQ_HRTIMER_DEFAULT= -!CONFIG_STACK_TRACER= -!CONFIG_STATIC_KEYS_SELFTEST= -!CONFIG_SYNTH_EVENTS= -!CONFIG_THERMAL_HWMON= -!CONFIG_TRACE_CLOCK= -!CONFIG_TRACE_EVAL_MAP_FILE= -!CONFIG_TRACE_EVENT_INJECT= -!CONFIG_TRACEPOINT_BENCHMARK= -!CONFIG_TRACEPOINTS= -!CONFIG_TRACER_SNAPSHOT= -!CONFIG_TRACING= -!CONFIG_TWL4030_CORE= -!CONFIG_TWL6040_CORE= -!CONFIG_UPROBE_EVENTS= -!CONFIG_UPROBES= -!CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT= -!CONFIG_VGACON_SOFT_SCROLLBACK_SIZE= -!CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK= -!CONFIG_X86_GOLDFISH= -!CONFIG_X86_INTEL_MID= -!CONFIG_X86_NEED_RELOCS= -!CONFIG_X86_VSMP= diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/11-update-01 b/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/11-update-01 deleted file mode 100644 index 874200b24..000000000 --- a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/11-update-01 +++ /dev/null @@ -1,10 +0,0 @@ -# Calculate format=kernel name=.config -CONFIG_CRASH_DUMP=y -# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set -CONFIG_PROC_VMCORE=y -# CONFIG_UFS_DEBUG is not set -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_VMWARE_BALLOON is not set -CONFIG_VMWARE_VMCI=m -CONFIG_VMWARE_VMCI_VSOCKETS=m diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/30-server b/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/30-server deleted file mode 100644 index 39dd3ea24..000000000 --- a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/30-server +++ /dev/null @@ -1,14 +0,0 @@ -# Calculate format=kernel name=.config merge(sys-kernel/calculate-sources[-desktop])!= -# CONFIG_BT is not set -# CONFIG_GAMEPORT is not set -# CONFIG_HZ_1000 is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_MACINTOSH_DRIVERS is not set -# CONFIG_MEDIA_SUPPORT is not set -# CONFIG_PREEMPT is not set -# CONFIG_RC_CORE is not set -# CONFIG_SOUND is not set -# CONFIG_USB_GADGET is not set diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4500_uksm.patch b/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4500_uksm.patch deleted file mode 100644 index 385cf030b..000000000 --- a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4500_uksm.patch +++ /dev/null @@ -1,6935 +0,0 @@ -# Calculate format=diff merge(sys-kernel/calculate-sources[uksm])!= -diff --git a/Documentation/vm/uksm.txt b/Documentation/vm/uksm.txt -new file mode 100644 -index 000000000000..be19a3127001 ---- /dev/null -+++ b/Documentation/vm/uksm.txt -@@ -0,0 +1,61 @@ -+The Ultra Kernel Samepage Merging feature -+---------------------------------------------- -+/* -+ * Ultra KSM. Copyright (C) 2011-2012 Nai Xia -+ * -+ * This is an improvement upon KSM. Some basic data structures and routines -+ * are borrowed from ksm.c . -+ * -+ * Its new features: -+ * 1. Full system scan: -+ * It automatically scans all user processes' anonymous VMAs. Kernel-user -+ * interaction to submit a memory area to KSM is no longer needed. -+ * -+ * 2. Rich area detection: -+ * It automatically detects rich areas containing abundant duplicated -+ * pages based. Rich areas are given a full scan speed. Poor areas are -+ * sampled at a reasonable speed with very low CPU consumption. -+ * -+ * 3. Ultra Per-page scan speed improvement: -+ * A new hash algorithm is proposed. As a result, on a machine with -+ * Core(TM)2 Quad Q9300 CPU in 32-bit mode and 800MHZ DDR2 main memory, it -+ * can scan memory areas that does not contain duplicated pages at speed of -+ * 627MB/sec ~ 2445MB/sec and can merge duplicated areas at speed of -+ * 477MB/sec ~ 923MB/sec. -+ * -+ * 4. Thrashing area avoidance: -+ * Thrashing area(an VMA that has frequent Ksm page break-out) can be -+ * filtered out. My benchmark shows it's more efficient than KSM's per-page -+ * hash value based volatile page detection. -+ * -+ * -+ * 5. Misc changes upon KSM: -+ * * It has a fully x86-opitmized memcmp dedicated for 4-byte-aligned page -+ * comparison. It's much faster than default C version on x86. -+ * * rmap_item now has an struct *page member to loosely cache a -+ * address-->page mapping, which reduces too much time-costly -+ * follow_page(). -+ * * The VMA creation/exit procedures are hooked to let the Ultra KSM know. -+ * * try_to_merge_two_pages() now can revert a pte if it fails. No break_ -+ * ksm is needed for this case. -+ * -+ * 6. Full Zero Page consideration(contributed by Figo Zhang) -+ * Now uksmd consider full zero pages as special pages and merge them to an -+ * special unswappable uksm zero page. -+ */ -+ -+ChangeLog: -+ -+2012-05-05 The creation of this Doc -+2012-05-08 UKSM 0.1.1.1 libc crash bug fix, api clean up, doc clean up. -+2012-05-28 UKSM 0.1.1.2 bug fix release -+2012-06-26 UKSM 0.1.2-beta1 first beta release for 0.1.2 -+2012-07-2 UKSM 0.1.2-beta2 -+2012-07-10 UKSM 0.1.2-beta3 -+2012-07-26 UKSM 0.1.2 Fine grained speed control, more scan optimization. -+2012-10-13 UKSM 0.1.2.1 Bug fixes. -+2012-12-31 UKSM 0.1.2.2 Minor bug fixes. -+2014-07-02 UKSM 0.1.2.3 Fix a " __this_cpu_read() in preemptible bug". -+2015-04-22 UKSM 0.1.2.4 Fix a race condition that can sometimes trigger anonying warnings. -+2016-09-10 UKSM 0.1.2.5 Fix a bug in dedup ratio calculation. -+2017-02-26 UKSM 0.1.2.6 Fix a bug in hugetlbpage handling and a race bug with page migration. -diff --git a/fs/exec.c b/fs/exec.c -index e6e8a9a70327..aa7b0ab67afa 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -62,6 +62,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c -index e9a6841fc25b..2d485b822b5f 100644 ---- a/fs/proc/meminfo.c -+++ b/fs/proc/meminfo.c -@@ -108,7 +108,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v) - #endif - show_val_kb(m, "PageTables: ", - global_zone_page_state(NR_PAGETABLE)); -- -+#ifdef CONFIG_UKSM -+ show_val_kb(m, "KsmZeroPages: ", -+ global_zone_page_state(NR_UKSM_ZERO_PAGES)); -+#endif - show_val_kb(m, "NFS_Unstable: ", 0); - show_val_kb(m, "Bounce: ", - global_zone_page_state(NR_BOUNCE)); -diff --git a/include/linux/ksm.h b/include/linux/ksm.h -index e48b1e453ff5..8cc8077cebf4 100644 ---- a/include/linux/ksm.h -+++ b/include/linux/ksm.h -@@ -21,20 +21,16 @@ struct mem_cgroup; - #ifdef CONFIG_KSM - int ksm_madvise(struct vm_area_struct *vma, unsigned long start, - unsigned long end, int advice, unsigned long *vm_flags); --int __ksm_enter(struct mm_struct *mm); --void __ksm_exit(struct mm_struct *mm); - --static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) -+static inline struct stable_node *page_stable_node(struct page *page) - { -- if (test_bit(MMF_VM_MERGEABLE, &oldmm->flags)) -- return __ksm_enter(mm); -- return 0; -+ return PageKsm(page) ? page_rmapping(page) : NULL; - } - --static inline void ksm_exit(struct mm_struct *mm) -+static inline void set_page_stable_node(struct page *page, -+ struct stable_node *stable_node) - { -- if (test_bit(MMF_VM_MERGEABLE, &mm->flags)) -- __ksm_exit(mm); -+ page->mapping = (void *)((unsigned long)stable_node | PAGE_MAPPING_KSM); - } - - /* -@@ -56,6 +52,33 @@ void ksm_migrate_page(struct page *newpage, struct page *oldpage); - bool reuse_ksm_page(struct page *page, - struct vm_area_struct *vma, unsigned long address); - -+#ifdef CONFIG_KSM_LEGACY -+int __ksm_enter(struct mm_struct *mm); -+void __ksm_exit(struct mm_struct *mm); -+static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) -+{ -+ if (test_bit(MMF_VM_MERGEABLE, &oldmm->flags)) -+ return __ksm_enter(mm); -+ return 0; -+} -+ -+static inline void ksm_exit(struct mm_struct *mm) -+{ -+ if (test_bit(MMF_VM_MERGEABLE, &mm->flags)) -+ __ksm_exit(mm); -+} -+ -+#elif defined(CONFIG_UKSM) -+static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) -+{ -+ return 0; -+} -+ -+static inline void ksm_exit(struct mm_struct *mm) -+{ -+} -+#endif /* !CONFIG_UKSM */ -+ - #else /* !CONFIG_KSM */ - - static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) -@@ -96,4 +119,6 @@ static inline bool reuse_ksm_page(struct page *page, - #endif /* CONFIG_MMU */ - #endif /* !CONFIG_KSM */ - -+#include -+ - #endif /* __LINUX_KSM_H */ -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index 64ede5f150dc..f7c58b497e88 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -367,6 +367,9 @@ struct vm_area_struct { - struct mempolicy *vm_policy; /* NUMA policy for the VMA */ - #endif - struct vm_userfaultfd_ctx vm_userfaultfd_ctx; -+#ifdef CONFIG_UKSM -+ struct vma_slot *uksm_vma_slot; -+#endif - } __randomize_layout; - - struct core_thread { -diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h -index f6f884970511..8ff0d75c2036 100644 ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -165,6 +165,9 @@ enum zone_stat_item { - NR_ZSPAGES, /* allocated in zsmalloc */ - #endif - NR_FREE_CMA_PAGES, -+#ifdef CONFIG_UKSM -+ NR_UKSM_ZERO_PAGES, -+#endif - NR_VM_ZONE_STAT_ITEMS }; - - enum node_stat_item { -diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h -index 56c1e8eb7bb0..757d18225cb0 100644 ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -1027,12 +1027,25 @@ extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn, - extern void untrack_pfn_moved(struct vm_area_struct *vma); - #endif - -+#ifdef CONFIG_UKSM -+static inline int is_uksm_zero_pfn(unsigned long pfn) -+{ -+ extern unsigned long uksm_zero_pfn; -+ return pfn == uksm_zero_pfn; -+} -+#else -+static inline int is_uksm_zero_pfn(unsigned long pfn) -+{ -+ return 0; -+} -+#endif -+ - #ifdef __HAVE_COLOR_ZERO_PAGE - static inline int is_zero_pfn(unsigned long pfn) - { - extern unsigned long zero_pfn; - unsigned long offset_from_zero_pfn = pfn - zero_pfn; -- return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT); -+ return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT) || is_uksm_zero_pfn(pfn); - } - - #define my_zero_pfn(addr) page_to_pfn(ZERO_PAGE(addr)) -@@ -1041,7 +1054,7 @@ static inline int is_zero_pfn(unsigned long pfn) - static inline int is_zero_pfn(unsigned long pfn) - { - extern unsigned long zero_pfn; -- return pfn == zero_pfn; -+ return (pfn == zero_pfn) || (is_uksm_zero_pfn(pfn)); - } - - static inline unsigned long my_zero_pfn(unsigned long addr) -diff --git a/include/linux/sradix-tree.h b/include/linux/sradix-tree.h -new file mode 100644 -index 000000000000..d71edba6b63f ---- /dev/null -+++ b/include/linux/sradix-tree.h -@@ -0,0 +1,77 @@ -+#ifndef _LINUX_SRADIX_TREE_H -+#define _LINUX_SRADIX_TREE_H -+ -+ -+#define INIT_SRADIX_TREE(root, mask) \ -+do { \ -+ (root)->height = 0; \ -+ (root)->gfp_mask = (mask); \ -+ (root)->rnode = NULL; \ -+} while (0) -+ -+#define ULONG_BITS (sizeof(unsigned long) * 8) -+#define SRADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) -+//#define SRADIX_TREE_MAP_SHIFT 6 -+//#define SRADIX_TREE_MAP_SIZE (1UL << SRADIX_TREE_MAP_SHIFT) -+//#define SRADIX_TREE_MAP_MASK (SRADIX_TREE_MAP_SIZE-1) -+ -+struct sradix_tree_node { -+ unsigned int height; /* Height from the bottom */ -+ unsigned int count; -+ unsigned int fulls; /* Number of full sublevel trees */ -+ struct sradix_tree_node *parent; -+ void *stores[0]; -+}; -+ -+/* A simple radix tree implementation */ -+struct sradix_tree_root { -+ unsigned int height; -+ struct sradix_tree_node *rnode; -+ -+ /* Where found to have available empty stores in its sublevels */ -+ struct sradix_tree_node *enter_node; -+ unsigned int shift; -+ unsigned int stores_size; -+ unsigned int mask; -+ unsigned long min; /* The first hole index */ -+ unsigned long num; -+ //unsigned long *height_to_maxindex; -+ -+ /* How the node is allocated and freed. */ -+ struct sradix_tree_node *(*alloc)(void); -+ void (*free)(struct sradix_tree_node *node); -+ -+ /* When a new node is added and removed */ -+ void (*extend)(struct sradix_tree_node *parent, struct sradix_tree_node *child); -+ void (*assign)(struct sradix_tree_node *node, unsigned int index, void *item); -+ void (*rm)(struct sradix_tree_node *node, unsigned int offset); -+}; -+ -+struct sradix_tree_path { -+ struct sradix_tree_node *node; -+ int offset; -+}; -+ -+static inline -+void init_sradix_tree_root(struct sradix_tree_root *root, unsigned long shift) -+{ -+ root->height = 0; -+ root->rnode = NULL; -+ root->shift = shift; -+ root->stores_size = 1UL << shift; -+ root->mask = root->stores_size - 1; -+} -+ -+ -+extern void *sradix_tree_next(struct sradix_tree_root *root, -+ struct sradix_tree_node *node, unsigned long index, -+ int (*iter)(void *, unsigned long)); -+ -+extern int sradix_tree_enter(struct sradix_tree_root *root, void **item, int num); -+ -+extern void sradix_tree_delete_from_leaf(struct sradix_tree_root *root, -+ struct sradix_tree_node *node, unsigned long index); -+ -+extern void *sradix_tree_lookup(struct sradix_tree_root *root, unsigned long index); -+ -+#endif /* _LINUX_SRADIX_TREE_H */ -diff --git a/include/linux/uksm.h b/include/linux/uksm.h -new file mode 100644 -index 000000000000..bb8651f534f2 ---- /dev/null -+++ b/include/linux/uksm.h -@@ -0,0 +1,149 @@ -+#ifndef __LINUX_UKSM_H -+#define __LINUX_UKSM_H -+/* -+ * Memory merging support. -+ * -+ * This code enables dynamic sharing of identical pages found in different -+ * memory areas, even if they are not shared by fork(). -+ */ -+ -+/* if !CONFIG_UKSM this file should not be compiled at all. */ -+#ifdef CONFIG_UKSM -+ -+#include -+#include -+#include -+#include -+#include -+ -+extern unsigned long zero_pfn __read_mostly; -+extern unsigned long uksm_zero_pfn __read_mostly; -+extern struct page *empty_uksm_zero_page; -+ -+/* must be done before linked to mm */ -+extern void uksm_vma_add_new(struct vm_area_struct *vma); -+extern void uksm_remove_vma(struct vm_area_struct *vma); -+ -+#define UKSM_SLOT_NEED_SORT (1 << 0) -+#define UKSM_SLOT_NEED_RERAND (1 << 1) -+#define UKSM_SLOT_SCANNED (1 << 2) /* It's scanned in this round */ -+#define UKSM_SLOT_FUL_SCANNED (1 << 3) -+#define UKSM_SLOT_IN_UKSM (1 << 4) -+ -+struct vma_slot { -+ struct sradix_tree_node *snode; -+ unsigned long sindex; -+ -+ struct list_head slot_list; -+ unsigned long fully_scanned_round; -+ unsigned long dedup_num; -+ unsigned long pages_scanned; -+ unsigned long this_sampled; -+ unsigned long last_scanned; -+ unsigned long pages_to_scan; -+ struct scan_rung *rung; -+ struct page **rmap_list_pool; -+ unsigned int *pool_counts; -+ unsigned long pool_size; -+ struct vm_area_struct *vma; -+ struct mm_struct *mm; -+ unsigned long ctime_j; -+ unsigned long pages; -+ unsigned long flags; -+ unsigned long pages_cowed; /* pages cowed this round */ -+ unsigned long pages_merged; /* pages merged this round */ -+ unsigned long pages_bemerged; -+ -+ /* when it has page merged in this eval round */ -+ struct list_head dedup_list; -+}; -+ -+static inline void uksm_unmap_zero_page(pte_t pte) -+{ -+ if (pte_pfn(pte) == uksm_zero_pfn) -+ __dec_zone_page_state(empty_uksm_zero_page, NR_UKSM_ZERO_PAGES); -+} -+ -+static inline void uksm_map_zero_page(pte_t pte) -+{ -+ if (pte_pfn(pte) == uksm_zero_pfn) -+ __inc_zone_page_state(empty_uksm_zero_page, NR_UKSM_ZERO_PAGES); -+} -+ -+static inline void uksm_cow_page(struct vm_area_struct *vma, struct page *page) -+{ -+ if (vma->uksm_vma_slot && PageKsm(page)) -+ vma->uksm_vma_slot->pages_cowed++; -+} -+ -+static inline void uksm_cow_pte(struct vm_area_struct *vma, pte_t pte) -+{ -+ if (vma->uksm_vma_slot && pte_pfn(pte) == uksm_zero_pfn) -+ vma->uksm_vma_slot->pages_cowed++; -+} -+ -+static inline int uksm_flags_can_scan(unsigned long vm_flags) -+{ -+#ifdef VM_SAO -+ if (vm_flags & VM_SAO) -+ return 0; -+#endif -+ -+ return !(vm_flags & (VM_PFNMAP | VM_IO | VM_DONTEXPAND | -+ VM_HUGETLB | VM_MIXEDMAP | VM_SHARED -+ | VM_MAYSHARE | VM_GROWSUP | VM_GROWSDOWN)); -+} -+ -+static inline void uksm_vm_flags_mod(unsigned long *vm_flags_p) -+{ -+ if (uksm_flags_can_scan(*vm_flags_p)) -+ *vm_flags_p |= VM_MERGEABLE; -+} -+ -+/* -+ * Just a wrapper for BUG_ON for where ksm_zeropage must not be. TODO: it will -+ * be removed when uksm zero page patch is stable enough. -+ */ -+static inline void uksm_bugon_zeropage(pte_t pte) -+{ -+ BUG_ON(pte_pfn(pte) == uksm_zero_pfn); -+} -+#else -+static inline void uksm_vma_add_new(struct vm_area_struct *vma) -+{ -+} -+ -+static inline void uksm_remove_vma(struct vm_area_struct *vma) -+{ -+} -+ -+static inline void uksm_unmap_zero_page(pte_t pte) -+{ -+} -+ -+static inline void uksm_map_zero_page(pte_t pte) -+{ -+} -+ -+static inline void uksm_cow_page(struct vm_area_struct *vma, struct page *page) -+{ -+} -+ -+static inline void uksm_cow_pte(struct vm_area_struct *vma, pte_t pte) -+{ -+} -+ -+static inline int uksm_flags_can_scan(unsigned long vm_flags) -+{ -+ return 0; -+} -+ -+static inline void uksm_vm_flags_mod(unsigned long *vm_flags_p) -+{ -+} -+ -+static inline void uksm_bugon_zeropage(pte_t pte) -+{ -+} -+#endif /* !CONFIG_UKSM */ -+#endif /* __LINUX_UKSM_H */ -diff --git a/kernel/fork.c b/kernel/fork.c -index efc5493203ae..97bd3a1ca732 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -603,7 +603,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, - __vma_link_rb(mm, tmp, rb_link, rb_parent); - rb_link = &tmp->vm_rb.rb_right; - rb_parent = &tmp->vm_rb; -- -+ uksm_vma_add_new(tmp); - mm->map_count++; - if (!(tmp->vm_flags & VM_WIPEONFORK)) - retval = copy_page_range(mm, oldmm, mpnt); -diff --git a/lib/Makefile b/lib/Makefile -index b1c42c10073b..dbd64025955c 100644 ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -29,7 +29,7 @@ endif - KCSAN_SANITIZE_random32.o := n - - lib-y := ctype.o string.o vsprintf.o cmdline.o \ -- rbtree.o radix-tree.o timerqueue.o xarray.o \ -+ rbtree.o radix-tree.o sradix-tree.o timerqueue.o xarray.o \ - idr.o extable.o sha1.o irq_regs.o argv_split.o \ - flex_proportions.o ratelimit.o show_mem.o \ - is_single_threaded.o plist.o decompress.o kobject_uevent.o \ -diff --git a/lib/sradix-tree.c b/lib/sradix-tree.c -new file mode 100644 -index 000000000000..ab21e6309b93 ---- /dev/null -+++ b/lib/sradix-tree.c -@@ -0,0 +1,476 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static inline int sradix_node_full(struct sradix_tree_root *root, struct sradix_tree_node *node) -+{ -+ return node->fulls == root->stores_size || -+ (node->height == 1 && node->count == root->stores_size); -+} -+ -+/* -+ * Extend a sradix tree so it can store key @index. -+ */ -+static int sradix_tree_extend(struct sradix_tree_root *root, unsigned long index) -+{ -+ struct sradix_tree_node *node; -+ unsigned int height; -+ -+ if (unlikely(root->rnode == NULL)) { -+ if (!(node = root->alloc())) -+ return -ENOMEM; -+ -+ node->height = 1; -+ root->rnode = node; -+ root->height = 1; -+ } -+ -+ /* Figure out what the height should be. */ -+ height = root->height; -+ index >>= root->shift * height; -+ -+ while (index) { -+ index >>= root->shift; -+ height++; -+ } -+ -+ while (height > root->height) { -+ unsigned int newheight; -+ -+ if (!(node = root->alloc())) -+ return -ENOMEM; -+ -+ /* Increase the height. */ -+ node->stores[0] = root->rnode; -+ root->rnode->parent = node; -+ if (root->extend) -+ root->extend(node, root->rnode); -+ -+ newheight = root->height + 1; -+ node->height = newheight; -+ node->count = 1; -+ if (sradix_node_full(root, root->rnode)) -+ node->fulls = 1; -+ -+ root->rnode = node; -+ root->height = newheight; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Search the next item from the current node, that is not NULL -+ * and can satify root->iter(). -+ */ -+void *sradix_tree_next(struct sradix_tree_root *root, -+ struct sradix_tree_node *node, unsigned long index, -+ int (*iter)(void *item, unsigned long height)) -+{ -+ unsigned long offset; -+ void *item; -+ -+ if (unlikely(node == NULL)) { -+ node = root->rnode; -+ for (offset = 0; offset < root->stores_size; offset++) { -+ item = node->stores[offset]; -+ if (item && (!iter || iter(item, node->height))) -+ break; -+ } -+ -+ if (unlikely(offset >= root->stores_size)) -+ return NULL; -+ -+ if (node->height == 1) -+ return item; -+ else -+ goto go_down; -+ } -+ -+ while (node) { -+ offset = (index & root->mask) + 1; -+ for (; offset < root->stores_size; offset++) { -+ item = node->stores[offset]; -+ if (item && (!iter || iter(item, node->height))) -+ break; -+ } -+ -+ if (offset < root->stores_size) -+ break; -+ -+ node = node->parent; -+ index >>= root->shift; -+ } -+ -+ if (!node) -+ return NULL; -+ -+ while (node->height > 1) { -+go_down: -+ node = item; -+ for (offset = 0; offset < root->stores_size; offset++) { -+ item = node->stores[offset]; -+ if (item && (!iter || iter(item, node->height))) -+ break; -+ } -+ -+ if (unlikely(offset >= root->stores_size)) -+ return NULL; -+ } -+ -+ BUG_ON(offset > root->stores_size); -+ -+ return item; -+} -+ -+/* -+ * Blindly insert the item to the tree. Typically, we reuse the -+ * first empty store item. -+ */ -+int sradix_tree_enter(struct sradix_tree_root *root, void **item, int num) -+{ -+ unsigned long index; -+ unsigned int height; -+ struct sradix_tree_node *node, *tmp = NULL; -+ int offset, offset_saved; -+ void **store = NULL; -+ int error, i, j, shift; -+ -+go_on: -+ index = root->min; -+ -+ if (root->enter_node && !sradix_node_full(root, root->enter_node)) { -+ node = root->enter_node; -+ BUG_ON((index >> (root->shift * root->height))); -+ } else { -+ node = root->rnode; -+ if (node == NULL || (index >> (root->shift * root->height)) -+ || sradix_node_full(root, node)) { -+ error = sradix_tree_extend(root, index); -+ if (error) -+ return error; -+ -+ node = root->rnode; -+ } -+ } -+ -+ -+ height = node->height; -+ shift = (height - 1) * root->shift; -+ offset = (index >> shift) & root->mask; -+ while (shift > 0) { -+ offset_saved = offset; -+ for (; offset < root->stores_size; offset++) { -+ store = &node->stores[offset]; -+ tmp = *store; -+ -+ if (!tmp || !sradix_node_full(root, tmp)) -+ break; -+ } -+ BUG_ON(offset >= root->stores_size); -+ -+ if (offset != offset_saved) { -+ index += (offset - offset_saved) << shift; -+ index &= ~((1UL << shift) - 1); -+ } -+ -+ if (!tmp) { -+ if (!(tmp = root->alloc())) -+ return -ENOMEM; -+ -+ tmp->height = shift / root->shift; -+ *store = tmp; -+ tmp->parent = node; -+ node->count++; -+// if (root->extend) -+// root->extend(node, tmp); -+ } -+ -+ node = tmp; -+ shift -= root->shift; -+ offset = (index >> shift) & root->mask; -+ } -+ -+ BUG_ON(node->height != 1); -+ -+ -+ store = &node->stores[offset]; -+ for (i = 0, j = 0; -+ j < root->stores_size - node->count && -+ i < root->stores_size - offset && j < num; i++) { -+ if (!store[i]) { -+ store[i] = item[j]; -+ if (root->assign) -+ root->assign(node, index + i, item[j]); -+ j++; -+ } -+ } -+ -+ node->count += j; -+ root->num += j; -+ num -= j; -+ -+ while (sradix_node_full(root, node)) { -+ node = node->parent; -+ if (!node) -+ break; -+ -+ node->fulls++; -+ } -+ -+ if (unlikely(!node)) { -+ /* All nodes are full */ -+ root->min = 1 << (root->height * root->shift); -+ root->enter_node = NULL; -+ } else { -+ root->min = index + i - 1; -+ root->min |= (1UL << (node->height - 1)) - 1; -+ root->min++; -+ root->enter_node = node; -+ } -+ -+ if (num) { -+ item += j; -+ goto go_on; -+ } -+ -+ return 0; -+} -+ -+ -+/** -+ * sradix_tree_shrink - shrink height of a sradix tree to minimal -+ * @root sradix tree root -+ * -+ */ -+static inline void sradix_tree_shrink(struct sradix_tree_root *root) -+{ -+ /* try to shrink tree height */ -+ while (root->height > 1) { -+ struct sradix_tree_node *to_free = root->rnode; -+ -+ /* -+ * The candidate node has more than one child, or its child -+ * is not at the leftmost store, we cannot shrink. -+ */ -+ if (to_free->count != 1 || !to_free->stores[0]) -+ break; -+ -+ root->rnode = to_free->stores[0]; -+ root->rnode->parent = NULL; -+ root->height--; -+ if (unlikely(root->enter_node == to_free)) -+ root->enter_node = NULL; -+ root->free(to_free); -+ } -+} -+ -+/* -+ * Del the item on the known leaf node and index -+ */ -+void sradix_tree_delete_from_leaf(struct sradix_tree_root *root, -+ struct sradix_tree_node *node, unsigned long index) -+{ -+ unsigned int offset; -+ struct sradix_tree_node *start, *end; -+ -+ BUG_ON(node->height != 1); -+ -+ start = node; -+ while (node && !(--node->count)) -+ node = node->parent; -+ -+ end = node; -+ if (!node) { -+ root->rnode = NULL; -+ root->height = 0; -+ root->min = 0; -+ root->num = 0; -+ root->enter_node = NULL; -+ } else { -+ offset = (index >> (root->shift * (node->height - 1))) & root->mask; -+ if (root->rm) -+ root->rm(node, offset); -+ node->stores[offset] = NULL; -+ root->num--; -+ if (root->min > index) { -+ root->min = index; -+ root->enter_node = node; -+ } -+ } -+ -+ if (start != end) { -+ do { -+ node = start; -+ start = start->parent; -+ if (unlikely(root->enter_node == node)) -+ root->enter_node = end; -+ root->free(node); -+ } while (start != end); -+ -+ /* -+ * Note that shrink may free "end", so enter_node still need to -+ * be checked inside. -+ */ -+ sradix_tree_shrink(root); -+ } else if (node->count == root->stores_size - 1) { -+ /* It WAS a full leaf node. Update the ancestors */ -+ node = node->parent; -+ while (node) { -+ node->fulls--; -+ if (node->fulls != root->stores_size - 1) -+ break; -+ -+ node = node->parent; -+ } -+ } -+} -+ -+void *sradix_tree_lookup(struct sradix_tree_root *root, unsigned long index) -+{ -+ unsigned int height, offset; -+ struct sradix_tree_node *node; -+ int shift; -+ -+ node = root->rnode; -+ if (node == NULL || (index >> (root->shift * root->height))) -+ return NULL; -+ -+ height = root->height; -+ shift = (height - 1) * root->shift; -+ -+ do { -+ offset = (index >> shift) & root->mask; -+ node = node->stores[offset]; -+ if (!node) -+ return NULL; -+ -+ shift -= root->shift; -+ } while (shift >= 0); -+ -+ return node; -+} -+ -+/* -+ * Return the item if it exists, otherwise create it in place -+ * and return the created item. -+ */ -+void *sradix_tree_lookup_create(struct sradix_tree_root *root, -+ unsigned long index, void *(*item_alloc)(void)) -+{ -+ unsigned int height, offset; -+ struct sradix_tree_node *node, *tmp; -+ void *item; -+ int shift, error; -+ -+ if (root->rnode == NULL || (index >> (root->shift * root->height))) { -+ if (item_alloc) { -+ error = sradix_tree_extend(root, index); -+ if (error) -+ return NULL; -+ } else { -+ return NULL; -+ } -+ } -+ -+ node = root->rnode; -+ height = root->height; -+ shift = (height - 1) * root->shift; -+ -+ do { -+ offset = (index >> shift) & root->mask; -+ if (!node->stores[offset]) { -+ if (!(tmp = root->alloc())) -+ return NULL; -+ -+ tmp->height = shift / root->shift; -+ node->stores[offset] = tmp; -+ tmp->parent = node; -+ node->count++; -+ node = tmp; -+ } else { -+ node = node->stores[offset]; -+ } -+ -+ shift -= root->shift; -+ } while (shift > 0); -+ -+ BUG_ON(node->height != 1); -+ offset = index & root->mask; -+ if (node->stores[offset]) { -+ return node->stores[offset]; -+ } else if (item_alloc) { -+ if (!(item = item_alloc())) -+ return NULL; -+ -+ node->stores[offset] = item; -+ -+ /* -+ * NOTE: we do NOT call root->assign here, since this item is -+ * newly created by us having no meaning. Caller can call this -+ * if it's necessary to do so. -+ */ -+ -+ node->count++; -+ root->num++; -+ -+ while (sradix_node_full(root, node)) { -+ node = node->parent; -+ if (!node) -+ break; -+ -+ node->fulls++; -+ } -+ -+ if (unlikely(!node)) { -+ /* All nodes are full */ -+ root->min = 1 << (root->height * root->shift); -+ } else { -+ if (root->min == index) { -+ root->min |= (1UL << (node->height - 1)) - 1; -+ root->min++; -+ root->enter_node = node; -+ } -+ } -+ -+ return item; -+ } else { -+ return NULL; -+ } -+ -+} -+ -+int sradix_tree_delete(struct sradix_tree_root *root, unsigned long index) -+{ -+ unsigned int height, offset; -+ struct sradix_tree_node *node; -+ int shift; -+ -+ node = root->rnode; -+ if (node == NULL || (index >> (root->shift * root->height))) -+ return -ENOENT; -+ -+ height = root->height; -+ shift = (height - 1) * root->shift; -+ -+ do { -+ offset = (index >> shift) & root->mask; -+ node = node->stores[offset]; -+ if (!node) -+ return -ENOENT; -+ -+ shift -= root->shift; -+ } while (shift > 0); -+ -+ offset = index & root->mask; -+ if (!node->stores[offset]) -+ return -ENOENT; -+ -+ sradix_tree_delete_from_leaf(root, node, index); -+ -+ return 0; -+} -diff --git a/mm/Kconfig b/mm/Kconfig -index f2104cc0d35c..6787eab6fea8 100644 ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -321,6 +321,32 @@ config KSM - See Documentation/vm/ksm.rst for more information: KSM is inactive - until a program has madvised that an area is MADV_MERGEABLE, and - root has set /sys/kernel/mm/ksm/run to 1 (if CONFIG_SYSFS is set). -+choice -+ prompt "Choose UKSM/KSM strategy" -+ default UKSM -+ depends on KSM -+ help -+ This option allows to select a UKSM/KSM stragety. -+ -+config UKSM -+ bool "Ultra-KSM for page merging" -+ depends on KSM -+ help -+ UKSM is inspired by the Linux kernel project \u2014 KSM(Kernel Same -+ page Merging), but with a fundamentally rewritten core algorithm. With -+ an advanced algorithm, UKSM now can transparently scans all anonymously -+ mapped user space applications with an significantly improved scan speed -+ and CPU efficiency. Since KVM is friendly to KSM, KVM can also benefit from -+ UKSM. Now UKSM has its first stable release and first real world enterprise user. -+ For more information, please goto its project page. -+ (github.com/dolohow/uksm) -+ -+config KSM_LEGACY -+ bool "Legacy KSM implementation" -+ depends on KSM -+ help -+ The legacy KSM implementation from Red Hat. -+endchoice - - config DEFAULT_MMAP_MIN_ADDR - int "Low address space to protect from user allocation" -diff --git a/mm/Makefile b/mm/Makefile -index 6e9d46b2efc9..fae71acbe7f0 100644 ---- a/mm/Makefile -+++ b/mm/Makefile -@@ -76,7 +76,8 @@ obj-$(CONFIG_SPARSEMEM) += sparse.o - obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o - obj-$(CONFIG_SLOB) += slob.o - obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o --obj-$(CONFIG_KSM) += ksm.o -+obj-$(CONFIG_KSM_LEGACY) += ksm.o -+obj-$(CONFIG_UKSM) += uksm.o - obj-$(CONFIG_PAGE_POISONING) += page_poison.o - obj-$(CONFIG_SLAB) += slab.o - obj-$(CONFIG_SLUB) += slub.o -diff --git a/mm/ksm.c b/mm/ksm.c -index 4102034cd55a..13ea01100de2 100644 ---- a/mm/ksm.c -+++ b/mm/ksm.c -@@ -857,17 +857,6 @@ static int unmerge_ksm_pages(struct vm_area_struct *vma, - return err; - } - --static inline struct stable_node *page_stable_node(struct page *page) --{ -- return PageKsm(page) ? page_rmapping(page) : NULL; --} -- --static inline void set_page_stable_node(struct page *page, -- struct stable_node *stable_node) --{ -- page->mapping = (void *)((unsigned long)stable_node | PAGE_MAPPING_KSM); --} -- - #ifdef CONFIG_SYSFS - /* - * Only called through the sysfs control interface: -diff --git a/mm/memory.c b/mm/memory.c -index 3ecad55103ad..fe4cb386639f 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -143,6 +143,25 @@ EXPORT_SYMBOL(zero_pfn); - - unsigned long highest_memmap_pfn __read_mostly; - -+#ifdef CONFIG_UKSM -+unsigned long uksm_zero_pfn __read_mostly; -+EXPORT_SYMBOL_GPL(uksm_zero_pfn); -+struct page *empty_uksm_zero_page; -+ -+static int __init setup_uksm_zero_page(void) -+{ -+ empty_uksm_zero_page = alloc_pages(__GFP_ZERO & ~__GFP_MOVABLE, 0); -+ if (!empty_uksm_zero_page) -+ panic("Oh boy, that early out of memory?"); -+ -+ SetPageReserved(empty_uksm_zero_page); -+ uksm_zero_pfn = page_to_pfn(empty_uksm_zero_page); -+ -+ return 0; -+} -+core_initcall(setup_uksm_zero_page); -+#endif -+ - /* - * CONFIG_MMU architectures set up ZERO_PAGE in their paging_init() - */ -@@ -158,6 +177,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member, long count) - trace_rss_stat(mm, member, count); - } - -+ - #if defined(SPLIT_RSS_COUNTING) - - void sync_mm_rss(struct mm_struct *mm) -@@ -801,6 +821,11 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, - get_page(page); - page_dup_rmap(page, false); - rss[mm_counter(page)]++; -+ -+ /* Should return NULL in vm_normal_page() */ -+ uksm_bugon_zeropage(pte); -+ } else { -+ uksm_map_zero_page(pte); - } - - out_set_pte: -@@ -1073,8 +1098,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, - ptent = ptep_get_and_clear_full(mm, addr, pte, - tlb->fullmm); - tlb_remove_tlb_entry(tlb, pte, addr); -- if (unlikely(!page)) -+ if (unlikely(!page)) { -+ uksm_unmap_zero_page(ptent); - continue; -+ } - - if (!PageAnon(page)) { - if (pte_dirty(ptent)) { -@@ -2410,6 +2437,7 @@ static inline bool cow_user_page(struct page *dst, struct page *src, - - if (likely(src)) { - copy_user_highpage(dst, src, addr, vma); -+ uksm_cow_page(vma, src); - return true; - } - -@@ -2655,6 +2683,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) - vmf->address); - if (!new_page) - goto oom; -+ uksm_cow_pte(vma, vmf->orig_pte); - } else { - new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, - vmf->address); -@@ -2697,7 +2726,9 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) - mm_counter_file(old_page)); - inc_mm_counter_fast(mm, MM_ANONPAGES); - } -+ uksm_bugon_zeropage(vmf->orig_pte); - } else { -+ uksm_unmap_zero_page(vmf->orig_pte); - inc_mm_counter_fast(mm, MM_ANONPAGES); - } - flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte)); -diff --git a/mm/mmap.c b/mm/mmap.c -index 8c7ca737a19b..a924cb128844 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -181,6 +182,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) - if (vma->vm_file) - fput(vma->vm_file); - mpol_put(vma_policy(vma)); -+ uksm_remove_vma(vma); - vm_area_free(vma); - return next; - } -@@ -708,9 +710,16 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - long adjust_next = 0; - int remove_next = 0; - -+/* -+ * to avoid deadlock, ksm_remove_vma must be done before any spin_lock is -+ * acquired -+ */ -+ uksm_remove_vma(vma); -+ - if (next && !insert) { - struct vm_area_struct *exporter = NULL, *importer = NULL; - -+ uksm_remove_vma(next); - if (end >= next->vm_end) { - /* - * vma expands, overlapping all the next, and -@@ -841,6 +850,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - end_changed = true; - } - vma->vm_pgoff = pgoff; -+ - if (adjust_next) { - next->vm_start += adjust_next << PAGE_SHIFT; - next->vm_pgoff += adjust_next; -@@ -946,6 +956,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - if (remove_next == 2) { - remove_next = 1; - end = next->vm_end; -+ uksm_remove_vma(next); - goto again; - } - else if (next) -@@ -972,10 +983,14 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - */ - VM_WARN_ON(mm->highest_vm_end != vm_end_gap(vma)); - } -+ } else { -+ if (next && !insert) -+ uksm_vma_add_new(next); - } - if (insert && file) - uprobe_mmap(insert); - -+ uksm_vma_add_new(vma); - validate_mm(mm); - - return 0; -@@ -1434,6 +1449,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr, - vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) | - mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; - -+ /* If uksm is enabled, we add VM_MERGEABLE to new VMAs. */ -+ uksm_vm_flags_mod(&vm_flags); -+ - if (flags & MAP_LOCKED) - if (!can_do_mlock()) - return -EPERM; -@@ -1801,6 +1819,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, - allow_write_access(file); - } - file = vma->vm_file; -+ uksm_vma_add_new(vma); - out: - perf_event_mmap(vma); - -@@ -1843,6 +1862,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, - if (vm_flags & VM_DENYWRITE) - allow_write_access(file); - free_vma: -+ uksm_remove_vma(vma); - vm_area_free(vma); - unacct_error: - if (charged) -@@ -2705,6 +2725,8 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, - else - err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); - -+ uksm_vma_add_new(new); -+ - /* Success. */ - if (!err) - return 0; -@@ -3012,6 +3034,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla - if ((flags & (~VM_EXEC)) != 0) - return -EINVAL; - flags |= VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; -+ uksm_vm_flags_mod(&flags); - - mapped_addr = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED); - if (IS_ERR_VALUE(mapped_addr)) -@@ -3062,6 +3085,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla - vma->vm_flags = flags; - vma->vm_page_prot = vm_get_page_prot(flags); - vma_link(mm, vma, prev, rb_link, rb_parent); -+ uksm_vma_add_new(vma); - out: - perf_event_mmap(vma); - mm->total_vm += len >> PAGE_SHIFT; -@@ -3139,6 +3163,12 @@ void exit_mmap(struct mm_struct *mm) - mmap_write_unlock(mm); - } - -+ /* -+ * Taking write lock on mmap does not harm others, -+ * but it's crucial for uksm to avoid races. -+ */ -+ mmap_write_lock(mm); -+ - if (mm->locked_vm) { - vma = mm->mmap; - while (vma) { -@@ -3173,6 +3203,11 @@ void exit_mmap(struct mm_struct *mm) - vma = remove_vma(vma); - } - vm_unacct_memory(nr_accounted); -+ -+ mm->mmap = NULL; -+ mm->mm_rb = RB_ROOT; -+ vmacache_invalidate(mm); -+ mmap_write_unlock(mm); - } - - /* Insert vm structure into process list sorted by address -@@ -3280,6 +3315,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, - new_vma->vm_ops->open(new_vma); - vma_link(mm, new_vma, prev, rb_link, rb_parent); - *need_rmap_locks = false; -+ uksm_vma_add_new(new_vma); - } - return new_vma; - -@@ -3432,6 +3468,7 @@ static struct vm_area_struct *__install_special_mapping( - vm_stat_account(mm, vma->vm_flags, len >> PAGE_SHIFT); - - perf_event_mmap(vma); -+ uksm_vma_add_new(vma); - - return vma; - -diff --git a/mm/uksm.c b/mm/uksm.c -new file mode 100644 -index 000000000000..c762d1c1d8a7 ---- /dev/null -+++ b/mm/uksm.c -@@ -0,0 +1,5613 @@ -+/* -+ * Ultra KSM. Copyright (C) 2011-2012 Nai Xia -+ * -+ * This is an improvement upon KSM. Some basic data structures and routines -+ * are borrowed from ksm.c . -+ * -+ * Its new features: -+ * 1. Full system scan: -+ * It automatically scans all user processes' anonymous VMAs. Kernel-user -+ * interaction to submit a memory area to KSM is no longer needed. -+ * -+ * 2. Rich area detection: -+ * It automatically detects rich areas containing abundant duplicated -+ * pages based. Rich areas are given a full scan speed. Poor areas are -+ * sampled at a reasonable speed with very low CPU consumption. -+ * -+ * 3. Ultra Per-page scan speed improvement: -+ * A new hash algorithm is proposed. As a result, on a machine with -+ * Core(TM)2 Quad Q9300 CPU in 32-bit mode and 800MHZ DDR2 main memory, it -+ * can scan memory areas that does not contain duplicated pages at speed of -+ * 627MB/sec ~ 2445MB/sec and can merge duplicated areas at speed of -+ * 477MB/sec ~ 923MB/sec. -+ * -+ * 4. Thrashing area avoidance: -+ * Thrashing area(an VMA that has frequent Ksm page break-out) can be -+ * filtered out. My benchmark shows it's more efficient than KSM's per-page -+ * hash value based volatile page detection. -+ * -+ * -+ * 5. Misc changes upon KSM: -+ * * It has a fully x86-opitmized memcmp dedicated for 4-byte-aligned page -+ * comparison. It's much faster than default C version on x86. -+ * * rmap_item now has an struct *page member to loosely cache a -+ * address-->page mapping, which reduces too much time-costly -+ * follow_page(). -+ * * The VMA creation/exit procedures are hooked to let the Ultra KSM know. -+ * * try_to_merge_two_pages() now can revert a pte if it fails. No break_ -+ * ksm is needed for this case. -+ * -+ * 6. Full Zero Page consideration(contributed by Figo Zhang) -+ * Now uksmd consider full zero pages as special pages and merge them to an -+ * special unswappable uksm zero page. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "internal.h" -+ -+#ifdef CONFIG_X86 -+#undef memcmp -+ -+#ifdef CONFIG_X86_32 -+#define memcmp memcmpx86_32 -+/* -+ * Compare 4-byte-aligned address s1 and s2, with length n -+ */ -+int memcmpx86_32(void *s1, void *s2, size_t n) -+{ -+ size_t num = n / 4; -+ register int res; -+ -+ __asm__ __volatile__ -+ ( -+ "testl %3,%3\n\t" -+ "repe; cmpsd\n\t" -+ "je 1f\n\t" -+ "sbbl %0,%0\n\t" -+ "orl $1,%0\n" -+ "1:" -+ : "=&a" (res), "+&S" (s1), "+&D" (s2), "+&c" (num) -+ : "0" (0) -+ : "cc"); -+ -+ return res; -+} -+ -+/* -+ * Check the page is all zero ? -+ */ -+static int is_full_zero(const void *s1, size_t len) -+{ -+ unsigned char same; -+ -+ len /= 4; -+ -+ __asm__ __volatile__ -+ ("repe; scasl;" -+ "sete %0" -+ : "=qm" (same), "+D" (s1), "+c" (len) -+ : "a" (0) -+ : "cc"); -+ -+ return same; -+} -+ -+ -+#elif defined(CONFIG_X86_64) -+#define memcmp memcmpx86_64 -+/* -+ * Compare 8-byte-aligned address s1 and s2, with length n -+ */ -+int memcmpx86_64(void *s1, void *s2, size_t n) -+{ -+ size_t num = n / 8; -+ register int res; -+ -+ __asm__ __volatile__ -+ ( -+ "testq %q3,%q3\n\t" -+ "repe; cmpsq\n\t" -+ "je 1f\n\t" -+ "sbbq %q0,%q0\n\t" -+ "orq $1,%q0\n" -+ "1:" -+ : "=&a" (res), "+&S" (s1), "+&D" (s2), "+&c" (num) -+ : "0" (0) -+ : "cc"); -+ -+ return res; -+} -+ -+static int is_full_zero(const void *s1, size_t len) -+{ -+ unsigned char same; -+ -+ len /= 8; -+ -+ __asm__ __volatile__ -+ ("repe; scasq;" -+ "sete %0" -+ : "=qm" (same), "+D" (s1), "+c" (len) -+ : "a" (0) -+ : "cc"); -+ -+ return same; -+} -+ -+#endif -+#else -+static int is_full_zero(const void *s1, size_t len) -+{ -+ unsigned long *src = s1; -+ int i; -+ -+ len /= sizeof(*src); -+ -+ for (i = 0; i < len; i++) { -+ if (src[i]) -+ return 0; -+ } -+ -+ return 1; -+} -+#endif -+ -+#define UKSM_RUNG_ROUND_FINISHED (1 << 0) -+#define TIME_RATIO_SCALE 10000 -+ -+#define SLOT_TREE_NODE_SHIFT 8 -+#define SLOT_TREE_NODE_STORE_SIZE (1UL << SLOT_TREE_NODE_SHIFT) -+struct slot_tree_node { -+ unsigned long size; -+ struct sradix_tree_node snode; -+ void *stores[SLOT_TREE_NODE_STORE_SIZE]; -+}; -+ -+static struct kmem_cache *slot_tree_node_cachep; -+ -+static struct sradix_tree_node *slot_tree_node_alloc(void) -+{ -+ struct slot_tree_node *p; -+ -+ p = kmem_cache_zalloc(slot_tree_node_cachep, GFP_KERNEL | -+ __GFP_NORETRY | __GFP_NOWARN); -+ if (!p) -+ return NULL; -+ -+ return &p->snode; -+} -+ -+static void slot_tree_node_free(struct sradix_tree_node *node) -+{ -+ struct slot_tree_node *p; -+ -+ p = container_of(node, struct slot_tree_node, snode); -+ kmem_cache_free(slot_tree_node_cachep, p); -+} -+ -+static void slot_tree_node_extend(struct sradix_tree_node *parent, -+ struct sradix_tree_node *child) -+{ -+ struct slot_tree_node *p, *c; -+ -+ p = container_of(parent, struct slot_tree_node, snode); -+ c = container_of(child, struct slot_tree_node, snode); -+ -+ p->size += c->size; -+} -+ -+void slot_tree_node_assign(struct sradix_tree_node *node, -+ unsigned int index, void *item) -+{ -+ struct vma_slot *slot = item; -+ struct slot_tree_node *cur; -+ -+ slot->snode = node; -+ slot->sindex = index; -+ -+ while (node) { -+ cur = container_of(node, struct slot_tree_node, snode); -+ cur->size += slot->pages; -+ node = node->parent; -+ } -+} -+ -+void slot_tree_node_rm(struct sradix_tree_node *node, unsigned int offset) -+{ -+ struct vma_slot *slot; -+ struct slot_tree_node *cur; -+ unsigned long pages; -+ -+ if (node->height == 1) { -+ slot = node->stores[offset]; -+ pages = slot->pages; -+ } else { -+ cur = container_of(node->stores[offset], -+ struct slot_tree_node, snode); -+ pages = cur->size; -+ } -+ -+ while (node) { -+ cur = container_of(node, struct slot_tree_node, snode); -+ cur->size -= pages; -+ node = node->parent; -+ } -+} -+ -+unsigned long slot_iter_index; -+int slot_iter(void *item, unsigned long height) -+{ -+ struct slot_tree_node *node; -+ struct vma_slot *slot; -+ -+ if (height == 1) { -+ slot = item; -+ if (slot_iter_index < slot->pages) { -+ /*in this one*/ -+ return 1; -+ } else { -+ slot_iter_index -= slot->pages; -+ return 0; -+ } -+ -+ } else { -+ node = container_of(item, struct slot_tree_node, snode); -+ if (slot_iter_index < node->size) { -+ /*in this one*/ -+ return 1; -+ } else { -+ slot_iter_index -= node->size; -+ return 0; -+ } -+ } -+} -+ -+ -+static inline void slot_tree_init_root(struct sradix_tree_root *root) -+{ -+ init_sradix_tree_root(root, SLOT_TREE_NODE_SHIFT); -+ root->alloc = slot_tree_node_alloc; -+ root->free = slot_tree_node_free; -+ root->extend = slot_tree_node_extend; -+ root->assign = slot_tree_node_assign; -+ root->rm = slot_tree_node_rm; -+} -+ -+void slot_tree_init(void) -+{ -+ slot_tree_node_cachep = kmem_cache_create("slot_tree_node", -+ sizeof(struct slot_tree_node), 0, -+ SLAB_PANIC | SLAB_RECLAIM_ACCOUNT, -+ NULL); -+} -+ -+ -+/* Each rung of this ladder is a list of VMAs having a same scan ratio */ -+struct scan_rung { -+ //struct list_head scanned_list; -+ struct sradix_tree_root vma_root; -+ struct sradix_tree_root vma_root2; -+ -+ struct vma_slot *current_scan; -+ unsigned long current_offset; -+ -+ /* -+ * The initial value for current_offset, it should loop over -+ * [0~ step - 1] to let all slot have its chance to be scanned. -+ */ -+ unsigned long offset_init; -+ unsigned long step; /* dynamic step for current_offset */ -+ unsigned int flags; -+ unsigned long pages_to_scan; -+ //unsigned long fully_scanned_slots; -+ /* -+ * a little bit tricky - if cpu_time_ratio > 0, then the value is the -+ * the cpu time ratio it can spend in rung_i for every scan -+ * period. if < 0, then it is the cpu time ratio relative to the -+ * max cpu percentage user specified. Both in unit of -+ * 1/TIME_RATIO_SCALE -+ */ -+ int cpu_ratio; -+ -+ /* -+ * How long it will take for all slots in this rung to be fully -+ * scanned? If it's zero, we don't care about the cover time: -+ * it's fully scanned. -+ */ -+ unsigned int cover_msecs; -+ //unsigned long vma_num; -+ //unsigned long pages; /* Sum of all slot's pages in rung */ -+}; -+ -+/** -+ * node of either the stable or unstale rbtree -+ * -+ */ -+struct tree_node { -+ struct rb_node node; /* link in the main (un)stable rbtree */ -+ struct rb_root sub_root; /* rb_root for sublevel collision rbtree */ -+ u32 hash; -+ unsigned long count; /* TODO: merged with sub_root */ -+ struct list_head all_list; /* all tree nodes in stable/unstable tree */ -+}; -+ -+/** -+ * struct stable_node - node of the stable rbtree -+ * @node: rb node of this ksm page in the stable tree -+ * @hlist: hlist head of rmap_items using this ksm page -+ * @kpfn: page frame number of this ksm page -+ */ -+struct stable_node { -+ struct rb_node node; /* link in sub-rbtree */ -+ struct tree_node *tree_node; /* it's tree node root in stable tree, NULL if it's in hell list */ -+ struct hlist_head hlist; -+ unsigned long kpfn; -+ u32 hash_max; /* if ==0 then it's not been calculated yet */ -+ struct list_head all_list; /* in a list for all stable nodes */ -+}; -+ -+/** -+ * struct node_vma - group rmap_items linked in a same stable -+ * node together. -+ */ -+struct node_vma { -+ union { -+ struct vma_slot *slot; -+ unsigned long key; /* slot is used as key sorted on hlist */ -+ }; -+ struct hlist_node hlist; -+ struct hlist_head rmap_hlist; -+ struct stable_node *head; -+}; -+ -+/** -+ * struct rmap_item - reverse mapping item for virtual addresses -+ * @rmap_list: next rmap_item in mm_slot's singly-linked rmap_list -+ * @anon_vma: pointer to anon_vma for this mm,address, when in stable tree -+ * @mm: the memory structure this rmap_item is pointing into -+ * @address: the virtual address this rmap_item tracks (+ flags in low bits) -+ * @node: rb node of this rmap_item in the unstable tree -+ * @head: pointer to stable_node heading this list in the stable tree -+ * @hlist: link into hlist of rmap_items hanging off that stable_node -+ */ -+struct rmap_item { -+ struct vma_slot *slot; -+ struct page *page; -+ unsigned long address; /* + low bits used for flags below */ -+ unsigned long hash_round; -+ unsigned long entry_index; -+ union { -+ struct {/* when in unstable tree */ -+ struct rb_node node; -+ struct tree_node *tree_node; -+ u32 hash_max; -+ }; -+ struct { /* when in stable tree */ -+ struct node_vma *head; -+ struct hlist_node hlist; -+ struct anon_vma *anon_vma; -+ }; -+ }; -+} __aligned(4); -+ -+struct rmap_list_entry { -+ union { -+ struct rmap_item *item; -+ unsigned long addr; -+ }; -+ /* lowest bit is used for is_addr tag */ -+} __aligned(4); /* 4 aligned to fit in to pages*/ -+ -+ -+/* Basic data structure definition ends */ -+ -+ -+/* -+ * Flags for rmap_item to judge if it's listed in the stable/unstable tree. -+ * The flags use the low bits of rmap_item.address -+ */ -+#define UNSTABLE_FLAG 0x1 -+#define STABLE_FLAG 0x2 -+#define get_rmap_addr(x) ((x)->address & PAGE_MASK) -+ -+/* -+ * rmap_list_entry helpers -+ */ -+#define IS_ADDR_FLAG 1 -+#define is_addr(ptr) ((unsigned long)(ptr) & IS_ADDR_FLAG) -+#define set_is_addr(ptr) ((ptr) |= IS_ADDR_FLAG) -+#define get_clean_addr(ptr) (((ptr) & ~(__typeof__(ptr))IS_ADDR_FLAG)) -+ -+ -+/* -+ * High speed caches for frequently allocated and freed structs -+ */ -+static struct kmem_cache *rmap_item_cache; -+static struct kmem_cache *stable_node_cache; -+static struct kmem_cache *node_vma_cache; -+static struct kmem_cache *vma_slot_cache; -+static struct kmem_cache *tree_node_cache; -+#define UKSM_KMEM_CACHE(__struct, __flags) kmem_cache_create("uksm_"#__struct,\ -+ sizeof(struct __struct), __alignof__(struct __struct),\ -+ (__flags), NULL) -+ -+/* Array of all scan_rung, uksm_scan_ladder[0] having the minimum scan ratio */ -+#define SCAN_LADDER_SIZE 4 -+static struct scan_rung uksm_scan_ladder[SCAN_LADDER_SIZE]; -+ -+/* The evaluation rounds uksmd has finished */ -+static unsigned long long uksm_eval_round = 1; -+ -+/* -+ * we add 1 to this var when we consider we should rebuild the whole -+ * unstable tree. -+ */ -+static unsigned long uksm_hash_round = 1; -+ -+/* -+ * How many times the whole memory is scanned. -+ */ -+static unsigned long long fully_scanned_round = 1; -+ -+/* The total number of virtual pages of all vma slots */ -+static u64 uksm_pages_total; -+ -+/* The number of pages has been scanned since the start up */ -+static u64 uksm_pages_scanned; -+ -+static u64 scanned_virtual_pages; -+ -+/* The number of pages has been scanned since last encode_benefit call */ -+static u64 uksm_pages_scanned_last; -+ -+/* If the scanned number is tooo large, we encode it here */ -+static u64 pages_scanned_stored; -+ -+static unsigned long pages_scanned_base; -+ -+/* The number of nodes in the stable tree */ -+static unsigned long uksm_pages_shared; -+ -+/* The number of page slots additionally sharing those nodes */ -+static unsigned long uksm_pages_sharing; -+ -+/* The number of nodes in the unstable tree */ -+static unsigned long uksm_pages_unshared; -+ -+/* -+ * Milliseconds ksmd should sleep between scans, -+ * >= 100ms to be consistent with -+ * scan_time_to_sleep_msec() -+ */ -+static unsigned int uksm_sleep_jiffies; -+ -+/* The real value for the uksmd next sleep */ -+static unsigned int uksm_sleep_real; -+ -+/* Saved value for user input uksm_sleep_jiffies when it's enlarged */ -+static unsigned int uksm_sleep_saved; -+ -+/* Max percentage of cpu utilization ksmd can take to scan in one batch */ -+static unsigned int uksm_max_cpu_percentage; -+ -+static int uksm_cpu_governor; -+ -+static char *uksm_cpu_governor_str[4] = { "full", "medium", "low", "quiet" }; -+ -+struct uksm_cpu_preset_s { -+ int cpu_ratio[SCAN_LADDER_SIZE]; -+ unsigned int cover_msecs[SCAN_LADDER_SIZE]; -+ unsigned int max_cpu; /* percentage */ -+}; -+ -+struct uksm_cpu_preset_s uksm_cpu_preset[4] = { -+ { {20, 40, -2500, -10000}, {1000, 500, 200, 50}, 95}, -+ { {20, 30, -2500, -10000}, {1000, 500, 400, 100}, 50}, -+ { {10, 20, -5000, -10000}, {1500, 1000, 1000, 250}, 20}, -+ { {10, 20, 40, 75}, {2000, 1000, 1000, 1000}, 1}, -+}; -+ -+/* The default value for uksm_ema_page_time if it's not initialized */ -+#define UKSM_PAGE_TIME_DEFAULT 500 -+ -+/*cost to scan one page by expotional moving average in nsecs */ -+static unsigned long uksm_ema_page_time = UKSM_PAGE_TIME_DEFAULT; -+ -+/* The expotional moving average alpha weight, in percentage. */ -+#define EMA_ALPHA 20 -+ -+/* -+ * The threshold used to filter out thrashing areas, -+ * If it == 0, filtering is disabled, otherwise it's the percentage up-bound -+ * of the thrashing ratio of all areas. Any area with a bigger thrashing ratio -+ * will be considered as having a zero duplication ratio. -+ */ -+static unsigned int uksm_thrash_threshold = 50; -+ -+/* How much dedup ratio is considered to be abundant*/ -+static unsigned int uksm_abundant_threshold = 10; -+ -+/* All slots having merged pages in this eval round. */ -+struct list_head vma_slot_dedup = LIST_HEAD_INIT(vma_slot_dedup); -+ -+/* How many times the ksmd has slept since startup */ -+static unsigned long long uksm_sleep_times; -+ -+#define UKSM_RUN_STOP 0 -+#define UKSM_RUN_MERGE 1 -+static unsigned int uksm_run = 1; -+ -+static DECLARE_WAIT_QUEUE_HEAD(uksm_thread_wait); -+static DEFINE_MUTEX(uksm_thread_mutex); -+ -+/* -+ * List vma_slot_new is for newly created vma_slot waiting to be added by -+ * ksmd. If one cannot be added(e.g. due to it's too small), it's moved to -+ * vma_slot_noadd. vma_slot_del is the list for vma_slot whose corresponding -+ * VMA has been removed/freed. -+ */ -+struct list_head vma_slot_new = LIST_HEAD_INIT(vma_slot_new); -+struct list_head vma_slot_noadd = LIST_HEAD_INIT(vma_slot_noadd); -+struct list_head vma_slot_del = LIST_HEAD_INIT(vma_slot_del); -+static DEFINE_SPINLOCK(vma_slot_list_lock); -+ -+/* The unstable tree heads */ -+static struct rb_root root_unstable_tree = RB_ROOT; -+ -+/* -+ * All tree_nodes are in a list to be freed at once when unstable tree is -+ * freed after each scan round. -+ */ -+static struct list_head unstable_tree_node_list = -+ LIST_HEAD_INIT(unstable_tree_node_list); -+ -+/* List contains all stable nodes */ -+static struct list_head stable_node_list = LIST_HEAD_INIT(stable_node_list); -+ -+/* -+ * When the hash strength is changed, the stable tree must be delta_hashed and -+ * re-structured. We use two set of below structs to speed up the -+ * re-structuring of stable tree. -+ */ -+static struct list_head -+stable_tree_node_list[2] = {LIST_HEAD_INIT(stable_tree_node_list[0]), -+ LIST_HEAD_INIT(stable_tree_node_list[1])}; -+ -+static struct list_head *stable_tree_node_listp = &stable_tree_node_list[0]; -+static struct rb_root root_stable_tree[2] = {RB_ROOT, RB_ROOT}; -+static struct rb_root *root_stable_treep = &root_stable_tree[0]; -+static unsigned long stable_tree_index; -+ -+/* The hash strength needed to hash a full page */ -+#define HASH_STRENGTH_FULL (PAGE_SIZE / sizeof(u32)) -+ -+/* The hash strength needed for loop-back hashing */ -+#define HASH_STRENGTH_MAX (HASH_STRENGTH_FULL + 10) -+ -+/* The random offsets in a page */ -+static u32 *random_nums; -+ -+/* The hash strength */ -+static unsigned long hash_strength = HASH_STRENGTH_FULL >> 4; -+ -+/* The delta value each time the hash strength increases or decreases */ -+static unsigned long hash_strength_delta; -+#define HASH_STRENGTH_DELTA_MAX 5 -+ -+/* The time we have saved due to random_sample_hash */ -+static u64 rshash_pos; -+ -+/* The time we have wasted due to hash collision */ -+static u64 rshash_neg; -+ -+struct uksm_benefit { -+ u64 pos; -+ u64 neg; -+ u64 scanned; -+ unsigned long base; -+} benefit; -+ -+/* -+ * The relative cost of memcmp, compared to 1 time unit of random sample -+ * hash, this value is tested when ksm module is initialized -+ */ -+static unsigned long memcmp_cost; -+ -+static unsigned long rshash_neg_cont_zero; -+static unsigned long rshash_cont_obscure; -+ -+/* The possible states of hash strength adjustment heuristic */ -+enum rshash_states { -+ RSHASH_STILL, -+ RSHASH_TRYUP, -+ RSHASH_TRYDOWN, -+ RSHASH_NEW, -+ RSHASH_PRE_STILL, -+}; -+ -+/* The possible direction we are about to adjust hash strength */ -+enum rshash_direct { -+ GO_UP, -+ GO_DOWN, -+ OBSCURE, -+ STILL, -+}; -+ -+/* random sampling hash state machine */ -+static struct { -+ enum rshash_states state; -+ enum rshash_direct pre_direct; -+ u8 below_count; -+ /* Keep a lookup window of size 5, iff above_count/below_count > 3 -+ * in this window we stop trying. -+ */ -+ u8 lookup_window_index; -+ u64 stable_benefit; -+ unsigned long turn_point_down; -+ unsigned long turn_benefit_down; -+ unsigned long turn_point_up; -+ unsigned long turn_benefit_up; -+ unsigned long stable_point; -+} rshash_state; -+ -+/*zero page hash table, hash_strength [0 ~ HASH_STRENGTH_MAX]*/ -+static u32 *zero_hash_table; -+ -+static inline struct node_vma *alloc_node_vma(void) -+{ -+ struct node_vma *node_vma; -+ -+ node_vma = kmem_cache_zalloc(node_vma_cache, GFP_KERNEL | -+ __GFP_NORETRY | __GFP_NOWARN); -+ if (node_vma) { -+ INIT_HLIST_HEAD(&node_vma->rmap_hlist); -+ INIT_HLIST_NODE(&node_vma->hlist); -+ } -+ return node_vma; -+} -+ -+static inline void free_node_vma(struct node_vma *node_vma) -+{ -+ kmem_cache_free(node_vma_cache, node_vma); -+} -+ -+ -+static inline struct vma_slot *alloc_vma_slot(void) -+{ -+ struct vma_slot *slot; -+ -+ /* -+ * In case ksm is not initialized by now. -+ * Oops, we need to consider the call site of uksm_init() in the future. -+ */ -+ if (!vma_slot_cache) -+ return NULL; -+ -+ slot = kmem_cache_zalloc(vma_slot_cache, GFP_KERNEL | -+ __GFP_NORETRY | __GFP_NOWARN); -+ if (slot) { -+ INIT_LIST_HEAD(&slot->slot_list); -+ INIT_LIST_HEAD(&slot->dedup_list); -+ slot->flags |= UKSM_SLOT_NEED_RERAND; -+ } -+ return slot; -+} -+ -+static inline void free_vma_slot(struct vma_slot *vma_slot) -+{ -+ kmem_cache_free(vma_slot_cache, vma_slot); -+} -+ -+ -+ -+static inline struct rmap_item *alloc_rmap_item(void) -+{ -+ struct rmap_item *rmap_item; -+ -+ rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL | -+ __GFP_NORETRY | __GFP_NOWARN); -+ if (rmap_item) { -+ /* bug on lowest bit is not clear for flag use */ -+ BUG_ON(is_addr(rmap_item)); -+ } -+ return rmap_item; -+} -+ -+static inline void free_rmap_item(struct rmap_item *rmap_item) -+{ -+ rmap_item->slot = NULL; /* debug safety */ -+ kmem_cache_free(rmap_item_cache, rmap_item); -+} -+ -+static inline struct stable_node *alloc_stable_node(void) -+{ -+ struct stable_node *node; -+ -+ node = kmem_cache_alloc(stable_node_cache, GFP_KERNEL | -+ __GFP_NORETRY | __GFP_NOWARN); -+ if (!node) -+ return NULL; -+ -+ INIT_HLIST_HEAD(&node->hlist); -+ list_add(&node->all_list, &stable_node_list); -+ return node; -+} -+ -+static inline void free_stable_node(struct stable_node *stable_node) -+{ -+ list_del(&stable_node->all_list); -+ kmem_cache_free(stable_node_cache, stable_node); -+} -+ -+static inline struct tree_node *alloc_tree_node(struct list_head *list) -+{ -+ struct tree_node *node; -+ -+ node = kmem_cache_zalloc(tree_node_cache, GFP_KERNEL | -+ __GFP_NORETRY | __GFP_NOWARN); -+ if (!node) -+ return NULL; -+ -+ list_add(&node->all_list, list); -+ return node; -+} -+ -+static inline void free_tree_node(struct tree_node *node) -+{ -+ list_del(&node->all_list); -+ kmem_cache_free(tree_node_cache, node); -+} -+ -+static void uksm_drop_anon_vma(struct rmap_item *rmap_item) -+{ -+ struct anon_vma *anon_vma = rmap_item->anon_vma; -+ -+ put_anon_vma(anon_vma); -+} -+ -+ -+/** -+ * Remove a stable node from stable_tree, may unlink from its tree_node and -+ * may remove its parent tree_node if no other stable node is pending. -+ * -+ * @stable_node The node need to be removed -+ * @unlink_rb Will this node be unlinked from the rbtree? -+ * @remove_tree_ node Will its tree_node be removed if empty? -+ */ -+static void remove_node_from_stable_tree(struct stable_node *stable_node, -+ int unlink_rb, int remove_tree_node) -+{ -+ struct node_vma *node_vma; -+ struct rmap_item *rmap_item; -+ struct hlist_node *n; -+ -+ if (!hlist_empty(&stable_node->hlist)) { -+ hlist_for_each_entry_safe(node_vma, n, -+ &stable_node->hlist, hlist) { -+ hlist_for_each_entry(rmap_item, &node_vma->rmap_hlist, hlist) { -+ uksm_pages_sharing--; -+ -+ uksm_drop_anon_vma(rmap_item); -+ rmap_item->address &= PAGE_MASK; -+ } -+ free_node_vma(node_vma); -+ cond_resched(); -+ } -+ -+ /* the last one is counted as shared */ -+ uksm_pages_shared--; -+ uksm_pages_sharing++; -+ } -+ -+ if (stable_node->tree_node && unlink_rb) { -+ rb_erase(&stable_node->node, -+ &stable_node->tree_node->sub_root); -+ -+ if (RB_EMPTY_ROOT(&stable_node->tree_node->sub_root) && -+ remove_tree_node) { -+ rb_erase(&stable_node->tree_node->node, -+ root_stable_treep); -+ free_tree_node(stable_node->tree_node); -+ } else { -+ stable_node->tree_node->count--; -+ } -+ } -+ -+ free_stable_node(stable_node); -+} -+ -+ -+/* -+ * get_uksm_page: checks if the page indicated by the stable node -+ * is still its ksm page, despite having held no reference to it. -+ * In which case we can trust the content of the page, and it -+ * returns the gotten page; but if the page has now been zapped, -+ * remove the stale node from the stable tree and return NULL. -+ * -+ * You would expect the stable_node to hold a reference to the ksm page. -+ * But if it increments the page's count, swapping out has to wait for -+ * ksmd to come around again before it can free the page, which may take -+ * seconds or even minutes: much too unresponsive. So instead we use a -+ * "keyhole reference": access to the ksm page from the stable node peeps -+ * out through its keyhole to see if that page still holds the right key, -+ * pointing back to this stable node. This relies on freeing a PageAnon -+ * page to reset its page->mapping to NULL, and relies on no other use of -+ * a page to put something that might look like our key in page->mapping. -+ * -+ * include/linux/pagemap.h page_cache_get_speculative() is a good reference, -+ * but this is different - made simpler by uksm_thread_mutex being held, but -+ * interesting for assuming that no other use of the struct page could ever -+ * put our expected_mapping into page->mapping (or a field of the union which -+ * coincides with page->mapping). The RCU calls are not for KSM at all, but -+ * to keep the page_count protocol described with page_cache_get_speculative. -+ * -+ * Note: it is possible that get_uksm_page() will return NULL one moment, -+ * then page the next, if the page is in between page_freeze_refs() and -+ * page_unfreeze_refs(): this shouldn't be a problem anywhere, the page -+ * is on its way to being freed; but it is an anomaly to bear in mind. -+ * -+ * @unlink_rb: if the removal of this node will firstly unlink from -+ * its rbtree. stable_node_reinsert will prevent this when restructuring the -+ * node from its old tree. -+ * -+ * @remove_tree_node: if this is the last one of its tree_node, will the -+ * tree_node be freed ? If we are inserting stable node, this tree_node may -+ * be reused, so don't free it. -+ */ -+static struct page *get_uksm_page(struct stable_node *stable_node, -+ int unlink_rb, int remove_tree_node) -+{ -+ struct page *page; -+ void *expected_mapping; -+ unsigned long kpfn; -+ -+ expected_mapping = (void *)((unsigned long)stable_node | -+ PAGE_MAPPING_KSM); -+again: -+ kpfn = READ_ONCE(stable_node->kpfn); -+ page = pfn_to_page(kpfn); -+ -+ /* -+ * page is computed from kpfn, so on most architectures reading -+ * page->mapping is naturally ordered after reading node->kpfn, -+ * but on Alpha we need to be more careful. -+ */ -+ smp_read_barrier_depends(); -+ -+ if (READ_ONCE(page->mapping) != expected_mapping) -+ goto stale; -+ -+ /* -+ * We cannot do anything with the page while its refcount is 0. -+ * Usually 0 means free, or tail of a higher-order page: in which -+ * case this node is no longer referenced, and should be freed; -+ * however, it might mean that the page is under page_freeze_refs(). -+ * The __remove_mapping() case is easy, again the node is now stale; -+ * but if page is swapcache in migrate_page_move_mapping(), it might -+ * still be our page, in which case it's essential to keep the node. -+ */ -+ while (!get_page_unless_zero(page)) { -+ /* -+ * Another check for page->mapping != expected_mapping would -+ * work here too. We have chosen the !PageSwapCache test to -+ * optimize the common case, when the page is or is about to -+ * be freed: PageSwapCache is cleared (under spin_lock_irq) -+ * in the freeze_refs section of __remove_mapping(); but Anon -+ * page->mapping reset to NULL later, in free_pages_prepare(). -+ */ -+ if (!PageSwapCache(page)) -+ goto stale; -+ cpu_relax(); -+ } -+ -+ if (READ_ONCE(page->mapping) != expected_mapping) { -+ put_page(page); -+ goto stale; -+ } -+ -+ lock_page(page); -+ if (READ_ONCE(page->mapping) != expected_mapping) { -+ unlock_page(page); -+ put_page(page); -+ goto stale; -+ } -+ unlock_page(page); -+ return page; -+stale: -+ /* -+ * We come here from above when page->mapping or !PageSwapCache -+ * suggests that the node is stale; but it might be under migration. -+ * We need smp_rmb(), matching the smp_wmb() in ksm_migrate_page(), -+ * before checking whether node->kpfn has been changed. -+ */ -+ smp_rmb(); -+ if (stable_node->kpfn != kpfn) -+ goto again; -+ -+ remove_node_from_stable_tree(stable_node, unlink_rb, remove_tree_node); -+ -+ return NULL; -+} -+ -+/* -+ * Removing rmap_item from stable or unstable tree. -+ * This function will clean the information from the stable/unstable tree. -+ */ -+static inline void remove_rmap_item_from_tree(struct rmap_item *rmap_item) -+{ -+ if (rmap_item->address & STABLE_FLAG) { -+ struct stable_node *stable_node; -+ struct node_vma *node_vma; -+ struct page *page; -+ -+ node_vma = rmap_item->head; -+ stable_node = node_vma->head; -+ page = get_uksm_page(stable_node, 1, 1); -+ if (!page) -+ goto out; -+ -+ /* -+ * page lock is needed because it's racing with -+ * try_to_unmap_ksm(), etc. -+ */ -+ lock_page(page); -+ hlist_del(&rmap_item->hlist); -+ -+ if (hlist_empty(&node_vma->rmap_hlist)) { -+ hlist_del(&node_vma->hlist); -+ free_node_vma(node_vma); -+ } -+ unlock_page(page); -+ -+ put_page(page); -+ if (hlist_empty(&stable_node->hlist)) { -+ /* do NOT call remove_node_from_stable_tree() here, -+ * it's possible for a forked rmap_item not in -+ * stable tree while the in-tree rmap_items were -+ * deleted. -+ */ -+ uksm_pages_shared--; -+ } else -+ uksm_pages_sharing--; -+ -+ -+ uksm_drop_anon_vma(rmap_item); -+ } else if (rmap_item->address & UNSTABLE_FLAG) { -+ if (rmap_item->hash_round == uksm_hash_round) { -+ -+ rb_erase(&rmap_item->node, -+ &rmap_item->tree_node->sub_root); -+ if (RB_EMPTY_ROOT(&rmap_item->tree_node->sub_root)) { -+ rb_erase(&rmap_item->tree_node->node, -+ &root_unstable_tree); -+ -+ free_tree_node(rmap_item->tree_node); -+ } else -+ rmap_item->tree_node->count--; -+ } -+ uksm_pages_unshared--; -+ } -+ -+ rmap_item->address &= PAGE_MASK; -+ rmap_item->hash_max = 0; -+ -+out: -+ cond_resched(); /* we're called from many long loops */ -+} -+ -+static inline int slot_in_uksm(struct vma_slot *slot) -+{ -+ return list_empty(&slot->slot_list); -+} -+ -+/* -+ * Test if the mm is exiting -+ */ -+static inline bool uksm_test_exit(struct mm_struct *mm) -+{ -+ return atomic_read(&mm->mm_users) == 0; -+} -+ -+static inline unsigned long vma_pool_size(struct vma_slot *slot) -+{ -+ return round_up(sizeof(struct rmap_list_entry) * slot->pages, -+ PAGE_SIZE) >> PAGE_SHIFT; -+} -+ -+#define CAN_OVERFLOW_U64(x, delta) (U64_MAX - (x) < (delta)) -+ -+/* must be done with sem locked */ -+static int slot_pool_alloc(struct vma_slot *slot) -+{ -+ unsigned long pool_size; -+ -+ if (slot->rmap_list_pool) -+ return 0; -+ -+ pool_size = vma_pool_size(slot); -+ slot->rmap_list_pool = kcalloc(pool_size, sizeof(struct page *), -+ GFP_KERNEL); -+ if (!slot->rmap_list_pool) -+ return -ENOMEM; -+ -+ slot->pool_counts = kcalloc(pool_size, sizeof(unsigned int), -+ GFP_KERNEL); -+ if (!slot->pool_counts) { -+ kfree(slot->rmap_list_pool); -+ return -ENOMEM; -+ } -+ -+ slot->pool_size = pool_size; -+ BUG_ON(CAN_OVERFLOW_U64(uksm_pages_total, slot->pages)); -+ slot->flags |= UKSM_SLOT_IN_UKSM; -+ uksm_pages_total += slot->pages; -+ -+ return 0; -+} -+ -+/* -+ * Called after vma is unlinked from its mm -+ */ -+void uksm_remove_vma(struct vm_area_struct *vma) -+{ -+ struct vma_slot *slot; -+ -+ if (!vma->uksm_vma_slot) -+ return; -+ -+ spin_lock(&vma_slot_list_lock); -+ slot = vma->uksm_vma_slot; -+ if (!slot) -+ goto out; -+ -+ if (slot_in_uksm(slot)) { -+ /** -+ * This slot has been added by ksmd, so move to the del list -+ * waiting ksmd to free it. -+ */ -+ list_add_tail(&slot->slot_list, &vma_slot_del); -+ } else { -+ /** -+ * It's still on new list. It's ok to free slot directly. -+ */ -+ list_del(&slot->slot_list); -+ free_vma_slot(slot); -+ } -+out: -+ vma->uksm_vma_slot = NULL; -+ spin_unlock(&vma_slot_list_lock); -+} -+ -+/** -+ * Need to do two things: -+ * 1. check if slot was moved to del list -+ * 2. make sure the mmap_sem is manipulated under valid vma. -+ * -+ * My concern here is that in some cases, this may make -+ * vma_slot_list_lock() waiters to serialized further by some -+ * sem->wait_lock, can this really be expensive? -+ * -+ * -+ * @return -+ * 0: if successfully locked mmap_sem -+ * -ENOENT: this slot was moved to del list -+ * -EBUSY: vma lock failed -+ */ -+static int try_down_read_slot_mmap_sem(struct vma_slot *slot) -+{ -+ struct vm_area_struct *vma; -+ struct mm_struct *mm; -+ struct rw_semaphore *sem; -+ -+ spin_lock(&vma_slot_list_lock); -+ -+ /* the slot_list was removed and inited from new list, when it enters -+ * uksm_list. If now it's not empty, then it must be moved to del list -+ */ -+ if (!slot_in_uksm(slot)) { -+ spin_unlock(&vma_slot_list_lock); -+ return -ENOENT; -+ } -+ -+ BUG_ON(slot->pages != vma_pages(slot->vma)); -+ /* Ok, vma still valid */ -+ vma = slot->vma; -+ mm = vma->vm_mm; -+ sem = &mm->mmap_lock; -+ -+ if (uksm_test_exit(mm)) { -+ spin_unlock(&vma_slot_list_lock); -+ return -ENOENT; -+ } -+ -+ if (down_read_trylock(sem)) { -+ spin_unlock(&vma_slot_list_lock); -+ if (slot_pool_alloc(slot)) { -+ uksm_remove_vma(vma); -+ up_read(sem); -+ return -ENOENT; -+ } -+ return 0; -+ } -+ -+ spin_unlock(&vma_slot_list_lock); -+ return -EBUSY; -+} -+ -+static inline unsigned long -+vma_page_address(struct page *page, struct vm_area_struct *vma) -+{ -+ pgoff_t pgoff = page->index; -+ unsigned long address; -+ -+ address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); -+ if (unlikely(address < vma->vm_start || address >= vma->vm_end)) { -+ /* page should be within @vma mapping range */ -+ return -EFAULT; -+ } -+ return address; -+} -+ -+ -+/* return 0 on success with the item's mmap_sem locked */ -+static inline int get_mergeable_page_lock_mmap(struct rmap_item *item) -+{ -+ struct mm_struct *mm; -+ struct vma_slot *slot = item->slot; -+ int err = -EINVAL; -+ -+ struct page *page; -+ -+ /* -+ * try_down_read_slot_mmap_sem() returns non-zero if the slot -+ * has been removed by uksm_remove_vma(). -+ */ -+ if (try_down_read_slot_mmap_sem(slot)) -+ return -EBUSY; -+ -+ mm = slot->vma->vm_mm; -+ -+ if (uksm_test_exit(mm)) -+ goto failout_up; -+ -+ page = item->page; -+ rcu_read_lock(); -+ if (!get_page_unless_zero(page)) { -+ rcu_read_unlock(); -+ goto failout_up; -+ } -+ -+ /* No need to consider huge page here. */ -+ if (item->slot->vma->anon_vma != page_anon_vma(page) || -+ vma_page_address(page, item->slot->vma) != get_rmap_addr(item)) { -+ /* -+ * TODO: -+ * should we release this item becase of its stale page -+ * mapping? -+ */ -+ put_page(page); -+ rcu_read_unlock(); -+ goto failout_up; -+ } -+ rcu_read_unlock(); -+ return 0; -+ -+failout_up: -+ mmap_read_unlock(mm); -+ return err; -+} -+ -+/* -+ * What kind of VMA is considered ? -+ */ -+static inline int vma_can_enter(struct vm_area_struct *vma) -+{ -+ return uksm_flags_can_scan(vma->vm_flags); -+} -+ -+/* -+ * Called whenever a fresh new vma is created A new vma_slot. -+ * is created and inserted into a global list Must be called. -+ * after vma is inserted to its mm. -+ */ -+void uksm_vma_add_new(struct vm_area_struct *vma) -+{ -+ struct vma_slot *slot; -+ -+ if (!vma_can_enter(vma)) { -+ vma->uksm_vma_slot = NULL; -+ return; -+ } -+ -+ slot = alloc_vma_slot(); -+ if (!slot) { -+ vma->uksm_vma_slot = NULL; -+ return; -+ } -+ -+ vma->uksm_vma_slot = slot; -+ vma->vm_flags |= VM_MERGEABLE; -+ slot->vma = vma; -+ slot->mm = vma->vm_mm; -+ slot->ctime_j = jiffies; -+ slot->pages = vma_pages(vma); -+ spin_lock(&vma_slot_list_lock); -+ list_add_tail(&slot->slot_list, &vma_slot_new); -+ spin_unlock(&vma_slot_list_lock); -+} -+ -+/* 32/3 < they < 32/2 */ -+#define shiftl 8 -+#define shiftr 12 -+ -+#define HASH_FROM_TO(from, to) \ -+for (index = from; index < to; index++) { \ -+ pos = random_nums[index]; \ -+ hash += key[pos]; \ -+ hash += (hash << shiftl); \ -+ hash ^= (hash >> shiftr); \ -+} -+ -+ -+#define HASH_FROM_DOWN_TO(from, to) \ -+for (index = from - 1; index >= to; index--) { \ -+ hash ^= (hash >> shiftr); \ -+ hash ^= (hash >> (shiftr*2)); \ -+ hash -= (hash << shiftl); \ -+ hash += (hash << (shiftl*2)); \ -+ pos = random_nums[index]; \ -+ hash -= key[pos]; \ -+} -+ -+/* -+ * The main random sample hash function. -+ */ -+static u32 random_sample_hash(void *addr, u32 hash_strength) -+{ -+ u32 hash = 0xdeadbeef; -+ int index, pos, loop = hash_strength; -+ u32 *key = (u32 *)addr; -+ -+ if (loop > HASH_STRENGTH_FULL) -+ loop = HASH_STRENGTH_FULL; -+ -+ HASH_FROM_TO(0, loop); -+ -+ if (hash_strength > HASH_STRENGTH_FULL) { -+ loop = hash_strength - HASH_STRENGTH_FULL; -+ HASH_FROM_TO(0, loop); -+ } -+ -+ return hash; -+} -+ -+ -+/** -+ * It's used when hash strength is adjusted -+ * -+ * @addr The page's virtual address -+ * @from The original hash strength -+ * @to The hash strength changed to -+ * @hash The hash value generated with "from" hash value -+ * -+ * return the hash value -+ */ -+static u32 delta_hash(void *addr, int from, int to, u32 hash) -+{ -+ u32 *key = (u32 *)addr; -+ int index, pos; /* make sure they are int type */ -+ -+ if (to > from) { -+ if (from >= HASH_STRENGTH_FULL) { -+ from -= HASH_STRENGTH_FULL; -+ to -= HASH_STRENGTH_FULL; -+ HASH_FROM_TO(from, to); -+ } else if (to <= HASH_STRENGTH_FULL) { -+ HASH_FROM_TO(from, to); -+ } else { -+ HASH_FROM_TO(from, HASH_STRENGTH_FULL); -+ HASH_FROM_TO(0, to - HASH_STRENGTH_FULL); -+ } -+ } else { -+ if (from <= HASH_STRENGTH_FULL) { -+ HASH_FROM_DOWN_TO(from, to); -+ } else if (to >= HASH_STRENGTH_FULL) { -+ from -= HASH_STRENGTH_FULL; -+ to -= HASH_STRENGTH_FULL; -+ HASH_FROM_DOWN_TO(from, to); -+ } else { -+ HASH_FROM_DOWN_TO(from - HASH_STRENGTH_FULL, 0); -+ HASH_FROM_DOWN_TO(HASH_STRENGTH_FULL, to); -+ } -+ } -+ -+ return hash; -+} -+ -+/** -+ * -+ * Called when: rshash_pos or rshash_neg is about to overflow or a scan round -+ * has finished. -+ * -+ * return 0 if no page has been scanned since last call, 1 otherwise. -+ */ -+static inline int encode_benefit(void) -+{ -+ u64 scanned_delta, pos_delta, neg_delta; -+ unsigned long base = benefit.base; -+ -+ scanned_delta = uksm_pages_scanned - uksm_pages_scanned_last; -+ -+ if (!scanned_delta) -+ return 0; -+ -+ scanned_delta >>= base; -+ pos_delta = rshash_pos >> base; -+ neg_delta = rshash_neg >> base; -+ -+ if (CAN_OVERFLOW_U64(benefit.pos, pos_delta) || -+ CAN_OVERFLOW_U64(benefit.neg, neg_delta) || -+ CAN_OVERFLOW_U64(benefit.scanned, scanned_delta)) { -+ benefit.scanned >>= 1; -+ benefit.neg >>= 1; -+ benefit.pos >>= 1; -+ benefit.base++; -+ scanned_delta >>= 1; -+ pos_delta >>= 1; -+ neg_delta >>= 1; -+ } -+ -+ benefit.pos += pos_delta; -+ benefit.neg += neg_delta; -+ benefit.scanned += scanned_delta; -+ -+ BUG_ON(!benefit.scanned); -+ -+ rshash_pos = rshash_neg = 0; -+ uksm_pages_scanned_last = uksm_pages_scanned; -+ -+ return 1; -+} -+ -+static inline void reset_benefit(void) -+{ -+ benefit.pos = 0; -+ benefit.neg = 0; -+ benefit.base = 0; -+ benefit.scanned = 0; -+} -+ -+static inline void inc_rshash_pos(unsigned long delta) -+{ -+ if (CAN_OVERFLOW_U64(rshash_pos, delta)) -+ encode_benefit(); -+ -+ rshash_pos += delta; -+} -+ -+static inline void inc_rshash_neg(unsigned long delta) -+{ -+ if (CAN_OVERFLOW_U64(rshash_neg, delta)) -+ encode_benefit(); -+ -+ rshash_neg += delta; -+} -+ -+ -+static inline u32 page_hash(struct page *page, unsigned long hash_strength, -+ int cost_accounting) -+{ -+ u32 val; -+ unsigned long delta; -+ -+ void *addr = kmap_atomic(page); -+ -+ val = random_sample_hash(addr, hash_strength); -+ kunmap_atomic(addr); -+ -+ if (cost_accounting) { -+ if (hash_strength < HASH_STRENGTH_FULL) -+ delta = HASH_STRENGTH_FULL - hash_strength; -+ else -+ delta = 0; -+ -+ inc_rshash_pos(delta); -+ } -+ -+ return val; -+} -+ -+static int memcmp_pages_with_cost(struct page *page1, struct page *page2, -+ int cost_accounting) -+{ -+ char *addr1, *addr2; -+ int ret; -+ -+ addr1 = kmap_atomic(page1); -+ addr2 = kmap_atomic(page2); -+ ret = memcmp(addr1, addr2, PAGE_SIZE); -+ kunmap_atomic(addr2); -+ kunmap_atomic(addr1); -+ -+ if (cost_accounting) -+ inc_rshash_neg(memcmp_cost); -+ -+ return ret; -+} -+ -+static inline int pages_identical_with_cost(struct page *page1, struct page *page2) -+{ -+ return !memcmp_pages_with_cost(page1, page2, 0); -+} -+ -+static inline int is_page_full_zero(struct page *page) -+{ -+ char *addr; -+ int ret; -+ -+ addr = kmap_atomic(page); -+ ret = is_full_zero(addr, PAGE_SIZE); -+ kunmap_atomic(addr); -+ -+ return ret; -+} -+ -+static int write_protect_page(struct vm_area_struct *vma, struct page *page, -+ pte_t *orig_pte, pte_t *old_pte) -+{ -+ struct mm_struct *mm = vma->vm_mm; -+ struct page_vma_mapped_walk pvmw = { -+ .page = page, -+ .vma = vma, -+ }; -+ struct mmu_notifier_range range; -+ int swapped; -+ int err = -EFAULT; -+ -+ pvmw.address = page_address_in_vma(page, vma); -+ if (pvmw.address == -EFAULT) -+ goto out; -+ -+ BUG_ON(PageTransCompound(page)); -+ -+ mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm, pvmw.address, -+ pvmw.address + PAGE_SIZE); -+ mmu_notifier_invalidate_range_start(&range); -+ -+ if (!page_vma_mapped_walk(&pvmw)) -+ goto out_mn; -+ if (WARN_ONCE(!pvmw.pte, "Unexpected PMD mapping?")) -+ goto out_unlock; -+ -+ if (old_pte) -+ *old_pte = *pvmw.pte; -+ -+ if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) || -+ (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte)) || mm_tlb_flush_pending(mm)) { -+ pte_t entry; -+ -+ swapped = PageSwapCache(page); -+ flush_cache_page(vma, pvmw.address, page_to_pfn(page)); -+ /* -+ * Ok this is tricky, when get_user_pages_fast() run it doesn't -+ * take any lock, therefore the check that we are going to make -+ * with the pagecount against the mapcount is racey and -+ * O_DIRECT can happen right after the check. -+ * So we clear the pte and flush the tlb before the check -+ * this assure us that no O_DIRECT can happen after the check -+ * or in the middle of the check. -+ */ -+ entry = ptep_clear_flush_notify(vma, pvmw.address, pvmw.pte); -+ /* -+ * Check that no O_DIRECT or similar I/O is in progress on the -+ * page -+ */ -+ if (page_mapcount(page) + 1 + swapped != page_count(page)) { -+ set_pte_at(mm, pvmw.address, pvmw.pte, entry); -+ goto out_unlock; -+ } -+ if (pte_dirty(entry)) -+ set_page_dirty(page); -+ -+ if (pte_protnone(entry)) -+ entry = pte_mkclean(pte_clear_savedwrite(entry)); -+ else -+ entry = pte_mkclean(pte_wrprotect(entry)); -+ -+ set_pte_at_notify(mm, pvmw.address, pvmw.pte, entry); -+ } -+ *orig_pte = *pvmw.pte; -+ err = 0; -+ -+out_unlock: -+ page_vma_mapped_walk_done(&pvmw); -+out_mn: -+ mmu_notifier_invalidate_range_end(&range); -+out: -+ return err; -+} -+ -+#define MERGE_ERR_PGERR 1 /* the page is invalid cannot continue */ -+#define MERGE_ERR_COLLI 2 /* there is a collision */ -+#define MERGE_ERR_COLLI_MAX 3 /* collision at the max hash strength */ -+#define MERGE_ERR_CHANGED 4 /* the page has changed since last hash */ -+ -+ -+/** -+ * replace_page - replace page in vma by new ksm page -+ * @vma: vma that holds the pte pointing to page -+ * @page: the page we are replacing by kpage -+ * @kpage: the ksm page we replace page by -+ * @orig_pte: the original value of the pte -+ * -+ * Returns 0 on success, MERGE_ERR_PGERR on failure. -+ */ -+static int replace_page(struct vm_area_struct *vma, struct page *page, -+ struct page *kpage, pte_t orig_pte) -+{ -+ struct mm_struct *mm = vma->vm_mm; -+ struct mmu_notifier_range range; -+ pgd_t *pgd; -+ p4d_t *p4d; -+ pud_t *pud; -+ pmd_t *pmd; -+ pte_t *ptep; -+ spinlock_t *ptl; -+ pte_t entry; -+ -+ unsigned long addr; -+ int err = MERGE_ERR_PGERR; -+ -+ addr = page_address_in_vma(page, vma); -+ if (addr == -EFAULT) -+ goto out; -+ -+ pgd = pgd_offset(mm, addr); -+ if (!pgd_present(*pgd)) -+ goto out; -+ -+ p4d = p4d_offset(pgd, addr); -+ pud = pud_offset(p4d, addr); -+ if (!pud_present(*pud)) -+ goto out; -+ -+ pmd = pmd_offset(pud, addr); -+ BUG_ON(pmd_trans_huge(*pmd)); -+ if (!pmd_present(*pmd)) -+ goto out; -+ -+ mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm, addr, -+ addr + PAGE_SIZE); -+ mmu_notifier_invalidate_range_start(&range); -+ -+ ptep = pte_offset_map_lock(mm, pmd, addr, &ptl); -+ if (!pte_same(*ptep, orig_pte)) { -+ pte_unmap_unlock(ptep, ptl); -+ goto out_mn; -+ } -+ -+ flush_cache_page(vma, addr, pte_pfn(*ptep)); -+ ptep_clear_flush_notify(vma, addr, ptep); -+ entry = mk_pte(kpage, vma->vm_page_prot); -+ -+ /* special treatment is needed for zero_page */ -+ if ((page_to_pfn(kpage) == uksm_zero_pfn) || -+ (page_to_pfn(kpage) == zero_pfn)) { -+ entry = pte_mkspecial(entry); -+ dec_mm_counter(mm, MM_ANONPAGES); -+ inc_zone_page_state(page, NR_UKSM_ZERO_PAGES); -+ } else { -+ get_page(kpage); -+ page_add_anon_rmap(kpage, vma, addr, false); -+ } -+ -+ set_pte_at_notify(mm, addr, ptep, entry); -+ -+ page_remove_rmap(page, false); -+ if (!page_mapped(page)) -+ try_to_free_swap(page); -+ put_page(page); -+ -+ pte_unmap_unlock(ptep, ptl); -+ err = 0; -+out_mn: -+ mmu_notifier_invalidate_range_end(&range); -+out: -+ return err; -+} -+ -+ -+/** -+ * Fully hash a page with HASH_STRENGTH_MAX return a non-zero hash value. The -+ * zero hash value at HASH_STRENGTH_MAX is used to indicated that its -+ * hash_max member has not been calculated. -+ * -+ * @page The page needs to be hashed -+ * @hash_old The hash value calculated with current hash strength -+ * -+ * return the new hash value calculated at HASH_STRENGTH_MAX -+ */ -+static inline u32 page_hash_max(struct page *page, u32 hash_old) -+{ -+ u32 hash_max = 0; -+ void *addr; -+ -+ addr = kmap_atomic(page); -+ hash_max = delta_hash(addr, hash_strength, -+ HASH_STRENGTH_MAX, hash_old); -+ -+ kunmap_atomic(addr); -+ -+ if (!hash_max) -+ hash_max = 1; -+ -+ inc_rshash_neg(HASH_STRENGTH_MAX - hash_strength); -+ return hash_max; -+} -+ -+/* -+ * We compare the hash again, to ensure that it is really a hash collision -+ * instead of being caused by page write. -+ */ -+static inline int check_collision(struct rmap_item *rmap_item, -+ u32 hash) -+{ -+ int err; -+ struct page *page = rmap_item->page; -+ -+ /* if this rmap_item has already been hash_maxed, then the collision -+ * must appears in the second-level rbtree search. In this case we check -+ * if its hash_max value has been changed. Otherwise, the collision -+ * happens in the first-level rbtree search, so we check against it's -+ * current hash value. -+ */ -+ if (rmap_item->hash_max) { -+ inc_rshash_neg(memcmp_cost); -+ inc_rshash_neg(HASH_STRENGTH_MAX - hash_strength); -+ -+ if (rmap_item->hash_max == page_hash_max(page, hash)) -+ err = MERGE_ERR_COLLI; -+ else -+ err = MERGE_ERR_CHANGED; -+ } else { -+ inc_rshash_neg(memcmp_cost + hash_strength); -+ -+ if (page_hash(page, hash_strength, 0) == hash) -+ err = MERGE_ERR_COLLI; -+ else -+ err = MERGE_ERR_CHANGED; -+ } -+ -+ return err; -+} -+ -+/** -+ * Try to merge a rmap_item.page with a kpage in stable node. kpage must -+ * already be a ksm page. -+ * -+ * @return 0 if the pages were merged, -EFAULT otherwise. -+ */ -+static int try_to_merge_with_uksm_page(struct rmap_item *rmap_item, -+ struct page *kpage, u32 hash) -+{ -+ struct vm_area_struct *vma = rmap_item->slot->vma; -+ struct mm_struct *mm = vma->vm_mm; -+ pte_t orig_pte = __pte(0); -+ int err = MERGE_ERR_PGERR; -+ struct page *page; -+ -+ if (uksm_test_exit(mm)) -+ goto out; -+ -+ page = rmap_item->page; -+ -+ if (page == kpage) { /* ksm page forked */ -+ err = 0; -+ goto out; -+ } -+ -+ /* -+ * We need the page lock to read a stable PageSwapCache in -+ * write_protect_page(). We use trylock_page() instead of -+ * lock_page() because we don't want to wait here - we -+ * prefer to continue scanning and merging different pages, -+ * then come back to this page when it is unlocked. -+ */ -+ if (!trylock_page(page)) -+ goto out; -+ -+ if (!PageAnon(page) || !PageKsm(kpage)) -+ goto out_unlock; -+ -+ if (PageTransCompound(page)) { -+ err = split_huge_page(page); -+ if (err) -+ goto out_unlock; -+ } -+ -+ /* -+ * If this anonymous page is mapped only here, its pte may need -+ * to be write-protected. If it's mapped elsewhere, all of its -+ * ptes are necessarily already write-protected. But in either -+ * case, we need to lock and check page_count is not raised. -+ */ -+ if (write_protect_page(vma, page, &orig_pte, NULL) == 0) { -+ if (pages_identical_with_cost(page, kpage)) -+ err = replace_page(vma, page, kpage, orig_pte); -+ else -+ err = check_collision(rmap_item, hash); -+ } -+ -+ if ((vma->vm_flags & VM_LOCKED) && kpage && !err) { -+ munlock_vma_page(page); -+ if (!PageMlocked(kpage)) { -+ unlock_page(page); -+ lock_page(kpage); -+ mlock_vma_page(kpage); -+ page = kpage; /* for final unlock */ -+ } -+ } -+ -+out_unlock: -+ unlock_page(page); -+out: -+ return err; -+} -+ -+ -+ -+/** -+ * If two pages fail to merge in try_to_merge_two_pages, then we have a chance -+ * to restore a page mapping that has been changed in try_to_merge_two_pages. -+ * -+ * @return 0 on success. -+ */ -+static int restore_uksm_page_pte(struct vm_area_struct *vma, unsigned long addr, -+ pte_t orig_pte, pte_t wprt_pte) -+{ -+ struct mm_struct *mm = vma->vm_mm; -+ pgd_t *pgd; -+ p4d_t *p4d; -+ pud_t *pud; -+ pmd_t *pmd; -+ pte_t *ptep; -+ spinlock_t *ptl; -+ -+ int err = -EFAULT; -+ -+ pgd = pgd_offset(mm, addr); -+ if (!pgd_present(*pgd)) -+ goto out; -+ -+ p4d = p4d_offset(pgd, addr); -+ pud = pud_offset(p4d, addr); -+ if (!pud_present(*pud)) -+ goto out; -+ -+ pmd = pmd_offset(pud, addr); -+ if (!pmd_present(*pmd)) -+ goto out; -+ -+ ptep = pte_offset_map_lock(mm, pmd, addr, &ptl); -+ if (!pte_same(*ptep, wprt_pte)) { -+ /* already copied, let it be */ -+ pte_unmap_unlock(ptep, ptl); -+ goto out; -+ } -+ -+ /* -+ * Good boy, still here. When we still get the ksm page, it does not -+ * return to the free page pool, there is no way that a pte was changed -+ * to other page and gets back to this page. And remind that ksm page -+ * do not reuse in do_wp_page(). So it's safe to restore the original -+ * pte. -+ */ -+ flush_cache_page(vma, addr, pte_pfn(*ptep)); -+ ptep_clear_flush_notify(vma, addr, ptep); -+ set_pte_at_notify(mm, addr, ptep, orig_pte); -+ -+ pte_unmap_unlock(ptep, ptl); -+ err = 0; -+out: -+ return err; -+} -+ -+/** -+ * try_to_merge_two_pages() - take two identical pages and prepare -+ * them to be merged into one page(rmap_item->page) -+ * -+ * @return 0 if we successfully merged two identical pages into -+ * one ksm page. MERGE_ERR_COLLI if it's only a hash collision -+ * search in rbtree. MERGE_ERR_CHANGED if rmap_item has been -+ * changed since it's hashed. MERGE_ERR_PGERR otherwise. -+ * -+ */ -+static int try_to_merge_two_pages(struct rmap_item *rmap_item, -+ struct rmap_item *tree_rmap_item, -+ u32 hash) -+{ -+ pte_t orig_pte1 = __pte(0), orig_pte2 = __pte(0); -+ pte_t wprt_pte1 = __pte(0), wprt_pte2 = __pte(0); -+ struct vm_area_struct *vma1 = rmap_item->slot->vma; -+ struct vm_area_struct *vma2 = tree_rmap_item->slot->vma; -+ struct page *page = rmap_item->page; -+ struct page *tree_page = tree_rmap_item->page; -+ int err = MERGE_ERR_PGERR; -+ struct address_space *saved_mapping; -+ -+ -+ if (rmap_item->page == tree_rmap_item->page) -+ goto out; -+ -+ if (!trylock_page(page)) -+ goto out; -+ -+ if (!PageAnon(page)) -+ goto out_unlock; -+ -+ if (PageTransCompound(page)) { -+ err = split_huge_page(page); -+ if (err) -+ goto out_unlock; -+ } -+ -+ if (write_protect_page(vma1, page, &wprt_pte1, &orig_pte1) != 0) { -+ unlock_page(page); -+ goto out; -+ } -+ -+ /* -+ * While we hold page lock, upgrade page from -+ * PageAnon+anon_vma to PageKsm+NULL stable_node: -+ * stable_tree_insert() will update stable_node. -+ */ -+ saved_mapping = page->mapping; -+ set_page_stable_node(page, NULL); -+ mark_page_accessed(page); -+ if (!PageDirty(page)) -+ SetPageDirty(page); -+ -+ unlock_page(page); -+ -+ if (!trylock_page(tree_page)) -+ goto restore_out; -+ -+ if (!PageAnon(tree_page)) { -+ unlock_page(tree_page); -+ goto restore_out; -+ } -+ -+ if (PageTransCompound(tree_page)) { -+ err = split_huge_page(tree_page); -+ if (err) { -+ unlock_page(tree_page); -+ goto restore_out; -+ } -+ } -+ -+ if (write_protect_page(vma2, tree_page, &wprt_pte2, &orig_pte2) != 0) { -+ unlock_page(tree_page); -+ goto restore_out; -+ } -+ -+ if (pages_identical_with_cost(page, tree_page)) { -+ err = replace_page(vma2, tree_page, page, wprt_pte2); -+ if (err) { -+ unlock_page(tree_page); -+ goto restore_out; -+ } -+ -+ if ((vma2->vm_flags & VM_LOCKED)) { -+ munlock_vma_page(tree_page); -+ if (!PageMlocked(page)) { -+ unlock_page(tree_page); -+ lock_page(page); -+ mlock_vma_page(page); -+ tree_page = page; /* for final unlock */ -+ } -+ } -+ -+ unlock_page(tree_page); -+ -+ goto out; /* success */ -+ -+ } else { -+ if (tree_rmap_item->hash_max && -+ tree_rmap_item->hash_max == rmap_item->hash_max) { -+ err = MERGE_ERR_COLLI_MAX; -+ } else if (page_hash(page, hash_strength, 0) == -+ page_hash(tree_page, hash_strength, 0)) { -+ inc_rshash_neg(memcmp_cost + hash_strength * 2); -+ err = MERGE_ERR_COLLI; -+ } else { -+ err = MERGE_ERR_CHANGED; -+ } -+ -+ unlock_page(tree_page); -+ } -+ -+restore_out: -+ lock_page(page); -+ if (!restore_uksm_page_pte(vma1, get_rmap_addr(rmap_item), -+ orig_pte1, wprt_pte1)) -+ page->mapping = saved_mapping; -+ -+out_unlock: -+ unlock_page(page); -+out: -+ return err; -+} -+ -+static inline int hash_cmp(u32 new_val, u32 node_val) -+{ -+ if (new_val > node_val) -+ return 1; -+ else if (new_val < node_val) -+ return -1; -+ else -+ return 0; -+} -+ -+static inline u32 rmap_item_hash_max(struct rmap_item *item, u32 hash) -+{ -+ u32 hash_max = item->hash_max; -+ -+ if (!hash_max) { -+ hash_max = page_hash_max(item->page, hash); -+ -+ item->hash_max = hash_max; -+ } -+ -+ return hash_max; -+} -+ -+ -+ -+/** -+ * stable_tree_search() - search the stable tree for a page -+ * -+ * @item: the rmap_item we are comparing with -+ * @hash: the hash value of this item->page already calculated -+ * -+ * @return the page we have found, NULL otherwise. The page returned has -+ * been gotten. -+ */ -+static struct page *stable_tree_search(struct rmap_item *item, u32 hash) -+{ -+ struct rb_node *node = root_stable_treep->rb_node; -+ struct tree_node *tree_node; -+ unsigned long hash_max; -+ struct page *page = item->page; -+ struct stable_node *stable_node; -+ -+ stable_node = page_stable_node(page); -+ if (stable_node) { -+ /* ksm page forked, that is -+ * if (PageKsm(page) && !in_stable_tree(rmap_item)) -+ * it's actually gotten once outside. -+ */ -+ get_page(page); -+ return page; -+ } -+ -+ while (node) { -+ int cmp; -+ -+ tree_node = rb_entry(node, struct tree_node, node); -+ -+ cmp = hash_cmp(hash, tree_node->hash); -+ -+ if (cmp < 0) -+ node = node->rb_left; -+ else if (cmp > 0) -+ node = node->rb_right; -+ else -+ break; -+ } -+ -+ if (!node) -+ return NULL; -+ -+ if (tree_node->count == 1) { -+ stable_node = rb_entry(tree_node->sub_root.rb_node, -+ struct stable_node, node); -+ BUG_ON(!stable_node); -+ -+ goto get_page_out; -+ } -+ -+ /* -+ * ok, we have to search the second -+ * level subtree, hash the page to a -+ * full strength. -+ */ -+ node = tree_node->sub_root.rb_node; -+ BUG_ON(!node); -+ hash_max = rmap_item_hash_max(item, hash); -+ -+ while (node) { -+ int cmp; -+ -+ stable_node = rb_entry(node, struct stable_node, node); -+ -+ cmp = hash_cmp(hash_max, stable_node->hash_max); -+ -+ if (cmp < 0) -+ node = node->rb_left; -+ else if (cmp > 0) -+ node = node->rb_right; -+ else -+ goto get_page_out; -+ } -+ -+ return NULL; -+ -+get_page_out: -+ page = get_uksm_page(stable_node, 1, 1); -+ return page; -+} -+ -+static int try_merge_rmap_item(struct rmap_item *item, -+ struct page *kpage, -+ struct page *tree_page) -+{ -+ struct vm_area_struct *vma = item->slot->vma; -+ struct page_vma_mapped_walk pvmw = { -+ .page = kpage, -+ .vma = vma, -+ }; -+ -+ pvmw.address = get_rmap_addr(item); -+ if (!page_vma_mapped_walk(&pvmw)) -+ return 0; -+ -+ if (pte_write(*pvmw.pte)) { -+ /* has changed, abort! */ -+ page_vma_mapped_walk_done(&pvmw); -+ return 0; -+ } -+ -+ get_page(tree_page); -+ page_add_anon_rmap(tree_page, vma, pvmw.address, false); -+ -+ flush_cache_page(vma, pvmw.address, page_to_pfn(kpage)); -+ ptep_clear_flush_notify(vma, pvmw.address, pvmw.pte); -+ set_pte_at_notify(vma->vm_mm, pvmw.address, pvmw.pte, -+ mk_pte(tree_page, vma->vm_page_prot)); -+ -+ page_remove_rmap(kpage, false); -+ put_page(kpage); -+ -+ page_vma_mapped_walk_done(&pvmw); -+ -+ return 1; -+} -+ -+/** -+ * try_to_merge_with_stable_page() - when two rmap_items need to be inserted -+ * into stable tree, the page was found to be identical to a stable ksm page, -+ * this is the last chance we can merge them into one. -+ * -+ * @item1: the rmap_item holding the page which we wanted to insert -+ * into stable tree. -+ * @item2: the other rmap_item we found when unstable tree search -+ * @oldpage: the page currently mapped by the two rmap_items -+ * @tree_page: the page we found identical in stable tree node -+ * @success1: return if item1 is successfully merged -+ * @success2: return if item2 is successfully merged -+ */ -+static void try_merge_with_stable(struct rmap_item *item1, -+ struct rmap_item *item2, -+ struct page **kpage, -+ struct page *tree_page, -+ int *success1, int *success2) -+{ -+ struct vm_area_struct *vma1 = item1->slot->vma; -+ struct vm_area_struct *vma2 = item2->slot->vma; -+ *success1 = 0; -+ *success2 = 0; -+ -+ if (unlikely(*kpage == tree_page)) { -+ /* I don't think this can really happen */ -+ pr_warn("UKSM: unexpected condition detected in " -+ "%s -- *kpage == tree_page !\n", __func__); -+ *success1 = 1; -+ *success2 = 1; -+ return; -+ } -+ -+ if (!PageAnon(*kpage) || !PageKsm(*kpage)) -+ goto failed; -+ -+ if (!trylock_page(tree_page)) -+ goto failed; -+ -+ /* If the oldpage is still ksm and still pointed -+ * to in the right place, and still write protected, -+ * we are confident it's not changed, no need to -+ * memcmp anymore. -+ * be ware, we cannot take nested pte locks, -+ * deadlock risk. -+ */ -+ if (!try_merge_rmap_item(item1, *kpage, tree_page)) -+ goto unlock_failed; -+ -+ /* ok, then vma2, remind that pte1 already set */ -+ if (!try_merge_rmap_item(item2, *kpage, tree_page)) -+ goto success_1; -+ -+ *success2 = 1; -+success_1: -+ *success1 = 1; -+ -+ -+ if ((*success1 && vma1->vm_flags & VM_LOCKED) || -+ (*success2 && vma2->vm_flags & VM_LOCKED)) { -+ munlock_vma_page(*kpage); -+ if (!PageMlocked(tree_page)) -+ mlock_vma_page(tree_page); -+ } -+ -+ /* -+ * We do not need oldpage any more in the caller, so can break the lock -+ * now. -+ */ -+ unlock_page(*kpage); -+ *kpage = tree_page; /* Get unlocked outside. */ -+ return; -+ -+unlock_failed: -+ unlock_page(tree_page); -+failed: -+ return; -+} -+ -+static inline void stable_node_hash_max(struct stable_node *node, -+ struct page *page, u32 hash) -+{ -+ u32 hash_max = node->hash_max; -+ -+ if (!hash_max) { -+ hash_max = page_hash_max(page, hash); -+ node->hash_max = hash_max; -+ } -+} -+ -+static inline -+struct stable_node *new_stable_node(struct tree_node *tree_node, -+ struct page *kpage, u32 hash_max) -+{ -+ struct stable_node *new_stable_node; -+ -+ new_stable_node = alloc_stable_node(); -+ if (!new_stable_node) -+ return NULL; -+ -+ new_stable_node->kpfn = page_to_pfn(kpage); -+ new_stable_node->hash_max = hash_max; -+ new_stable_node->tree_node = tree_node; -+ set_page_stable_node(kpage, new_stable_node); -+ -+ return new_stable_node; -+} -+ -+static inline -+struct stable_node *first_level_insert(struct tree_node *tree_node, -+ struct rmap_item *rmap_item, -+ struct rmap_item *tree_rmap_item, -+ struct page **kpage, u32 hash, -+ int *success1, int *success2) -+{ -+ int cmp; -+ struct page *tree_page; -+ u32 hash_max = 0; -+ struct stable_node *stable_node, *new_snode; -+ struct rb_node *parent = NULL, **new; -+ -+ /* this tree node contains no sub-tree yet */ -+ stable_node = rb_entry(tree_node->sub_root.rb_node, -+ struct stable_node, node); -+ -+ tree_page = get_uksm_page(stable_node, 1, 0); -+ if (tree_page) { -+ cmp = memcmp_pages_with_cost(*kpage, tree_page, 1); -+ if (!cmp) { -+ try_merge_with_stable(rmap_item, tree_rmap_item, kpage, -+ tree_page, success1, success2); -+ put_page(tree_page); -+ if (!*success1 && !*success2) -+ goto failed; -+ -+ return stable_node; -+ -+ } else { -+ /* -+ * collision in first level try to create a subtree. -+ * A new node need to be created. -+ */ -+ put_page(tree_page); -+ -+ stable_node_hash_max(stable_node, tree_page, -+ tree_node->hash); -+ hash_max = rmap_item_hash_max(rmap_item, hash); -+ cmp = hash_cmp(hash_max, stable_node->hash_max); -+ -+ parent = &stable_node->node; -+ if (cmp < 0) -+ new = &parent->rb_left; -+ else if (cmp > 0) -+ new = &parent->rb_right; -+ else -+ goto failed; -+ } -+ -+ } else { -+ /* the only stable_node deleted, we reuse its tree_node. -+ */ -+ parent = NULL; -+ new = &tree_node->sub_root.rb_node; -+ } -+ -+ new_snode = new_stable_node(tree_node, *kpage, hash_max); -+ if (!new_snode) -+ goto failed; -+ -+ rb_link_node(&new_snode->node, parent, new); -+ rb_insert_color(&new_snode->node, &tree_node->sub_root); -+ tree_node->count++; -+ *success1 = *success2 = 1; -+ -+ return new_snode; -+ -+failed: -+ return NULL; -+} -+ -+static inline -+struct stable_node *stable_subtree_insert(struct tree_node *tree_node, -+ struct rmap_item *rmap_item, -+ struct rmap_item *tree_rmap_item, -+ struct page **kpage, u32 hash, -+ int *success1, int *success2) -+{ -+ struct page *tree_page; -+ u32 hash_max; -+ struct stable_node *stable_node, *new_snode; -+ struct rb_node *parent, **new; -+ -+research: -+ parent = NULL; -+ new = &tree_node->sub_root.rb_node; -+ BUG_ON(!*new); -+ hash_max = rmap_item_hash_max(rmap_item, hash); -+ while (*new) { -+ int cmp; -+ -+ stable_node = rb_entry(*new, struct stable_node, node); -+ -+ cmp = hash_cmp(hash_max, stable_node->hash_max); -+ -+ if (cmp < 0) { -+ parent = *new; -+ new = &parent->rb_left; -+ } else if (cmp > 0) { -+ parent = *new; -+ new = &parent->rb_right; -+ } else { -+ tree_page = get_uksm_page(stable_node, 1, 0); -+ if (tree_page) { -+ cmp = memcmp_pages_with_cost(*kpage, tree_page, 1); -+ if (!cmp) { -+ try_merge_with_stable(rmap_item, -+ tree_rmap_item, kpage, -+ tree_page, success1, success2); -+ -+ put_page(tree_page); -+ if (!*success1 && !*success2) -+ goto failed; -+ /* -+ * successfully merged with a stable -+ * node -+ */ -+ return stable_node; -+ } else { -+ put_page(tree_page); -+ goto failed; -+ } -+ } else { -+ /* -+ * stable node may be deleted, -+ * and subtree maybe -+ * restructed, cannot -+ * continue, research it. -+ */ -+ if (tree_node->count) { -+ goto research; -+ } else { -+ /* reuse the tree node*/ -+ parent = NULL; -+ new = &tree_node->sub_root.rb_node; -+ } -+ } -+ } -+ } -+ -+ new_snode = new_stable_node(tree_node, *kpage, hash_max); -+ if (!new_snode) -+ goto failed; -+ -+ rb_link_node(&new_snode->node, parent, new); -+ rb_insert_color(&new_snode->node, &tree_node->sub_root); -+ tree_node->count++; -+ *success1 = *success2 = 1; -+ -+ return new_snode; -+ -+failed: -+ return NULL; -+} -+ -+ -+/** -+ * stable_tree_insert() - try to insert a merged page in unstable tree to -+ * the stable tree -+ * -+ * @kpage: the page need to be inserted -+ * @hash: the current hash of this page -+ * @rmap_item: the rmap_item being scanned -+ * @tree_rmap_item: the rmap_item found on unstable tree -+ * @success1: return if rmap_item is merged -+ * @success2: return if tree_rmap_item is merged -+ * -+ * @return the stable_node on stable tree if at least one -+ * rmap_item is inserted into stable tree, NULL -+ * otherwise. -+ */ -+static struct stable_node * -+stable_tree_insert(struct page **kpage, u32 hash, -+ struct rmap_item *rmap_item, -+ struct rmap_item *tree_rmap_item, -+ int *success1, int *success2) -+{ -+ struct rb_node **new = &root_stable_treep->rb_node; -+ struct rb_node *parent = NULL; -+ struct stable_node *stable_node; -+ struct tree_node *tree_node; -+ u32 hash_max = 0; -+ -+ *success1 = *success2 = 0; -+ -+ while (*new) { -+ int cmp; -+ -+ tree_node = rb_entry(*new, struct tree_node, node); -+ -+ cmp = hash_cmp(hash, tree_node->hash); -+ -+ if (cmp < 0) { -+ parent = *new; -+ new = &parent->rb_left; -+ } else if (cmp > 0) { -+ parent = *new; -+ new = &parent->rb_right; -+ } else -+ break; -+ } -+ -+ if (*new) { -+ if (tree_node->count == 1) { -+ stable_node = first_level_insert(tree_node, rmap_item, -+ tree_rmap_item, kpage, -+ hash, success1, success2); -+ } else { -+ stable_node = stable_subtree_insert(tree_node, -+ rmap_item, tree_rmap_item, kpage, -+ hash, success1, success2); -+ } -+ } else { -+ -+ /* no tree node found */ -+ tree_node = alloc_tree_node(stable_tree_node_listp); -+ if (!tree_node) { -+ stable_node = NULL; -+ goto out; -+ } -+ -+ stable_node = new_stable_node(tree_node, *kpage, hash_max); -+ if (!stable_node) { -+ free_tree_node(tree_node); -+ goto out; -+ } -+ -+ tree_node->hash = hash; -+ rb_link_node(&tree_node->node, parent, new); -+ rb_insert_color(&tree_node->node, root_stable_treep); -+ parent = NULL; -+ new = &tree_node->sub_root.rb_node; -+ -+ rb_link_node(&stable_node->node, parent, new); -+ rb_insert_color(&stable_node->node, &tree_node->sub_root); -+ tree_node->count++; -+ *success1 = *success2 = 1; -+ } -+ -+out: -+ return stable_node; -+} -+ -+ -+/** -+ * get_tree_rmap_item_page() - try to get the page and lock the mmap_sem -+ * -+ * @return 0 on success, -EBUSY if unable to lock the mmap_sem, -+ * -EINVAL if the page mapping has been changed. -+ */ -+static inline int get_tree_rmap_item_page(struct rmap_item *tree_rmap_item) -+{ -+ int err; -+ -+ err = get_mergeable_page_lock_mmap(tree_rmap_item); -+ -+ if (err == -EINVAL) { -+ /* its page map has been changed, remove it */ -+ remove_rmap_item_from_tree(tree_rmap_item); -+ } -+ -+ /* The page is gotten and mmap_sem is locked now. */ -+ return err; -+} -+ -+ -+/** -+ * unstable_tree_search_insert() - search an unstable tree rmap_item with the -+ * same hash value. Get its page and trylock the mmap_sem -+ */ -+static inline -+struct rmap_item *unstable_tree_search_insert(struct rmap_item *rmap_item, -+ u32 hash) -+ -+{ -+ struct rb_node **new = &root_unstable_tree.rb_node; -+ struct rb_node *parent = NULL; -+ struct tree_node *tree_node; -+ u32 hash_max; -+ struct rmap_item *tree_rmap_item; -+ -+ while (*new) { -+ int cmp; -+ -+ tree_node = rb_entry(*new, struct tree_node, node); -+ -+ cmp = hash_cmp(hash, tree_node->hash); -+ -+ if (cmp < 0) { -+ parent = *new; -+ new = &parent->rb_left; -+ } else if (cmp > 0) { -+ parent = *new; -+ new = &parent->rb_right; -+ } else -+ break; -+ } -+ -+ if (*new) { -+ /* got the tree_node */ -+ if (tree_node->count == 1) { -+ tree_rmap_item = rb_entry(tree_node->sub_root.rb_node, -+ struct rmap_item, node); -+ BUG_ON(!tree_rmap_item); -+ -+ goto get_page_out; -+ } -+ -+ /* well, search the collision subtree */ -+ new = &tree_node->sub_root.rb_node; -+ BUG_ON(!*new); -+ hash_max = rmap_item_hash_max(rmap_item, hash); -+ -+ while (*new) { -+ int cmp; -+ -+ tree_rmap_item = rb_entry(*new, struct rmap_item, -+ node); -+ -+ cmp = hash_cmp(hash_max, tree_rmap_item->hash_max); -+ parent = *new; -+ if (cmp < 0) -+ new = &parent->rb_left; -+ else if (cmp > 0) -+ new = &parent->rb_right; -+ else -+ goto get_page_out; -+ } -+ } else { -+ /* alloc a new tree_node */ -+ tree_node = alloc_tree_node(&unstable_tree_node_list); -+ if (!tree_node) -+ return NULL; -+ -+ tree_node->hash = hash; -+ rb_link_node(&tree_node->node, parent, new); -+ rb_insert_color(&tree_node->node, &root_unstable_tree); -+ parent = NULL; -+ new = &tree_node->sub_root.rb_node; -+ } -+ -+ /* did not found even in sub-tree */ -+ rmap_item->tree_node = tree_node; -+ rmap_item->address |= UNSTABLE_FLAG; -+ rmap_item->hash_round = uksm_hash_round; -+ rb_link_node(&rmap_item->node, parent, new); -+ rb_insert_color(&rmap_item->node, &tree_node->sub_root); -+ -+ uksm_pages_unshared++; -+ return NULL; -+ -+get_page_out: -+ if (tree_rmap_item->page == rmap_item->page) -+ return NULL; -+ -+ if (get_tree_rmap_item_page(tree_rmap_item)) -+ return NULL; -+ -+ return tree_rmap_item; -+} -+ -+static void hold_anon_vma(struct rmap_item *rmap_item, -+ struct anon_vma *anon_vma) -+{ -+ rmap_item->anon_vma = anon_vma; -+ get_anon_vma(anon_vma); -+} -+ -+ -+/** -+ * stable_tree_append() - append a rmap_item to a stable node. Deduplication -+ * ratio statistics is done in this function. -+ * -+ */ -+static void stable_tree_append(struct rmap_item *rmap_item, -+ struct stable_node *stable_node, int logdedup) -+{ -+ struct node_vma *node_vma = NULL, *new_node_vma, *node_vma_cont = NULL; -+ unsigned long key = (unsigned long)rmap_item->slot; -+ unsigned long factor = rmap_item->slot->rung->step; -+ -+ BUG_ON(!stable_node); -+ rmap_item->address |= STABLE_FLAG; -+ -+ if (hlist_empty(&stable_node->hlist)) { -+ uksm_pages_shared++; -+ goto node_vma_new; -+ } else { -+ uksm_pages_sharing++; -+ } -+ -+ hlist_for_each_entry(node_vma, &stable_node->hlist, hlist) { -+ if (node_vma->key >= key) -+ break; -+ -+ if (logdedup) { -+ node_vma->slot->pages_bemerged += factor; -+ if (list_empty(&node_vma->slot->dedup_list)) -+ list_add(&node_vma->slot->dedup_list, -+ &vma_slot_dedup); -+ } -+ } -+ -+ if (node_vma) { -+ if (node_vma->key == key) { -+ node_vma_cont = hlist_entry_safe(node_vma->hlist.next, struct node_vma, hlist); -+ goto node_vma_ok; -+ } else if (node_vma->key > key) { -+ node_vma_cont = node_vma; -+ } -+ } -+ -+node_vma_new: -+ /* no same vma already in node, alloc a new node_vma */ -+ new_node_vma = alloc_node_vma(); -+ BUG_ON(!new_node_vma); -+ new_node_vma->head = stable_node; -+ new_node_vma->slot = rmap_item->slot; -+ -+ if (!node_vma) { -+ hlist_add_head(&new_node_vma->hlist, &stable_node->hlist); -+ } else if (node_vma->key != key) { -+ if (node_vma->key < key) -+ hlist_add_behind(&new_node_vma->hlist, &node_vma->hlist); -+ else { -+ hlist_add_before(&new_node_vma->hlist, -+ &node_vma->hlist); -+ } -+ -+ } -+ node_vma = new_node_vma; -+ -+node_vma_ok: /* ok, ready to add to the list */ -+ rmap_item->head = node_vma; -+ hlist_add_head(&rmap_item->hlist, &node_vma->rmap_hlist); -+ hold_anon_vma(rmap_item, rmap_item->slot->vma->anon_vma); -+ if (logdedup) { -+ rmap_item->slot->pages_merged++; -+ if (node_vma_cont) { -+ node_vma = node_vma_cont; -+ hlist_for_each_entry_continue(node_vma, hlist) { -+ node_vma->slot->pages_bemerged += factor; -+ if (list_empty(&node_vma->slot->dedup_list)) -+ list_add(&node_vma->slot->dedup_list, -+ &vma_slot_dedup); -+ } -+ } -+ } -+} -+ -+/* -+ * We use break_ksm to break COW on a ksm page: it's a stripped down -+ * -+ * if (get_user_pages(addr, 1, 1, 1, &page, NULL) == 1) -+ * put_page(page); -+ * -+ * but taking great care only to touch a ksm page, in a VM_MERGEABLE vma, -+ * in case the application has unmapped and remapped mm,addr meanwhile. -+ * Could a ksm page appear anywhere else? Actually yes, in a VM_PFNMAP -+ * mmap of /dev/mem or /dev/kmem, where we would not want to touch it. -+ */ -+static int break_ksm(struct vm_area_struct *vma, unsigned long addr) -+{ -+ struct page *page; -+ int ret = 0; -+ -+ do { -+ cond_resched(); -+ page = follow_page(vma, addr, FOLL_GET | FOLL_MIGRATION | FOLL_REMOTE); -+ if (IS_ERR_OR_NULL(page)) -+ break; -+ if (PageKsm(page)) { -+ ret = handle_mm_fault(vma, addr, -+ FAULT_FLAG_WRITE | FAULT_FLAG_REMOTE); -+ } else -+ ret = VM_FAULT_WRITE; -+ put_page(page); -+ } while (!(ret & (VM_FAULT_WRITE | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | VM_FAULT_OOM))); -+ /* -+ * We must loop because handle_mm_fault() may back out if there's -+ * any difficulty e.g. if pte accessed bit gets updated concurrently. -+ * -+ * VM_FAULT_WRITE is what we have been hoping for: it indicates that -+ * COW has been broken, even if the vma does not permit VM_WRITE; -+ * but note that a concurrent fault might break PageKsm for us. -+ * -+ * VM_FAULT_SIGBUS could occur if we race with truncation of the -+ * backing file, which also invalidates anonymous pages: that's -+ * okay, that truncation will have unmapped the PageKsm for us. -+ * -+ * VM_FAULT_OOM: at the time of writing (late July 2009), setting -+ * aside mem_cgroup limits, VM_FAULT_OOM would only be set if the -+ * current task has TIF_MEMDIE set, and will be OOM killed on return -+ * to user; and ksmd, having no mm, would never be chosen for that. -+ * -+ * But if the mm is in a limited mem_cgroup, then the fault may fail -+ * with VM_FAULT_OOM even if the current task is not TIF_MEMDIE; and -+ * even ksmd can fail in this way - though it's usually breaking ksm -+ * just to undo a merge it made a moment before, so unlikely to oom. -+ * -+ * That's a pity: we might therefore have more kernel pages allocated -+ * than we're counting as nodes in the stable tree; but uksm_do_scan -+ * will retry to break_cow on each pass, so should recover the page -+ * in due course. The important thing is to not let VM_MERGEABLE -+ * be cleared while any such pages might remain in the area. -+ */ -+ return (ret & VM_FAULT_OOM) ? -ENOMEM : 0; -+} -+ -+static void break_cow(struct rmap_item *rmap_item) -+{ -+ struct vm_area_struct *vma = rmap_item->slot->vma; -+ struct mm_struct *mm = vma->vm_mm; -+ unsigned long addr = get_rmap_addr(rmap_item); -+ -+ if (uksm_test_exit(mm)) -+ goto out; -+ -+ break_ksm(vma, addr); -+out: -+ return; -+} -+ -+/* -+ * Though it's very tempting to unmerge in_stable_tree(rmap_item)s rather -+ * than check every pte of a given vma, the locking doesn't quite work for -+ * that - an rmap_item is assigned to the stable tree after inserting ksm -+ * page and upping mmap_sem. Nor does it fit with the way we skip dup'ing -+ * rmap_items from parent to child at fork time (so as not to waste time -+ * if exit comes before the next scan reaches it). -+ * -+ * Similarly, although we'd like to remove rmap_items (so updating counts -+ * and freeing memory) when unmerging an area, it's easier to leave that -+ * to the next pass of ksmd - consider, for example, how ksmd might be -+ * in cmp_and_merge_page on one of the rmap_items we would be removing. -+ */ -+inline int unmerge_uksm_pages(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end) -+{ -+ unsigned long addr; -+ int err = 0; -+ -+ for (addr = start; addr < end && !err; addr += PAGE_SIZE) { -+ if (uksm_test_exit(vma->vm_mm)) -+ break; -+ if (signal_pending(current)) -+ err = -ERESTARTSYS; -+ else -+ err = break_ksm(vma, addr); -+ } -+ return err; -+} -+ -+static inline void inc_uksm_pages_scanned(void) -+{ -+ u64 delta; -+ -+ -+ if (uksm_pages_scanned == U64_MAX) { -+ encode_benefit(); -+ -+ delta = uksm_pages_scanned >> pages_scanned_base; -+ -+ if (CAN_OVERFLOW_U64(pages_scanned_stored, delta)) { -+ pages_scanned_stored >>= 1; -+ delta >>= 1; -+ pages_scanned_base++; -+ } -+ -+ pages_scanned_stored += delta; -+ -+ uksm_pages_scanned = uksm_pages_scanned_last = 0; -+ } -+ -+ uksm_pages_scanned++; -+} -+ -+static inline int find_zero_page_hash(int strength, u32 hash) -+{ -+ return (zero_hash_table[strength] == hash); -+} -+ -+static -+int cmp_and_merge_zero_page(struct vm_area_struct *vma, struct page *page) -+{ -+ struct page *zero_page = empty_uksm_zero_page; -+ struct mm_struct *mm = vma->vm_mm; -+ pte_t orig_pte = __pte(0); -+ int err = -EFAULT; -+ -+ if (uksm_test_exit(mm)) -+ goto out; -+ -+ if (!trylock_page(page)) -+ goto out; -+ -+ if (!PageAnon(page)) -+ goto out_unlock; -+ -+ if (PageTransCompound(page)) { -+ err = split_huge_page(page); -+ if (err) -+ goto out_unlock; -+ } -+ -+ if (write_protect_page(vma, page, &orig_pte, 0) == 0) { -+ if (is_page_full_zero(page)) -+ err = replace_page(vma, page, zero_page, orig_pte); -+ } -+ -+out_unlock: -+ unlock_page(page); -+out: -+ return err; -+} -+ -+/* -+ * cmp_and_merge_page() - first see if page can be merged into the stable -+ * tree; if not, compare hash to previous and if it's the same, see if page -+ * can be inserted into the unstable tree, or merged with a page already there -+ * and both transferred to the stable tree. -+ * -+ * @page: the page that we are searching identical page to. -+ * @rmap_item: the reverse mapping into the virtual address of this page -+ */ -+static void cmp_and_merge_page(struct rmap_item *rmap_item, u32 hash) -+{ -+ struct rmap_item *tree_rmap_item; -+ struct page *page; -+ struct page *kpage = NULL; -+ u32 hash_max; -+ int err; -+ unsigned int success1, success2; -+ struct stable_node *snode; -+ int cmp; -+ struct rb_node *parent = NULL, **new; -+ -+ remove_rmap_item_from_tree(rmap_item); -+ page = rmap_item->page; -+ -+ /* We first start with searching the page inside the stable tree */ -+ kpage = stable_tree_search(rmap_item, hash); -+ if (kpage) { -+ err = try_to_merge_with_uksm_page(rmap_item, kpage, -+ hash); -+ if (!err) { -+ /* -+ * The page was successfully merged, add -+ * its rmap_item to the stable tree. -+ * page lock is needed because it's -+ * racing with try_to_unmap_ksm(), etc. -+ */ -+ lock_page(kpage); -+ snode = page_stable_node(kpage); -+ stable_tree_append(rmap_item, snode, 1); -+ unlock_page(kpage); -+ put_page(kpage); -+ return; /* success */ -+ } -+ put_page(kpage); -+ -+ /* -+ * if it's a collision and it has been search in sub-rbtree -+ * (hash_max != 0), we want to abort, because if it is -+ * successfully merged in unstable tree, the collision trends to -+ * happen again. -+ */ -+ if (err == MERGE_ERR_COLLI && rmap_item->hash_max) -+ return; -+ } -+ -+ tree_rmap_item = -+ unstable_tree_search_insert(rmap_item, hash); -+ if (tree_rmap_item) { -+ err = try_to_merge_two_pages(rmap_item, tree_rmap_item, hash); -+ /* -+ * As soon as we merge this page, we want to remove the -+ * rmap_item of the page we have merged with from the unstable -+ * tree, and insert it instead as new node in the stable tree. -+ */ -+ if (!err) { -+ kpage = page; -+ remove_rmap_item_from_tree(tree_rmap_item); -+ lock_page(kpage); -+ snode = stable_tree_insert(&kpage, hash, -+ rmap_item, tree_rmap_item, -+ &success1, &success2); -+ -+ /* -+ * Do not log dedup for tree item, it's not counted as -+ * scanned in this round. -+ */ -+ if (success2) -+ stable_tree_append(tree_rmap_item, snode, 0); -+ -+ /* -+ * The order of these two stable append is important: -+ * we are scanning rmap_item. -+ */ -+ if (success1) -+ stable_tree_append(rmap_item, snode, 1); -+ -+ /* -+ * The original kpage may be unlocked inside -+ * stable_tree_insert() already. This page -+ * should be unlocked before doing -+ * break_cow(). -+ */ -+ unlock_page(kpage); -+ -+ if (!success1) -+ break_cow(rmap_item); -+ -+ if (!success2) -+ break_cow(tree_rmap_item); -+ -+ } else if (err == MERGE_ERR_COLLI) { -+ BUG_ON(tree_rmap_item->tree_node->count > 1); -+ -+ rmap_item_hash_max(tree_rmap_item, -+ tree_rmap_item->tree_node->hash); -+ -+ hash_max = rmap_item_hash_max(rmap_item, hash); -+ cmp = hash_cmp(hash_max, tree_rmap_item->hash_max); -+ parent = &tree_rmap_item->node; -+ if (cmp < 0) -+ new = &parent->rb_left; -+ else if (cmp > 0) -+ new = &parent->rb_right; -+ else -+ goto put_up_out; -+ -+ rmap_item->tree_node = tree_rmap_item->tree_node; -+ rmap_item->address |= UNSTABLE_FLAG; -+ rmap_item->hash_round = uksm_hash_round; -+ rb_link_node(&rmap_item->node, parent, new); -+ rb_insert_color(&rmap_item->node, -+ &tree_rmap_item->tree_node->sub_root); -+ rmap_item->tree_node->count++; -+ } else { -+ /* -+ * either one of the page has changed or they collide -+ * at the max hash, we consider them as ill items. -+ */ -+ remove_rmap_item_from_tree(tree_rmap_item); -+ } -+put_up_out: -+ put_page(tree_rmap_item->page); -+ mmap_read_unlock(tree_rmap_item->slot->vma->vm_mm); -+ } -+} -+ -+ -+ -+ -+static inline unsigned long get_pool_index(struct vma_slot *slot, -+ unsigned long index) -+{ -+ unsigned long pool_index; -+ -+ pool_index = (sizeof(struct rmap_list_entry *) * index) >> PAGE_SHIFT; -+ if (pool_index >= slot->pool_size) -+ BUG(); -+ return pool_index; -+} -+ -+static inline unsigned long index_page_offset(unsigned long index) -+{ -+ return offset_in_page(sizeof(struct rmap_list_entry *) * index); -+} -+ -+static inline -+struct rmap_list_entry *get_rmap_list_entry(struct vma_slot *slot, -+ unsigned long index, int need_alloc) -+{ -+ unsigned long pool_index; -+ struct page *page; -+ void *addr; -+ -+ -+ pool_index = get_pool_index(slot, index); -+ if (!slot->rmap_list_pool[pool_index]) { -+ if (!need_alloc) -+ return NULL; -+ -+ page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN); -+ if (!page) -+ return NULL; -+ -+ slot->rmap_list_pool[pool_index] = page; -+ } -+ -+ addr = kmap(slot->rmap_list_pool[pool_index]); -+ addr += index_page_offset(index); -+ -+ return addr; -+} -+ -+static inline void put_rmap_list_entry(struct vma_slot *slot, -+ unsigned long index) -+{ -+ unsigned long pool_index; -+ -+ pool_index = get_pool_index(slot, index); -+ BUG_ON(!slot->rmap_list_pool[pool_index]); -+ kunmap(slot->rmap_list_pool[pool_index]); -+} -+ -+static inline int entry_is_new(struct rmap_list_entry *entry) -+{ -+ return !entry->item; -+} -+ -+static inline unsigned long get_index_orig_addr(struct vma_slot *slot, -+ unsigned long index) -+{ -+ return slot->vma->vm_start + (index << PAGE_SHIFT); -+} -+ -+static inline unsigned long get_entry_address(struct rmap_list_entry *entry) -+{ -+ unsigned long addr; -+ -+ if (is_addr(entry->addr)) -+ addr = get_clean_addr(entry->addr); -+ else if (entry->item) -+ addr = get_rmap_addr(entry->item); -+ else -+ BUG(); -+ -+ return addr; -+} -+ -+static inline struct rmap_item *get_entry_item(struct rmap_list_entry *entry) -+{ -+ if (is_addr(entry->addr)) -+ return NULL; -+ -+ return entry->item; -+} -+ -+static inline void inc_rmap_list_pool_count(struct vma_slot *slot, -+ unsigned long index) -+{ -+ unsigned long pool_index; -+ -+ pool_index = get_pool_index(slot, index); -+ BUG_ON(!slot->rmap_list_pool[pool_index]); -+ slot->pool_counts[pool_index]++; -+} -+ -+static inline void dec_rmap_list_pool_count(struct vma_slot *slot, -+ unsigned long index) -+{ -+ unsigned long pool_index; -+ -+ pool_index = get_pool_index(slot, index); -+ BUG_ON(!slot->rmap_list_pool[pool_index]); -+ BUG_ON(!slot->pool_counts[pool_index]); -+ slot->pool_counts[pool_index]--; -+} -+ -+static inline int entry_has_rmap(struct rmap_list_entry *entry) -+{ -+ return !is_addr(entry->addr) && entry->item; -+} -+ -+static inline void swap_entries(struct rmap_list_entry *entry1, -+ unsigned long index1, -+ struct rmap_list_entry *entry2, -+ unsigned long index2) -+{ -+ struct rmap_list_entry tmp; -+ -+ /* swapping two new entries is meaningless */ -+ BUG_ON(entry_is_new(entry1) && entry_is_new(entry2)); -+ -+ tmp = *entry1; -+ *entry1 = *entry2; -+ *entry2 = tmp; -+ -+ if (entry_has_rmap(entry1)) -+ entry1->item->entry_index = index1; -+ -+ if (entry_has_rmap(entry2)) -+ entry2->item->entry_index = index2; -+ -+ if (entry_has_rmap(entry1) && !entry_has_rmap(entry2)) { -+ inc_rmap_list_pool_count(entry1->item->slot, index1); -+ dec_rmap_list_pool_count(entry1->item->slot, index2); -+ } else if (!entry_has_rmap(entry1) && entry_has_rmap(entry2)) { -+ inc_rmap_list_pool_count(entry2->item->slot, index2); -+ dec_rmap_list_pool_count(entry2->item->slot, index1); -+ } -+} -+ -+static inline void free_entry_item(struct rmap_list_entry *entry) -+{ -+ unsigned long index; -+ struct rmap_item *item; -+ -+ if (!is_addr(entry->addr)) { -+ BUG_ON(!entry->item); -+ item = entry->item; -+ entry->addr = get_rmap_addr(item); -+ set_is_addr(entry->addr); -+ index = item->entry_index; -+ remove_rmap_item_from_tree(item); -+ dec_rmap_list_pool_count(item->slot, index); -+ free_rmap_item(item); -+ } -+} -+ -+static inline int pool_entry_boundary(unsigned long index) -+{ -+ unsigned long linear_addr; -+ -+ linear_addr = sizeof(struct rmap_list_entry *) * index; -+ return index && !offset_in_page(linear_addr); -+} -+ -+static inline void try_free_last_pool(struct vma_slot *slot, -+ unsigned long index) -+{ -+ unsigned long pool_index; -+ -+ pool_index = get_pool_index(slot, index); -+ if (slot->rmap_list_pool[pool_index] && -+ !slot->pool_counts[pool_index]) { -+ __free_page(slot->rmap_list_pool[pool_index]); -+ slot->rmap_list_pool[pool_index] = NULL; -+ slot->flags |= UKSM_SLOT_NEED_SORT; -+ } -+ -+} -+ -+static inline unsigned long vma_item_index(struct vm_area_struct *vma, -+ struct rmap_item *item) -+{ -+ return (get_rmap_addr(item) - vma->vm_start) >> PAGE_SHIFT; -+} -+ -+static int within_same_pool(struct vma_slot *slot, -+ unsigned long i, unsigned long j) -+{ -+ unsigned long pool_i, pool_j; -+ -+ pool_i = get_pool_index(slot, i); -+ pool_j = get_pool_index(slot, j); -+ -+ return (pool_i == pool_j); -+} -+ -+static void sort_rmap_entry_list(struct vma_slot *slot) -+{ -+ unsigned long i, j; -+ struct rmap_list_entry *entry, *swap_entry; -+ -+ entry = get_rmap_list_entry(slot, 0, 0); -+ for (i = 0; i < slot->pages; ) { -+ -+ if (!entry) -+ goto skip_whole_pool; -+ -+ if (entry_is_new(entry)) -+ goto next_entry; -+ -+ if (is_addr(entry->addr)) { -+ entry->addr = 0; -+ goto next_entry; -+ } -+ -+ j = vma_item_index(slot->vma, entry->item); -+ if (j == i) -+ goto next_entry; -+ -+ if (within_same_pool(slot, i, j)) -+ swap_entry = entry + j - i; -+ else -+ swap_entry = get_rmap_list_entry(slot, j, 1); -+ -+ swap_entries(entry, i, swap_entry, j); -+ if (!within_same_pool(slot, i, j)) -+ put_rmap_list_entry(slot, j); -+ continue; -+ -+skip_whole_pool: -+ i += PAGE_SIZE / sizeof(*entry); -+ if (i < slot->pages) -+ entry = get_rmap_list_entry(slot, i, 0); -+ continue; -+ -+next_entry: -+ if (i >= slot->pages - 1 || -+ !within_same_pool(slot, i, i + 1)) { -+ put_rmap_list_entry(slot, i); -+ if (i + 1 < slot->pages) -+ entry = get_rmap_list_entry(slot, i + 1, 0); -+ } else -+ entry++; -+ i++; -+ continue; -+ } -+ -+ /* free empty pool entries which contain no rmap_item */ -+ /* CAN be simplied to based on only pool_counts when bug freed !!!!! */ -+ for (i = 0; i < slot->pool_size; i++) { -+ unsigned char has_rmap; -+ void *addr; -+ -+ if (!slot->rmap_list_pool[i]) -+ continue; -+ -+ has_rmap = 0; -+ addr = kmap(slot->rmap_list_pool[i]); -+ BUG_ON(!addr); -+ for (j = 0; j < PAGE_SIZE / sizeof(*entry); j++) { -+ entry = (struct rmap_list_entry *)addr + j; -+ if (is_addr(entry->addr)) -+ continue; -+ if (!entry->item) -+ continue; -+ has_rmap = 1; -+ } -+ kunmap(slot->rmap_list_pool[i]); -+ if (!has_rmap) { -+ BUG_ON(slot->pool_counts[i]); -+ __free_page(slot->rmap_list_pool[i]); -+ slot->rmap_list_pool[i] = NULL; -+ } -+ } -+ -+ slot->flags &= ~UKSM_SLOT_NEED_SORT; -+} -+ -+/* -+ * vma_fully_scanned() - if all the pages in this slot have been scanned. -+ */ -+static inline int vma_fully_scanned(struct vma_slot *slot) -+{ -+ return slot->pages_scanned == slot->pages; -+} -+ -+/** -+ * get_next_rmap_item() - Get the next rmap_item in a vma_slot according to -+ * its random permutation. This function is embedded with the random -+ * permutation index management code. -+ */ -+static struct rmap_item *get_next_rmap_item(struct vma_slot *slot, u32 *hash) -+{ -+ unsigned long rand_range, addr, swap_index, scan_index; -+ struct rmap_item *item = NULL; -+ struct rmap_list_entry *scan_entry, *swap_entry = NULL; -+ struct page *page; -+ -+ scan_index = swap_index = slot->pages_scanned % slot->pages; -+ -+ if (pool_entry_boundary(scan_index)) -+ try_free_last_pool(slot, scan_index - 1); -+ -+ if (vma_fully_scanned(slot)) { -+ if (slot->flags & UKSM_SLOT_NEED_SORT) -+ slot->flags |= UKSM_SLOT_NEED_RERAND; -+ else -+ slot->flags &= ~UKSM_SLOT_NEED_RERAND; -+ if (slot->flags & UKSM_SLOT_NEED_SORT) -+ sort_rmap_entry_list(slot); -+ } -+ -+ scan_entry = get_rmap_list_entry(slot, scan_index, 1); -+ if (!scan_entry) -+ return NULL; -+ -+ if (entry_is_new(scan_entry)) { -+ scan_entry->addr = get_index_orig_addr(slot, scan_index); -+ set_is_addr(scan_entry->addr); -+ } -+ -+ if (slot->flags & UKSM_SLOT_NEED_RERAND) { -+ rand_range = slot->pages - scan_index; -+ BUG_ON(!rand_range); -+ swap_index = scan_index + (prandom_u32() % rand_range); -+ } -+ -+ if (swap_index != scan_index) { -+ swap_entry = get_rmap_list_entry(slot, swap_index, 1); -+ -+ if (!swap_entry) -+ return NULL; -+ -+ if (entry_is_new(swap_entry)) { -+ swap_entry->addr = get_index_orig_addr(slot, -+ swap_index); -+ set_is_addr(swap_entry->addr); -+ } -+ swap_entries(scan_entry, scan_index, swap_entry, swap_index); -+ } -+ -+ addr = get_entry_address(scan_entry); -+ item = get_entry_item(scan_entry); -+ BUG_ON(addr > slot->vma->vm_end || addr < slot->vma->vm_start); -+ -+ page = follow_page(slot->vma, addr, FOLL_GET); -+ if (IS_ERR_OR_NULL(page)) -+ goto nopage; -+ -+ if (!PageAnon(page)) -+ goto putpage; -+ -+ /*check is zero_page pfn or uksm_zero_page*/ -+ if ((page_to_pfn(page) == zero_pfn) -+ || (page_to_pfn(page) == uksm_zero_pfn)) -+ goto putpage; -+ -+ flush_anon_page(slot->vma, page, addr); -+ flush_dcache_page(page); -+ -+ -+ *hash = page_hash(page, hash_strength, 1); -+ inc_uksm_pages_scanned(); -+ /*if the page content all zero, re-map to zero-page*/ -+ if (find_zero_page_hash(hash_strength, *hash)) { -+ if (!cmp_and_merge_zero_page(slot->vma, page)) { -+ slot->pages_merged++; -+ -+ /* For full-zero pages, no need to create rmap item */ -+ goto putpage; -+ } else { -+ inc_rshash_neg(memcmp_cost / 2); -+ } -+ } -+ -+ if (!item) { -+ item = alloc_rmap_item(); -+ if (item) { -+ /* It has already been zeroed */ -+ item->slot = slot; -+ item->address = addr; -+ item->entry_index = scan_index; -+ scan_entry->item = item; -+ inc_rmap_list_pool_count(slot, scan_index); -+ } else -+ goto putpage; -+ } -+ -+ BUG_ON(item->slot != slot); -+ /* the page may have changed */ -+ item->page = page; -+ put_rmap_list_entry(slot, scan_index); -+ if (swap_entry) -+ put_rmap_list_entry(slot, swap_index); -+ return item; -+ -+putpage: -+ put_page(page); -+ page = NULL; -+nopage: -+ /* no page, store addr back and free rmap_item if possible */ -+ free_entry_item(scan_entry); -+ put_rmap_list_entry(slot, scan_index); -+ if (swap_entry) -+ put_rmap_list_entry(slot, swap_index); -+ return NULL; -+} -+ -+static inline int in_stable_tree(struct rmap_item *rmap_item) -+{ -+ return rmap_item->address & STABLE_FLAG; -+} -+ -+/** -+ * scan_vma_one_page() - scan the next page in a vma_slot. Called with -+ * mmap_sem locked. -+ */ -+static noinline void scan_vma_one_page(struct vma_slot *slot) -+{ -+ u32 hash; -+ struct mm_struct *mm; -+ struct rmap_item *rmap_item = NULL; -+ struct vm_area_struct *vma = slot->vma; -+ -+ mm = vma->vm_mm; -+ BUG_ON(!mm); -+ BUG_ON(!slot); -+ -+ rmap_item = get_next_rmap_item(slot, &hash); -+ if (!rmap_item) -+ goto out1; -+ -+ if (PageKsm(rmap_item->page) && in_stable_tree(rmap_item)) -+ goto out2; -+ -+ cmp_and_merge_page(rmap_item, hash); -+out2: -+ put_page(rmap_item->page); -+out1: -+ slot->pages_scanned++; -+ slot->this_sampled++; -+ if (slot->fully_scanned_round != fully_scanned_round) -+ scanned_virtual_pages++; -+ -+ if (vma_fully_scanned(slot)) -+ slot->fully_scanned_round = fully_scanned_round; -+} -+ -+static inline unsigned long rung_get_pages(struct scan_rung *rung) -+{ -+ struct slot_tree_node *node; -+ -+ if (!rung->vma_root.rnode) -+ return 0; -+ -+ node = container_of(rung->vma_root.rnode, struct slot_tree_node, snode); -+ -+ return node->size; -+} -+ -+#define RUNG_SAMPLED_MIN 3 -+ -+static inline -+void uksm_calc_rung_step(struct scan_rung *rung, -+ unsigned long page_time, unsigned long ratio) -+{ -+ unsigned long sampled, pages; -+ -+ /* will be fully scanned ? */ -+ if (!rung->cover_msecs) { -+ rung->step = 1; -+ return; -+ } -+ -+ sampled = rung->cover_msecs * (NSEC_PER_MSEC / TIME_RATIO_SCALE) -+ * ratio / page_time; -+ -+ /* -+ * Before we finsish a scan round and expensive per-round jobs, -+ * we need to have a chance to estimate the per page time. So -+ * the sampled number can not be too small. -+ */ -+ if (sampled < RUNG_SAMPLED_MIN) -+ sampled = RUNG_SAMPLED_MIN; -+ -+ pages = rung_get_pages(rung); -+ if (likely(pages > sampled)) -+ rung->step = pages / sampled; -+ else -+ rung->step = 1; -+} -+ -+static inline int step_need_recalc(struct scan_rung *rung) -+{ -+ unsigned long pages, stepmax; -+ -+ pages = rung_get_pages(rung); -+ stepmax = pages / RUNG_SAMPLED_MIN; -+ -+ return pages && (rung->step > pages || -+ (stepmax && rung->step > stepmax)); -+} -+ -+static inline -+void reset_current_scan(struct scan_rung *rung, int finished, int step_recalc) -+{ -+ struct vma_slot *slot; -+ -+ if (finished) -+ rung->flags |= UKSM_RUNG_ROUND_FINISHED; -+ -+ if (step_recalc || step_need_recalc(rung)) { -+ uksm_calc_rung_step(rung, uksm_ema_page_time, rung->cpu_ratio); -+ BUG_ON(step_need_recalc(rung)); -+ } -+ -+ slot_iter_index = prandom_u32() % rung->step; -+ BUG_ON(!rung->vma_root.rnode); -+ slot = sradix_tree_next(&rung->vma_root, NULL, 0, slot_iter); -+ BUG_ON(!slot); -+ -+ rung->current_scan = slot; -+ rung->current_offset = slot_iter_index; -+} -+ -+static inline struct sradix_tree_root *slot_get_root(struct vma_slot *slot) -+{ -+ return &slot->rung->vma_root; -+} -+ -+/* -+ * return if resetted. -+ */ -+static int advance_current_scan(struct scan_rung *rung) -+{ -+ unsigned short n; -+ struct vma_slot *slot, *next = NULL; -+ -+ BUG_ON(!rung->vma_root.num); -+ -+ slot = rung->current_scan; -+ n = (slot->pages - rung->current_offset) % rung->step; -+ slot_iter_index = rung->step - n; -+ next = sradix_tree_next(&rung->vma_root, slot->snode, -+ slot->sindex, slot_iter); -+ -+ if (next) { -+ rung->current_offset = slot_iter_index; -+ rung->current_scan = next; -+ return 0; -+ } else { -+ reset_current_scan(rung, 1, 0); -+ return 1; -+ } -+} -+ -+static inline void rung_rm_slot(struct vma_slot *slot) -+{ -+ struct scan_rung *rung = slot->rung; -+ struct sradix_tree_root *root; -+ -+ if (rung->current_scan == slot) -+ advance_current_scan(rung); -+ -+ root = slot_get_root(slot); -+ sradix_tree_delete_from_leaf(root, slot->snode, slot->sindex); -+ slot->snode = NULL; -+ if (step_need_recalc(rung)) { -+ uksm_calc_rung_step(rung, uksm_ema_page_time, rung->cpu_ratio); -+ BUG_ON(step_need_recalc(rung)); -+ } -+ -+ /* In case advance_current_scan loop back to this slot again */ -+ if (rung->vma_root.num && rung->current_scan == slot) -+ reset_current_scan(slot->rung, 1, 0); -+} -+ -+static inline void rung_add_new_slots(struct scan_rung *rung, -+ struct vma_slot **slots, unsigned long num) -+{ -+ int err; -+ struct vma_slot *slot; -+ unsigned long i; -+ struct sradix_tree_root *root = &rung->vma_root; -+ -+ err = sradix_tree_enter(root, (void **)slots, num); -+ BUG_ON(err); -+ -+ for (i = 0; i < num; i++) { -+ slot = slots[i]; -+ slot->rung = rung; -+ BUG_ON(vma_fully_scanned(slot)); -+ } -+ -+ if (rung->vma_root.num == num) -+ reset_current_scan(rung, 0, 1); -+} -+ -+static inline int rung_add_one_slot(struct scan_rung *rung, -+ struct vma_slot *slot) -+{ -+ int err; -+ -+ err = sradix_tree_enter(&rung->vma_root, (void **)&slot, 1); -+ if (err) -+ return err; -+ -+ slot->rung = rung; -+ if (rung->vma_root.num == 1) -+ reset_current_scan(rung, 0, 1); -+ -+ return 0; -+} -+ -+/* -+ * Return true if the slot is deleted from its rung. -+ */ -+static inline int vma_rung_enter(struct vma_slot *slot, struct scan_rung *rung) -+{ -+ struct scan_rung *old_rung = slot->rung; -+ int err; -+ -+ if (old_rung == rung) -+ return 0; -+ -+ rung_rm_slot(slot); -+ err = rung_add_one_slot(rung, slot); -+ if (err) { -+ err = rung_add_one_slot(old_rung, slot); -+ WARN_ON(err); /* OOPS, badly OOM, we lost this slot */ -+ } -+ -+ return 1; -+} -+ -+static inline int vma_rung_up(struct vma_slot *slot) -+{ -+ struct scan_rung *rung; -+ -+ rung = slot->rung; -+ if (slot->rung != &uksm_scan_ladder[SCAN_LADDER_SIZE-1]) -+ rung++; -+ -+ return vma_rung_enter(slot, rung); -+} -+ -+static inline int vma_rung_down(struct vma_slot *slot) -+{ -+ struct scan_rung *rung; -+ -+ rung = slot->rung; -+ if (slot->rung != &uksm_scan_ladder[0]) -+ rung--; -+ -+ return vma_rung_enter(slot, rung); -+} -+ -+/** -+ * cal_dedup_ratio() - Calculate the deduplication ratio for this slot. -+ */ -+static unsigned long cal_dedup_ratio(struct vma_slot *slot) -+{ -+ unsigned long ret; -+ unsigned long pages; -+ -+ pages = slot->this_sampled; -+ if (!pages) -+ return 0; -+ -+ BUG_ON(slot->pages_scanned == slot->last_scanned); -+ -+ ret = slot->pages_merged; -+ -+ /* Thrashing area filtering */ -+ if (ret && uksm_thrash_threshold) { -+ if (slot->pages_cowed * 100 / slot->pages_merged -+ > uksm_thrash_threshold) { -+ ret = 0; -+ } else { -+ ret = slot->pages_merged - slot->pages_cowed; -+ } -+ } -+ -+ return ret * 100 / pages; -+} -+ -+/** -+ * cal_dedup_ratio() - Calculate the deduplication ratio for this slot. -+ */ -+static unsigned long cal_dedup_ratio_old(struct vma_slot *slot) -+{ -+ unsigned long ret; -+ unsigned long pages; -+ -+ pages = slot->pages; -+ if (!pages) -+ return 0; -+ -+ ret = slot->pages_bemerged; -+ -+ /* Thrashing area filtering */ -+ if (ret && uksm_thrash_threshold) { -+ if (slot->pages_cowed * 100 / slot->pages_bemerged -+ > uksm_thrash_threshold) { -+ ret = 0; -+ } else { -+ ret = slot->pages_bemerged - slot->pages_cowed; -+ } -+ } -+ -+ return ret * 100 / pages; -+} -+ -+/** -+ * stable_node_reinsert() - When the hash_strength has been adjusted, the -+ * stable tree need to be restructured, this is the function re-inserting the -+ * stable node. -+ */ -+static inline void stable_node_reinsert(struct stable_node *new_node, -+ struct page *page, -+ struct rb_root *root_treep, -+ struct list_head *tree_node_listp, -+ u32 hash) -+{ -+ struct rb_node **new = &root_treep->rb_node; -+ struct rb_node *parent = NULL; -+ struct stable_node *stable_node; -+ struct tree_node *tree_node; -+ struct page *tree_page; -+ int cmp; -+ -+ while (*new) { -+ int cmp; -+ -+ tree_node = rb_entry(*new, struct tree_node, node); -+ -+ cmp = hash_cmp(hash, tree_node->hash); -+ -+ if (cmp < 0) { -+ parent = *new; -+ new = &parent->rb_left; -+ } else if (cmp > 0) { -+ parent = *new; -+ new = &parent->rb_right; -+ } else -+ break; -+ } -+ -+ if (*new) { -+ /* find a stable tree node with same first level hash value */ -+ stable_node_hash_max(new_node, page, hash); -+ if (tree_node->count == 1) { -+ stable_node = rb_entry(tree_node->sub_root.rb_node, -+ struct stable_node, node); -+ tree_page = get_uksm_page(stable_node, 1, 0); -+ if (tree_page) { -+ stable_node_hash_max(stable_node, -+ tree_page, hash); -+ put_page(tree_page); -+ -+ /* prepare for stable node insertion */ -+ -+ cmp = hash_cmp(new_node->hash_max, -+ stable_node->hash_max); -+ parent = &stable_node->node; -+ if (cmp < 0) -+ new = &parent->rb_left; -+ else if (cmp > 0) -+ new = &parent->rb_right; -+ else -+ goto failed; -+ -+ goto add_node; -+ } else { -+ /* the only stable_node deleted, the tree node -+ * was not deleted. -+ */ -+ goto tree_node_reuse; -+ } -+ } -+ -+ /* well, search the collision subtree */ -+ new = &tree_node->sub_root.rb_node; -+ parent = NULL; -+ BUG_ON(!*new); -+ while (*new) { -+ int cmp; -+ -+ stable_node = rb_entry(*new, struct stable_node, node); -+ -+ cmp = hash_cmp(new_node->hash_max, -+ stable_node->hash_max); -+ -+ if (cmp < 0) { -+ parent = *new; -+ new = &parent->rb_left; -+ } else if (cmp > 0) { -+ parent = *new; -+ new = &parent->rb_right; -+ } else { -+ /* oh, no, still a collision */ -+ goto failed; -+ } -+ } -+ -+ goto add_node; -+ } -+ -+ /* no tree node found */ -+ tree_node = alloc_tree_node(tree_node_listp); -+ if (!tree_node) { -+ pr_err("UKSM: memory allocation error!\n"); -+ goto failed; -+ } else { -+ tree_node->hash = hash; -+ rb_link_node(&tree_node->node, parent, new); -+ rb_insert_color(&tree_node->node, root_treep); -+ -+tree_node_reuse: -+ /* prepare for stable node insertion */ -+ parent = NULL; -+ new = &tree_node->sub_root.rb_node; -+ } -+ -+add_node: -+ rb_link_node(&new_node->node, parent, new); -+ rb_insert_color(&new_node->node, &tree_node->sub_root); -+ new_node->tree_node = tree_node; -+ tree_node->count++; -+ return; -+ -+failed: -+ /* This can only happen when two nodes have collided -+ * in two levels. -+ */ -+ new_node->tree_node = NULL; -+ return; -+} -+ -+static inline void free_all_tree_nodes(struct list_head *list) -+{ -+ struct tree_node *node, *tmp; -+ -+ list_for_each_entry_safe(node, tmp, list, all_list) { -+ free_tree_node(node); -+ } -+} -+ -+/** -+ * stable_tree_delta_hash() - Delta hash the stable tree from previous hash -+ * strength to the current hash_strength. It re-structures the hole tree. -+ */ -+static inline void stable_tree_delta_hash(u32 prev_hash_strength) -+{ -+ struct stable_node *node, *tmp; -+ struct rb_root *root_new_treep; -+ struct list_head *new_tree_node_listp; -+ -+ stable_tree_index = (stable_tree_index + 1) % 2; -+ root_new_treep = &root_stable_tree[stable_tree_index]; -+ new_tree_node_listp = &stable_tree_node_list[stable_tree_index]; -+ *root_new_treep = RB_ROOT; -+ BUG_ON(!list_empty(new_tree_node_listp)); -+ -+ /* -+ * we need to be safe, the node could be removed by get_uksm_page() -+ */ -+ list_for_each_entry_safe(node, tmp, &stable_node_list, all_list) { -+ void *addr; -+ struct page *node_page; -+ u32 hash; -+ -+ /* -+ * We are completely re-structuring the stable nodes to a new -+ * stable tree. We don't want to touch the old tree unlinks and -+ * old tree_nodes. The old tree_nodes will be freed at once. -+ */ -+ node_page = get_uksm_page(node, 0, 0); -+ if (!node_page) -+ continue; -+ -+ if (node->tree_node) { -+ hash = node->tree_node->hash; -+ -+ addr = kmap_atomic(node_page); -+ -+ hash = delta_hash(addr, prev_hash_strength, -+ hash_strength, hash); -+ kunmap_atomic(addr); -+ } else { -+ /* -+ *it was not inserted to rbtree due to collision in last -+ *round scan. -+ */ -+ hash = page_hash(node_page, hash_strength, 0); -+ } -+ -+ stable_node_reinsert(node, node_page, root_new_treep, -+ new_tree_node_listp, hash); -+ put_page(node_page); -+ } -+ -+ root_stable_treep = root_new_treep; -+ free_all_tree_nodes(stable_tree_node_listp); -+ BUG_ON(!list_empty(stable_tree_node_listp)); -+ stable_tree_node_listp = new_tree_node_listp; -+} -+ -+static inline void inc_hash_strength(unsigned long delta) -+{ -+ hash_strength += 1 << delta; -+ if (hash_strength > HASH_STRENGTH_MAX) -+ hash_strength = HASH_STRENGTH_MAX; -+} -+ -+static inline void dec_hash_strength(unsigned long delta) -+{ -+ unsigned long change = 1 << delta; -+ -+ if (hash_strength <= change + 1) -+ hash_strength = 1; -+ else -+ hash_strength -= change; -+} -+ -+static inline void inc_hash_strength_delta(void) -+{ -+ hash_strength_delta++; -+ if (hash_strength_delta > HASH_STRENGTH_DELTA_MAX) -+ hash_strength_delta = HASH_STRENGTH_DELTA_MAX; -+} -+ -+static inline unsigned long get_current_neg_ratio(void) -+{ -+ u64 pos = benefit.pos; -+ u64 neg = benefit.neg; -+ -+ if (!neg) -+ return 0; -+ -+ if (!pos || neg > pos) -+ return 100; -+ -+ if (neg > div64_u64(U64_MAX, 100)) -+ pos = div64_u64(pos, 100); -+ else -+ neg *= 100; -+ -+ return div64_u64(neg, pos); -+} -+ -+static inline unsigned long get_current_benefit(void) -+{ -+ u64 pos = benefit.pos; -+ u64 neg = benefit.neg; -+ u64 scanned = benefit.scanned; -+ -+ if (neg > pos) -+ return 0; -+ -+ return div64_u64((pos - neg), scanned); -+} -+ -+static inline int judge_rshash_direction(void) -+{ -+ u64 current_neg_ratio, stable_benefit; -+ u64 current_benefit, delta = 0; -+ int ret = STILL; -+ -+ /* -+ * Try to probe a value after the boot, and in case the system -+ * are still for a long time. -+ */ -+ if ((fully_scanned_round & 0xFFULL) == 10) { -+ ret = OBSCURE; -+ goto out; -+ } -+ -+ current_neg_ratio = get_current_neg_ratio(); -+ -+ if (current_neg_ratio == 0) { -+ rshash_neg_cont_zero++; -+ if (rshash_neg_cont_zero > 2) -+ return GO_DOWN; -+ else -+ return STILL; -+ } -+ rshash_neg_cont_zero = 0; -+ -+ if (current_neg_ratio > 90) { -+ ret = GO_UP; -+ goto out; -+ } -+ -+ current_benefit = get_current_benefit(); -+ stable_benefit = rshash_state.stable_benefit; -+ -+ if (!stable_benefit) { -+ ret = OBSCURE; -+ goto out; -+ } -+ -+ if (current_benefit > stable_benefit) -+ delta = current_benefit - stable_benefit; -+ else if (current_benefit < stable_benefit) -+ delta = stable_benefit - current_benefit; -+ -+ delta = div64_u64(100 * delta, stable_benefit); -+ -+ if (delta > 50) { -+ rshash_cont_obscure++; -+ if (rshash_cont_obscure > 2) -+ return OBSCURE; -+ else -+ return STILL; -+ } -+ -+out: -+ rshash_cont_obscure = 0; -+ return ret; -+} -+ -+/** -+ * rshash_adjust() - The main function to control the random sampling state -+ * machine for hash strength adapting. -+ * -+ * return true if hash_strength has changed. -+ */ -+static inline int rshash_adjust(void) -+{ -+ unsigned long prev_hash_strength = hash_strength; -+ -+ if (!encode_benefit()) -+ return 0; -+ -+ switch (rshash_state.state) { -+ case RSHASH_STILL: -+ switch (judge_rshash_direction()) { -+ case GO_UP: -+ if (rshash_state.pre_direct == GO_DOWN) -+ hash_strength_delta = 0; -+ -+ inc_hash_strength(hash_strength_delta); -+ inc_hash_strength_delta(); -+ rshash_state.stable_benefit = get_current_benefit(); -+ rshash_state.pre_direct = GO_UP; -+ break; -+ -+ case GO_DOWN: -+ if (rshash_state.pre_direct == GO_UP) -+ hash_strength_delta = 0; -+ -+ dec_hash_strength(hash_strength_delta); -+ inc_hash_strength_delta(); -+ rshash_state.stable_benefit = get_current_benefit(); -+ rshash_state.pre_direct = GO_DOWN; -+ break; -+ -+ case OBSCURE: -+ rshash_state.stable_point = hash_strength; -+ rshash_state.turn_point_down = hash_strength; -+ rshash_state.turn_point_up = hash_strength; -+ rshash_state.turn_benefit_down = get_current_benefit(); -+ rshash_state.turn_benefit_up = get_current_benefit(); -+ rshash_state.lookup_window_index = 0; -+ rshash_state.state = RSHASH_TRYDOWN; -+ dec_hash_strength(hash_strength_delta); -+ inc_hash_strength_delta(); -+ break; -+ -+ case STILL: -+ break; -+ default: -+ BUG(); -+ } -+ break; -+ -+ case RSHASH_TRYDOWN: -+ if (rshash_state.lookup_window_index++ % 5 == 0) -+ rshash_state.below_count = 0; -+ -+ if (get_current_benefit() < rshash_state.stable_benefit) -+ rshash_state.below_count++; -+ else if (get_current_benefit() > -+ rshash_state.turn_benefit_down) { -+ rshash_state.turn_point_down = hash_strength; -+ rshash_state.turn_benefit_down = get_current_benefit(); -+ } -+ -+ if (rshash_state.below_count >= 3 || -+ judge_rshash_direction() == GO_UP || -+ hash_strength == 1) { -+ hash_strength = rshash_state.stable_point; -+ hash_strength_delta = 0; -+ inc_hash_strength(hash_strength_delta); -+ inc_hash_strength_delta(); -+ rshash_state.lookup_window_index = 0; -+ rshash_state.state = RSHASH_TRYUP; -+ hash_strength_delta = 0; -+ } else { -+ dec_hash_strength(hash_strength_delta); -+ inc_hash_strength_delta(); -+ } -+ break; -+ -+ case RSHASH_TRYUP: -+ if (rshash_state.lookup_window_index++ % 5 == 0) -+ rshash_state.below_count = 0; -+ -+ if (get_current_benefit() < rshash_state.turn_benefit_down) -+ rshash_state.below_count++; -+ else if (get_current_benefit() > rshash_state.turn_benefit_up) { -+ rshash_state.turn_point_up = hash_strength; -+ rshash_state.turn_benefit_up = get_current_benefit(); -+ } -+ -+ if (rshash_state.below_count >= 3 || -+ judge_rshash_direction() == GO_DOWN || -+ hash_strength == HASH_STRENGTH_MAX) { -+ hash_strength = rshash_state.turn_benefit_up > -+ rshash_state.turn_benefit_down ? -+ rshash_state.turn_point_up : -+ rshash_state.turn_point_down; -+ -+ rshash_state.state = RSHASH_PRE_STILL; -+ } else { -+ inc_hash_strength(hash_strength_delta); -+ inc_hash_strength_delta(); -+ } -+ -+ break; -+ -+ case RSHASH_NEW: -+ case RSHASH_PRE_STILL: -+ rshash_state.stable_benefit = get_current_benefit(); -+ rshash_state.state = RSHASH_STILL; -+ hash_strength_delta = 0; -+ break; -+ default: -+ BUG(); -+ } -+ -+ /* rshash_neg = rshash_pos = 0; */ -+ reset_benefit(); -+ -+ if (prev_hash_strength != hash_strength) -+ stable_tree_delta_hash(prev_hash_strength); -+ -+ return prev_hash_strength != hash_strength; -+} -+ -+/** -+ * round_update_ladder() - The main function to do update of all the -+ * adjustments whenever a scan round is finished. -+ */ -+static noinline void round_update_ladder(void) -+{ -+ int i; -+ unsigned long dedup; -+ struct vma_slot *slot, *tmp_slot; -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) -+ uksm_scan_ladder[i].flags &= ~UKSM_RUNG_ROUND_FINISHED; -+ -+ list_for_each_entry_safe(slot, tmp_slot, &vma_slot_dedup, dedup_list) { -+ -+ /* slot may be rung_rm_slot() when mm exits */ -+ if (slot->snode) { -+ dedup = cal_dedup_ratio_old(slot); -+ if (dedup && dedup >= uksm_abundant_threshold) -+ vma_rung_up(slot); -+ } -+ -+ slot->pages_bemerged = 0; -+ slot->pages_cowed = 0; -+ -+ list_del_init(&slot->dedup_list); -+ } -+} -+ -+static void uksm_del_vma_slot(struct vma_slot *slot) -+{ -+ int i, j; -+ struct rmap_list_entry *entry; -+ -+ if (slot->snode) { -+ /* -+ * In case it just failed when entering the rung, it's not -+ * necessary. -+ */ -+ rung_rm_slot(slot); -+ } -+ -+ if (!list_empty(&slot->dedup_list)) -+ list_del(&slot->dedup_list); -+ -+ if (!slot->rmap_list_pool || !slot->pool_counts) { -+ /* In case it OOMed in uksm_vma_enter() */ -+ goto out; -+ } -+ -+ for (i = 0; i < slot->pool_size; i++) { -+ void *addr; -+ -+ if (!slot->rmap_list_pool[i]) -+ continue; -+ -+ addr = kmap(slot->rmap_list_pool[i]); -+ for (j = 0; j < PAGE_SIZE / sizeof(*entry); j++) { -+ entry = (struct rmap_list_entry *)addr + j; -+ if (is_addr(entry->addr)) -+ continue; -+ if (!entry->item) -+ continue; -+ -+ remove_rmap_item_from_tree(entry->item); -+ free_rmap_item(entry->item); -+ slot->pool_counts[i]--; -+ } -+ BUG_ON(slot->pool_counts[i]); -+ kunmap(slot->rmap_list_pool[i]); -+ __free_page(slot->rmap_list_pool[i]); -+ } -+ kfree(slot->rmap_list_pool); -+ kfree(slot->pool_counts); -+ -+out: -+ slot->rung = NULL; -+ if (slot->flags & UKSM_SLOT_IN_UKSM) { -+ BUG_ON(uksm_pages_total < slot->pages); -+ uksm_pages_total -= slot->pages; -+ } -+ -+ if (slot->fully_scanned_round == fully_scanned_round) -+ scanned_virtual_pages -= slot->pages; -+ else -+ scanned_virtual_pages -= slot->pages_scanned; -+ free_vma_slot(slot); -+} -+ -+ -+#define SPIN_LOCK_PERIOD 32 -+static struct vma_slot *cleanup_slots[SPIN_LOCK_PERIOD]; -+static inline void cleanup_vma_slots(void) -+{ -+ struct vma_slot *slot; -+ int i; -+ -+ i = 0; -+ spin_lock(&vma_slot_list_lock); -+ while (!list_empty(&vma_slot_del)) { -+ slot = list_entry(vma_slot_del.next, -+ struct vma_slot, slot_list); -+ list_del(&slot->slot_list); -+ cleanup_slots[i++] = slot; -+ if (i == SPIN_LOCK_PERIOD) { -+ spin_unlock(&vma_slot_list_lock); -+ while (--i >= 0) -+ uksm_del_vma_slot(cleanup_slots[i]); -+ i = 0; -+ spin_lock(&vma_slot_list_lock); -+ } -+ } -+ spin_unlock(&vma_slot_list_lock); -+ -+ while (--i >= 0) -+ uksm_del_vma_slot(cleanup_slots[i]); -+} -+ -+/* -+ * Expotional moving average formula -+ */ -+static inline unsigned long ema(unsigned long curr, unsigned long last_ema) -+{ -+ /* -+ * For a very high burst, even the ema cannot work well, a false very -+ * high per-page time estimation can result in feedback in very high -+ * overhead of context switch and rung update -- this will then lead -+ * to higher per-paper time, this may not converge. -+ * -+ * Instead, we try to approach this value in a binary manner. -+ */ -+ if (curr > last_ema * 10) -+ return last_ema * 2; -+ -+ return (EMA_ALPHA * curr + (100 - EMA_ALPHA) * last_ema) / 100; -+} -+ -+/* -+ * convert cpu ratio in 1/TIME_RATIO_SCALE configured by user to -+ * nanoseconds based on current uksm_sleep_jiffies. -+ */ -+static inline unsigned long cpu_ratio_to_nsec(unsigned int ratio) -+{ -+ return NSEC_PER_USEC * jiffies_to_usecs(uksm_sleep_jiffies) / -+ (TIME_RATIO_SCALE - ratio) * ratio; -+} -+ -+ -+static inline unsigned long rung_real_ratio(int cpu_time_ratio) -+{ -+ unsigned long ret; -+ -+ BUG_ON(!cpu_time_ratio); -+ -+ if (cpu_time_ratio > 0) -+ ret = cpu_time_ratio; -+ else -+ ret = (unsigned long)(-cpu_time_ratio) * -+ uksm_max_cpu_percentage / 100UL; -+ -+ return ret ? ret : 1; -+} -+ -+static noinline void uksm_calc_scan_pages(void) -+{ -+ struct scan_rung *ladder = uksm_scan_ladder; -+ unsigned long sleep_usecs, nsecs; -+ unsigned long ratio; -+ int i; -+ unsigned long per_page; -+ -+ if (uksm_ema_page_time > 100000 || -+ (((unsigned long) uksm_eval_round & (256UL - 1)) == 0UL)) -+ uksm_ema_page_time = UKSM_PAGE_TIME_DEFAULT; -+ -+ per_page = uksm_ema_page_time; -+ BUG_ON(!per_page); -+ -+ /* -+ * For every 8 eval round, we try to probe a uksm_sleep_jiffies value -+ * based on saved user input. -+ */ -+ if (((unsigned long) uksm_eval_round & (8UL - 1)) == 0UL) -+ uksm_sleep_jiffies = uksm_sleep_saved; -+ -+ /* We require a rung scan at least 1 page in a period. */ -+ nsecs = per_page; -+ ratio = rung_real_ratio(ladder[0].cpu_ratio); -+ if (cpu_ratio_to_nsec(ratio) < nsecs) { -+ sleep_usecs = nsecs * (TIME_RATIO_SCALE - ratio) / ratio -+ / NSEC_PER_USEC; -+ uksm_sleep_jiffies = usecs_to_jiffies(sleep_usecs) + 1; -+ } -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ ratio = rung_real_ratio(ladder[i].cpu_ratio); -+ ladder[i].pages_to_scan = cpu_ratio_to_nsec(ratio) / -+ per_page; -+ BUG_ON(!ladder[i].pages_to_scan); -+ uksm_calc_rung_step(&ladder[i], per_page, ratio); -+ } -+} -+ -+/* -+ * From the scan time of this round (ns) to next expected min sleep time -+ * (ms), be careful of the possible overflows. ratio is taken from -+ * rung_real_ratio() -+ */ -+static inline -+unsigned int scan_time_to_sleep(unsigned long long scan_time, unsigned long ratio) -+{ -+ scan_time >>= 20; /* to msec level now */ -+ BUG_ON(scan_time > (ULONG_MAX / TIME_RATIO_SCALE)); -+ -+ return (unsigned int) ((unsigned long) scan_time * -+ (TIME_RATIO_SCALE - ratio) / ratio); -+} -+ -+#define __round_mask(x, y) ((__typeof__(x))((y)-1)) -+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) -+ -+static void uksm_vma_enter(struct vma_slot **slots, unsigned long num) -+{ -+ struct scan_rung *rung; -+ -+ rung = &uksm_scan_ladder[0]; -+ rung_add_new_slots(rung, slots, num); -+} -+ -+static struct vma_slot *batch_slots[SLOT_TREE_NODE_STORE_SIZE]; -+ -+static void uksm_enter_all_slots(void) -+{ -+ struct vma_slot *slot; -+ unsigned long index; -+ struct list_head empty_vma_list; -+ int i; -+ -+ i = 0; -+ index = 0; -+ INIT_LIST_HEAD(&empty_vma_list); -+ -+ spin_lock(&vma_slot_list_lock); -+ while (!list_empty(&vma_slot_new)) { -+ slot = list_entry(vma_slot_new.next, -+ struct vma_slot, slot_list); -+ -+ if (!slot->vma->anon_vma) { -+ list_move(&slot->slot_list, &empty_vma_list); -+ } else if (vma_can_enter(slot->vma)) { -+ batch_slots[index++] = slot; -+ list_del_init(&slot->slot_list); -+ } else { -+ list_move(&slot->slot_list, &vma_slot_noadd); -+ } -+ -+ if (++i == SPIN_LOCK_PERIOD || -+ (index && !(index % SLOT_TREE_NODE_STORE_SIZE))) { -+ spin_unlock(&vma_slot_list_lock); -+ -+ if (index && !(index % SLOT_TREE_NODE_STORE_SIZE)) { -+ uksm_vma_enter(batch_slots, index); -+ index = 0; -+ } -+ i = 0; -+ cond_resched(); -+ spin_lock(&vma_slot_list_lock); -+ } -+ } -+ -+ list_splice(&empty_vma_list, &vma_slot_new); -+ -+ spin_unlock(&vma_slot_list_lock); -+ -+ if (index) -+ uksm_vma_enter(batch_slots, index); -+ -+} -+ -+static inline int rung_round_finished(struct scan_rung *rung) -+{ -+ return rung->flags & UKSM_RUNG_ROUND_FINISHED; -+} -+ -+static inline void judge_slot(struct vma_slot *slot) -+{ -+ struct scan_rung *rung = slot->rung; -+ unsigned long dedup; -+ int deleted; -+ -+ dedup = cal_dedup_ratio(slot); -+ if (vma_fully_scanned(slot) && uksm_thrash_threshold) -+ deleted = vma_rung_enter(slot, &uksm_scan_ladder[0]); -+ else if (dedup && dedup >= uksm_abundant_threshold) -+ deleted = vma_rung_up(slot); -+ else -+ deleted = vma_rung_down(slot); -+ -+ slot->pages_merged = 0; -+ slot->pages_cowed = 0; -+ slot->this_sampled = 0; -+ -+ if (vma_fully_scanned(slot)) -+ slot->pages_scanned = 0; -+ -+ slot->last_scanned = slot->pages_scanned; -+ -+ /* If its deleted in above, then rung was already advanced. */ -+ if (!deleted) -+ advance_current_scan(rung); -+} -+ -+ -+static inline int hash_round_finished(void) -+{ -+ if (scanned_virtual_pages > (uksm_pages_total >> 2)) { -+ scanned_virtual_pages = 0; -+ if (uksm_pages_scanned) -+ fully_scanned_round++; -+ -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ -+#define UKSM_MMSEM_BATCH 5 -+#define BUSY_RETRY 100 -+ -+/** -+ * uksm_do_scan() - the main worker function. -+ */ -+static noinline void uksm_do_scan(void) -+{ -+ struct vma_slot *slot, *iter; -+ struct mm_struct *busy_mm; -+ unsigned char round_finished, all_rungs_emtpy; -+ int i, err, mmsem_batch; -+ unsigned long pcost; -+ long long delta_exec; -+ unsigned long vpages, max_cpu_ratio; -+ unsigned long long start_time, end_time, scan_time; -+ unsigned int expected_jiffies; -+ -+ might_sleep(); -+ -+ vpages = 0; -+ -+ start_time = task_sched_runtime(current); -+ max_cpu_ratio = 0; -+ mmsem_batch = 0; -+ -+ for (i = 0; i < SCAN_LADDER_SIZE;) { -+ struct scan_rung *rung = &uksm_scan_ladder[i]; -+ unsigned long ratio; -+ int busy_retry; -+ -+ if (!rung->pages_to_scan) { -+ i++; -+ continue; -+ } -+ -+ if (!rung->vma_root.num) { -+ rung->pages_to_scan = 0; -+ i++; -+ continue; -+ } -+ -+ ratio = rung_real_ratio(rung->cpu_ratio); -+ if (ratio > max_cpu_ratio) -+ max_cpu_ratio = ratio; -+ -+ busy_retry = BUSY_RETRY; -+ /* -+ * Do not consider rung_round_finished() here, just used up the -+ * rung->pages_to_scan quota. -+ */ -+ while (rung->pages_to_scan && rung->vma_root.num && -+ likely(!freezing(current))) { -+ int reset = 0; -+ -+ slot = rung->current_scan; -+ -+ BUG_ON(vma_fully_scanned(slot)); -+ -+ if (mmsem_batch) -+ err = 0; -+ else -+ err = try_down_read_slot_mmap_sem(slot); -+ -+ if (err == -ENOENT) { -+rm_slot: -+ rung_rm_slot(slot); -+ continue; -+ } -+ -+ busy_mm = slot->mm; -+ -+ if (err == -EBUSY) { -+ /* skip other vmas on the same mm */ -+ do { -+ reset = advance_current_scan(rung); -+ iter = rung->current_scan; -+ busy_retry--; -+ if (iter->vma->vm_mm != busy_mm || -+ !busy_retry || reset) -+ break; -+ } while (1); -+ -+ if (iter->vma->vm_mm != busy_mm) { -+ continue; -+ } else { -+ /* scan round finsished */ -+ break; -+ } -+ } -+ -+ BUG_ON(!vma_can_enter(slot->vma)); -+ if (uksm_test_exit(slot->vma->vm_mm)) { -+ mmsem_batch = 0; -+ mmap_read_unlock(slot->vma->vm_mm); -+ goto rm_slot; -+ } -+ -+ if (mmsem_batch) -+ mmsem_batch--; -+ else -+ mmsem_batch = UKSM_MMSEM_BATCH; -+ -+ /* Ok, we have take the mmap_sem, ready to scan */ -+ scan_vma_one_page(slot); -+ rung->pages_to_scan--; -+ vpages++; -+ -+ if (rung->current_offset + rung->step > slot->pages - 1 -+ || vma_fully_scanned(slot)) { -+ mmap_read_unlock(slot->vma->vm_mm); -+ judge_slot(slot); -+ mmsem_batch = 0; -+ } else { -+ rung->current_offset += rung->step; -+ if (!mmsem_batch) -+ mmap_read_unlock(slot->vma->vm_mm); -+ } -+ -+ busy_retry = BUSY_RETRY; -+ cond_resched(); -+ } -+ -+ if (mmsem_batch) { -+ mmap_read_unlock(slot->vma->vm_mm); -+ mmsem_batch = 0; -+ } -+ -+ if (freezing(current)) -+ break; -+ -+ cond_resched(); -+ } -+ end_time = task_sched_runtime(current); -+ delta_exec = end_time - start_time; -+ -+ if (freezing(current)) -+ return; -+ -+ cleanup_vma_slots(); -+ uksm_enter_all_slots(); -+ -+ round_finished = 1; -+ all_rungs_emtpy = 1; -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ struct scan_rung *rung = &uksm_scan_ladder[i]; -+ -+ if (rung->vma_root.num) { -+ all_rungs_emtpy = 0; -+ if (!rung_round_finished(rung)) -+ round_finished = 0; -+ } -+ } -+ -+ if (all_rungs_emtpy) -+ round_finished = 0; -+ -+ if (round_finished) { -+ round_update_ladder(); -+ uksm_eval_round++; -+ -+ if (hash_round_finished() && rshash_adjust()) { -+ /* Reset the unstable root iff hash strength changed */ -+ uksm_hash_round++; -+ root_unstable_tree = RB_ROOT; -+ free_all_tree_nodes(&unstable_tree_node_list); -+ } -+ -+ /* -+ * A number of pages can hang around indefinitely on per-cpu -+ * pagevecs, raised page count preventing write_protect_page -+ * from merging them. Though it doesn't really matter much, -+ * it is puzzling to see some stuck in pages_volatile until -+ * other activity jostles them out, and they also prevented -+ * LTP's KSM test from succeeding deterministically; so drain -+ * them here (here rather than on entry to uksm_do_scan(), -+ * so we don't IPI too often when pages_to_scan is set low). -+ */ -+ lru_add_drain_all(); -+ } -+ -+ -+ if (vpages && delta_exec > 0) { -+ pcost = (unsigned long) delta_exec / vpages; -+ if (likely(uksm_ema_page_time)) -+ uksm_ema_page_time = ema(pcost, uksm_ema_page_time); -+ else -+ uksm_ema_page_time = pcost; -+ } -+ -+ uksm_calc_scan_pages(); -+ uksm_sleep_real = uksm_sleep_jiffies; -+ /* in case of radical cpu bursts, apply the upper bound */ -+ end_time = task_sched_runtime(current); -+ if (max_cpu_ratio && end_time > start_time) { -+ scan_time = end_time - start_time; -+ expected_jiffies = msecs_to_jiffies( -+ scan_time_to_sleep(scan_time, max_cpu_ratio)); -+ -+ if (expected_jiffies > uksm_sleep_real) -+ uksm_sleep_real = expected_jiffies; -+ -+ /* We have a 1 second up bound for responsiveness. */ -+ if (jiffies_to_msecs(uksm_sleep_real) > MSEC_PER_SEC) -+ uksm_sleep_real = msecs_to_jiffies(1000); -+ } -+ -+ return; -+} -+ -+static int ksmd_should_run(void) -+{ -+ return uksm_run & UKSM_RUN_MERGE; -+} -+ -+static int uksm_scan_thread(void *nothing) -+{ -+ set_freezable(); -+ set_user_nice(current, 5); -+ -+ while (!kthread_should_stop()) { -+ mutex_lock(&uksm_thread_mutex); -+ if (ksmd_should_run()) -+ uksm_do_scan(); -+ mutex_unlock(&uksm_thread_mutex); -+ -+ try_to_freeze(); -+ -+ if (ksmd_should_run()) { -+ schedule_timeout_interruptible(uksm_sleep_real); -+ uksm_sleep_times++; -+ } else { -+ wait_event_freezable(uksm_thread_wait, -+ ksmd_should_run() || kthread_should_stop()); -+ } -+ } -+ return 0; -+} -+ -+void rmap_walk_ksm(struct page *page, struct rmap_walk_control *rwc) -+{ -+ struct stable_node *stable_node; -+ struct node_vma *node_vma; -+ struct rmap_item *rmap_item; -+ int search_new_forks = 0; -+ unsigned long address; -+ -+ VM_BUG_ON_PAGE(!PageKsm(page), page); -+ VM_BUG_ON_PAGE(!PageLocked(page), page); -+ -+ stable_node = page_stable_node(page); -+ if (!stable_node) -+ return; -+again: -+ hlist_for_each_entry(node_vma, &stable_node->hlist, hlist) { -+ hlist_for_each_entry(rmap_item, &node_vma->rmap_hlist, hlist) { -+ struct anon_vma *anon_vma = rmap_item->anon_vma; -+ struct anon_vma_chain *vmac; -+ struct vm_area_struct *vma; -+ -+ cond_resched(); -+ anon_vma_lock_read(anon_vma); -+ anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, -+ 0, ULONG_MAX) { -+ cond_resched(); -+ vma = vmac->vma; -+ address = get_rmap_addr(rmap_item); -+ -+ if (address < vma->vm_start || -+ address >= vma->vm_end) -+ continue; -+ -+ if ((rmap_item->slot->vma == vma) == -+ search_new_forks) -+ continue; -+ -+ if (rwc->invalid_vma && rwc->invalid_vma(vma, rwc->arg)) -+ continue; -+ -+ if (!rwc->rmap_one(page, vma, address, rwc->arg)) { -+ anon_vma_unlock_read(anon_vma); -+ return; -+ } -+ -+ if (rwc->done && rwc->done(page)) { -+ anon_vma_unlock_read(anon_vma); -+ return; -+ } -+ } -+ anon_vma_unlock_read(anon_vma); -+ } -+ } -+ if (!search_new_forks++) -+ goto again; -+} -+ -+#ifdef CONFIG_MIGRATION -+/* Common ksm interface but may be specific to uksm */ -+void ksm_migrate_page(struct page *newpage, struct page *oldpage) -+{ -+ struct stable_node *stable_node; -+ -+ VM_BUG_ON_PAGE(!PageLocked(oldpage), oldpage); -+ VM_BUG_ON_PAGE(!PageLocked(newpage), newpage); -+ VM_BUG_ON(newpage->mapping != oldpage->mapping); -+ -+ stable_node = page_stable_node(newpage); -+ if (stable_node) { -+ VM_BUG_ON(stable_node->kpfn != page_to_pfn(oldpage)); -+ stable_node->kpfn = page_to_pfn(newpage); -+ /* -+ * newpage->mapping was set in advance; now we need smp_wmb() -+ * to make sure that the new stable_node->kpfn is visible -+ * to get_ksm_page() before it can see that oldpage->mapping -+ * has gone stale (or that PageSwapCache has been cleared). -+ */ -+ smp_wmb(); -+ set_page_stable_node(oldpage, NULL); -+ } -+} -+#endif /* CONFIG_MIGRATION */ -+ -+#ifdef CONFIG_MEMORY_HOTREMOVE -+static struct stable_node *uksm_check_stable_tree(unsigned long start_pfn, -+ unsigned long end_pfn) -+{ -+ struct rb_node *node; -+ -+ for (node = rb_first(root_stable_treep); node; node = rb_next(node)) { -+ struct stable_node *stable_node; -+ -+ stable_node = rb_entry(node, struct stable_node, node); -+ if (stable_node->kpfn >= start_pfn && -+ stable_node->kpfn < end_pfn) -+ return stable_node; -+ } -+ return NULL; -+} -+ -+static int uksm_memory_callback(struct notifier_block *self, -+ unsigned long action, void *arg) -+{ -+ struct memory_notify *mn = arg; -+ struct stable_node *stable_node; -+ -+ switch (action) { -+ case MEM_GOING_OFFLINE: -+ /* -+ * Keep it very simple for now: just lock out ksmd and -+ * MADV_UNMERGEABLE while any memory is going offline. -+ * mutex_lock_nested() is necessary because lockdep was alarmed -+ * that here we take uksm_thread_mutex inside notifier chain -+ * mutex, and later take notifier chain mutex inside -+ * uksm_thread_mutex to unlock it. But that's safe because both -+ * are inside mem_hotplug_mutex. -+ */ -+ mutex_lock_nested(&uksm_thread_mutex, SINGLE_DEPTH_NESTING); -+ break; -+ -+ case MEM_OFFLINE: -+ /* -+ * Most of the work is done by page migration; but there might -+ * be a few stable_nodes left over, still pointing to struct -+ * pages which have been offlined: prune those from the tree. -+ */ -+ while ((stable_node = uksm_check_stable_tree(mn->start_pfn, -+ mn->start_pfn + mn->nr_pages)) != NULL) -+ remove_node_from_stable_tree(stable_node, 1, 1); -+ /* fallthrough */ -+ -+ case MEM_CANCEL_OFFLINE: -+ mutex_unlock(&uksm_thread_mutex); -+ break; -+ } -+ return NOTIFY_OK; -+} -+#endif /* CONFIG_MEMORY_HOTREMOVE */ -+ -+#ifdef CONFIG_SYSFS -+/* -+ * This all compiles without CONFIG_SYSFS, but is a waste of space. -+ */ -+ -+#define UKSM_ATTR_RO(_name) \ -+ static struct kobj_attribute _name##_attr = __ATTR_RO(_name) -+#define UKSM_ATTR(_name) \ -+ static struct kobj_attribute _name##_attr = \ -+ __ATTR(_name, 0644, _name##_show, _name##_store) -+ -+static ssize_t max_cpu_percentage_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%u\n", uksm_max_cpu_percentage); -+} -+ -+static ssize_t max_cpu_percentage_store(struct kobject *kobj, -+ struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ unsigned long max_cpu_percentage; -+ int err; -+ -+ err = kstrtoul(buf, 10, &max_cpu_percentage); -+ if (err || max_cpu_percentage > 100) -+ return -EINVAL; -+ -+ if (max_cpu_percentage == 100) -+ max_cpu_percentage = 99; -+ else if (max_cpu_percentage < 10) -+ max_cpu_percentage = 10; -+ -+ uksm_max_cpu_percentage = max_cpu_percentage; -+ -+ return count; -+} -+UKSM_ATTR(max_cpu_percentage); -+ -+static ssize_t sleep_millisecs_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%u\n", jiffies_to_msecs(uksm_sleep_jiffies)); -+} -+ -+static ssize_t sleep_millisecs_store(struct kobject *kobj, -+ struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ unsigned long msecs; -+ int err; -+ -+ err = kstrtoul(buf, 10, &msecs); -+ if (err || msecs > MSEC_PER_SEC) -+ return -EINVAL; -+ -+ uksm_sleep_jiffies = msecs_to_jiffies(msecs); -+ uksm_sleep_saved = uksm_sleep_jiffies; -+ -+ return count; -+} -+UKSM_ATTR(sleep_millisecs); -+ -+ -+static ssize_t cpu_governor_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ int n = sizeof(uksm_cpu_governor_str) / sizeof(char *); -+ int i; -+ -+ buf[0] = '\0'; -+ for (i = 0; i < n ; i++) { -+ if (uksm_cpu_governor == i) -+ strcat(buf, "["); -+ -+ strcat(buf, uksm_cpu_governor_str[i]); -+ -+ if (uksm_cpu_governor == i) -+ strcat(buf, "]"); -+ -+ strcat(buf, " "); -+ } -+ strcat(buf, "\n"); -+ -+ return strlen(buf); -+} -+ -+static inline void init_performance_values(void) -+{ -+ int i; -+ struct scan_rung *rung; -+ struct uksm_cpu_preset_s *preset = uksm_cpu_preset + uksm_cpu_governor; -+ -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ rung = uksm_scan_ladder + i; -+ rung->cpu_ratio = preset->cpu_ratio[i]; -+ rung->cover_msecs = preset->cover_msecs[i]; -+ } -+ -+ uksm_max_cpu_percentage = preset->max_cpu; -+} -+ -+static ssize_t cpu_governor_store(struct kobject *kobj, -+ struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int n = sizeof(uksm_cpu_governor_str) / sizeof(char *); -+ -+ for (n--; n >= 0 ; n--) { -+ if (!strncmp(buf, uksm_cpu_governor_str[n], -+ strlen(uksm_cpu_governor_str[n]))) -+ break; -+ } -+ -+ if (n < 0) -+ return -EINVAL; -+ else -+ uksm_cpu_governor = n; -+ -+ init_performance_values(); -+ -+ return count; -+} -+UKSM_ATTR(cpu_governor); -+ -+static ssize_t run_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ return sprintf(buf, "%u\n", uksm_run); -+} -+ -+static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int err; -+ unsigned long flags; -+ -+ err = kstrtoul(buf, 10, &flags); -+ if (err || flags > UINT_MAX) -+ return -EINVAL; -+ if (flags > UKSM_RUN_MERGE) -+ return -EINVAL; -+ -+ mutex_lock(&uksm_thread_mutex); -+ if (uksm_run != flags) -+ uksm_run = flags; -+ mutex_unlock(&uksm_thread_mutex); -+ -+ if (flags & UKSM_RUN_MERGE) -+ wake_up_interruptible(&uksm_thread_wait); -+ -+ return count; -+} -+UKSM_ATTR(run); -+ -+static ssize_t abundant_threshold_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%u\n", uksm_abundant_threshold); -+} -+ -+static ssize_t abundant_threshold_store(struct kobject *kobj, -+ struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int err; -+ unsigned long flags; -+ -+ err = kstrtoul(buf, 10, &flags); -+ if (err || flags > 99) -+ return -EINVAL; -+ -+ uksm_abundant_threshold = flags; -+ -+ return count; -+} -+UKSM_ATTR(abundant_threshold); -+ -+static ssize_t thrash_threshold_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%u\n", uksm_thrash_threshold); -+} -+ -+static ssize_t thrash_threshold_store(struct kobject *kobj, -+ struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int err; -+ unsigned long flags; -+ -+ err = kstrtoul(buf, 10, &flags); -+ if (err || flags > 99) -+ return -EINVAL; -+ -+ uksm_thrash_threshold = flags; -+ -+ return count; -+} -+UKSM_ATTR(thrash_threshold); -+ -+static ssize_t cpu_ratios_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ int i, size; -+ struct scan_rung *rung; -+ char *p = buf; -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ rung = &uksm_scan_ladder[i]; -+ -+ if (rung->cpu_ratio > 0) -+ size = sprintf(p, "%d ", rung->cpu_ratio); -+ else -+ size = sprintf(p, "MAX/%d ", -+ TIME_RATIO_SCALE / -rung->cpu_ratio); -+ -+ p += size; -+ } -+ -+ *p++ = '\n'; -+ *p = '\0'; -+ -+ return p - buf; -+} -+ -+static ssize_t cpu_ratios_store(struct kobject *kobj, -+ struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int i, cpuratios[SCAN_LADDER_SIZE], err; -+ unsigned long value; -+ struct scan_rung *rung; -+ char *p, *end = NULL; -+ -+ p = kzalloc(count, GFP_KERNEL); -+ if (!p) -+ return -ENOMEM; -+ -+ memcpy(p, buf, count); -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ if (i != SCAN_LADDER_SIZE - 1) { -+ end = strchr(p, ' '); -+ if (!end) -+ return -EINVAL; -+ -+ *end = '\0'; -+ } -+ -+ if (strstr(p, "MAX/")) { -+ p = strchr(p, '/') + 1; -+ err = kstrtoul(p, 10, &value); -+ if (err || value > TIME_RATIO_SCALE || !value) -+ return -EINVAL; -+ -+ cpuratios[i] = -(int) (TIME_RATIO_SCALE / value); -+ } else { -+ err = kstrtoul(p, 10, &value); -+ if (err || value > TIME_RATIO_SCALE || !value) -+ return -EINVAL; -+ -+ cpuratios[i] = value; -+ } -+ -+ p = end + 1; -+ } -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ rung = &uksm_scan_ladder[i]; -+ -+ rung->cpu_ratio = cpuratios[i]; -+ } -+ -+ return count; -+} -+UKSM_ATTR(cpu_ratios); -+ -+static ssize_t eval_intervals_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ int i, size; -+ struct scan_rung *rung; -+ char *p = buf; -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ rung = &uksm_scan_ladder[i]; -+ size = sprintf(p, "%u ", rung->cover_msecs); -+ p += size; -+ } -+ -+ *p++ = '\n'; -+ *p = '\0'; -+ -+ return p - buf; -+} -+ -+static ssize_t eval_intervals_store(struct kobject *kobj, -+ struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ int i, err; -+ unsigned long values[SCAN_LADDER_SIZE]; -+ struct scan_rung *rung; -+ char *p, *end = NULL; -+ ssize_t ret = count; -+ -+ p = kzalloc(count + 2, GFP_KERNEL); -+ if (!p) -+ return -ENOMEM; -+ -+ memcpy(p, buf, count); -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ if (i != SCAN_LADDER_SIZE - 1) { -+ end = strchr(p, ' '); -+ if (!end) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ *end = '\0'; -+ } -+ -+ err = kstrtoul(p, 10, &values[i]); -+ if (err) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ p = end + 1; -+ } -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ rung = &uksm_scan_ladder[i]; -+ -+ rung->cover_msecs = values[i]; -+ } -+ -+out: -+ kfree(p); -+ return ret; -+} -+UKSM_ATTR(eval_intervals); -+ -+static ssize_t ema_per_page_time_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%lu\n", uksm_ema_page_time); -+} -+UKSM_ATTR_RO(ema_per_page_time); -+ -+static ssize_t pages_shared_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%lu\n", uksm_pages_shared); -+} -+UKSM_ATTR_RO(pages_shared); -+ -+static ssize_t pages_sharing_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%lu\n", uksm_pages_sharing); -+} -+UKSM_ATTR_RO(pages_sharing); -+ -+static ssize_t pages_unshared_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%lu\n", uksm_pages_unshared); -+} -+UKSM_ATTR_RO(pages_unshared); -+ -+static ssize_t full_scans_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%llu\n", fully_scanned_round); -+} -+UKSM_ATTR_RO(full_scans); -+ -+static ssize_t pages_scanned_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ unsigned long base = 0; -+ u64 delta, ret; -+ -+ if (pages_scanned_stored) { -+ base = pages_scanned_base; -+ ret = pages_scanned_stored; -+ delta = uksm_pages_scanned >> base; -+ if (CAN_OVERFLOW_U64(ret, delta)) { -+ ret >>= 1; -+ delta >>= 1; -+ base++; -+ ret += delta; -+ } -+ } else { -+ ret = uksm_pages_scanned; -+ } -+ -+ while (ret > ULONG_MAX) { -+ ret >>= 1; -+ base++; -+ } -+ -+ if (base) -+ return sprintf(buf, "%lu * 2^%lu\n", (unsigned long)ret, base); -+ else -+ return sprintf(buf, "%lu\n", (unsigned long)ret); -+} -+UKSM_ATTR_RO(pages_scanned); -+ -+static ssize_t hash_strength_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%lu\n", hash_strength); -+} -+UKSM_ATTR_RO(hash_strength); -+ -+static ssize_t sleep_times_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%llu\n", uksm_sleep_times); -+} -+UKSM_ATTR_RO(sleep_times); -+ -+ -+static struct attribute *uksm_attrs[] = { -+ &max_cpu_percentage_attr.attr, -+ &sleep_millisecs_attr.attr, -+ &cpu_governor_attr.attr, -+ &run_attr.attr, -+ &ema_per_page_time_attr.attr, -+ &pages_shared_attr.attr, -+ &pages_sharing_attr.attr, -+ &pages_unshared_attr.attr, -+ &full_scans_attr.attr, -+ &pages_scanned_attr.attr, -+ &hash_strength_attr.attr, -+ &sleep_times_attr.attr, -+ &thrash_threshold_attr.attr, -+ &abundant_threshold_attr.attr, -+ &cpu_ratios_attr.attr, -+ &eval_intervals_attr.attr, -+ NULL, -+}; -+ -+static struct attribute_group uksm_attr_group = { -+ .attrs = uksm_attrs, -+ .name = "uksm", -+}; -+#endif /* CONFIG_SYSFS */ -+ -+static inline void init_scan_ladder(void) -+{ -+ int i; -+ struct scan_rung *rung; -+ -+ for (i = 0; i < SCAN_LADDER_SIZE; i++) { -+ rung = uksm_scan_ladder + i; -+ slot_tree_init_root(&rung->vma_root); -+ } -+ -+ init_performance_values(); -+ uksm_calc_scan_pages(); -+} -+ -+static inline int cal_positive_negative_costs(void) -+{ -+ struct page *p1, *p2; -+ unsigned char *addr1, *addr2; -+ unsigned long i, time_start, hash_cost; -+ unsigned long loopnum = 0; -+ -+ /*IMPORTANT: volatile is needed to prevent over-optimization by gcc. */ -+ volatile u32 hash; -+ volatile int ret; -+ -+ p1 = alloc_page(GFP_KERNEL); -+ if (!p1) -+ return -ENOMEM; -+ -+ p2 = alloc_page(GFP_KERNEL); -+ if (!p2) -+ return -ENOMEM; -+ -+ addr1 = kmap_atomic(p1); -+ addr2 = kmap_atomic(p2); -+ memset(addr1, prandom_u32(), PAGE_SIZE); -+ memcpy(addr2, addr1, PAGE_SIZE); -+ -+ /* make sure that the two pages differ in last byte */ -+ addr2[PAGE_SIZE-1] = ~addr2[PAGE_SIZE-1]; -+ kunmap_atomic(addr2); -+ kunmap_atomic(addr1); -+ -+ time_start = jiffies; -+ while (jiffies - time_start < 100) { -+ for (i = 0; i < 100; i++) -+ hash = page_hash(p1, HASH_STRENGTH_FULL, 0); -+ loopnum += 100; -+ } -+ hash_cost = (jiffies - time_start); -+ -+ time_start = jiffies; -+ for (i = 0; i < loopnum; i++) -+ ret = pages_identical_with_cost(p1, p2); -+ memcmp_cost = HASH_STRENGTH_FULL * (jiffies - time_start); -+ memcmp_cost /= hash_cost; -+ pr_info("UKSM: relative memcmp_cost = %lu " -+ "hash=%u cmp_ret=%d.\n", -+ memcmp_cost, hash, ret); -+ -+ __free_page(p1); -+ __free_page(p2); -+ return 0; -+} -+ -+static int init_zeropage_hash_table(void) -+{ -+ struct page *page; -+ char *addr; -+ int i; -+ -+ page = alloc_page(GFP_KERNEL); -+ if (!page) -+ return -ENOMEM; -+ -+ addr = kmap_atomic(page); -+ memset(addr, 0, PAGE_SIZE); -+ kunmap_atomic(addr); -+ -+ zero_hash_table = kmalloc_array(HASH_STRENGTH_MAX, sizeof(u32), -+ GFP_KERNEL); -+ if (!zero_hash_table) -+ return -ENOMEM; -+ -+ for (i = 0; i < HASH_STRENGTH_MAX; i++) -+ zero_hash_table[i] = page_hash(page, i, 0); -+ -+ __free_page(page); -+ -+ return 0; -+} -+ -+static inline int init_random_sampling(void) -+{ -+ unsigned long i; -+ -+ random_nums = kmalloc(PAGE_SIZE, GFP_KERNEL); -+ if (!random_nums) -+ return -ENOMEM; -+ -+ for (i = 0; i < HASH_STRENGTH_FULL; i++) -+ random_nums[i] = i; -+ -+ for (i = 0; i < HASH_STRENGTH_FULL; i++) { -+ unsigned long rand_range, swap_index, tmp; -+ -+ rand_range = HASH_STRENGTH_FULL - i; -+ swap_index = i + prandom_u32() % rand_range; -+ tmp = random_nums[i]; -+ random_nums[i] = random_nums[swap_index]; -+ random_nums[swap_index] = tmp; -+ } -+ -+ rshash_state.state = RSHASH_NEW; -+ rshash_state.below_count = 0; -+ rshash_state.lookup_window_index = 0; -+ -+ return cal_positive_negative_costs(); -+} -+ -+static int __init uksm_slab_init(void) -+{ -+ rmap_item_cache = UKSM_KMEM_CACHE(rmap_item, 0); -+ if (!rmap_item_cache) -+ goto out; -+ -+ stable_node_cache = UKSM_KMEM_CACHE(stable_node, 0); -+ if (!stable_node_cache) -+ goto out_free1; -+ -+ node_vma_cache = UKSM_KMEM_CACHE(node_vma, 0); -+ if (!node_vma_cache) -+ goto out_free2; -+ -+ vma_slot_cache = UKSM_KMEM_CACHE(vma_slot, 0); -+ if (!vma_slot_cache) -+ goto out_free3; -+ -+ tree_node_cache = UKSM_KMEM_CACHE(tree_node, 0); -+ if (!tree_node_cache) -+ goto out_free4; -+ -+ return 0; -+ -+out_free4: -+ kmem_cache_destroy(vma_slot_cache); -+out_free3: -+ kmem_cache_destroy(node_vma_cache); -+out_free2: -+ kmem_cache_destroy(stable_node_cache); -+out_free1: -+ kmem_cache_destroy(rmap_item_cache); -+out: -+ return -ENOMEM; -+} -+ -+static void __init uksm_slab_free(void) -+{ -+ kmem_cache_destroy(stable_node_cache); -+ kmem_cache_destroy(rmap_item_cache); -+ kmem_cache_destroy(node_vma_cache); -+ kmem_cache_destroy(vma_slot_cache); -+ kmem_cache_destroy(tree_node_cache); -+} -+ -+/* Common interface to ksm, different to it. */ -+int ksm_madvise(struct vm_area_struct *vma, unsigned long start, -+ unsigned long end, int advice, unsigned long *vm_flags) -+{ -+ int err; -+ -+ switch (advice) { -+ case MADV_MERGEABLE: -+ return 0; /* just ignore the advice */ -+ -+ case MADV_UNMERGEABLE: -+ if (!(*vm_flags & VM_MERGEABLE) || !uksm_flags_can_scan(*vm_flags)) -+ return 0; /* just ignore the advice */ -+ -+ if (vma->anon_vma) { -+ err = unmerge_uksm_pages(vma, start, end); -+ if (err) -+ return err; -+ } -+ -+ uksm_remove_vma(vma); -+ *vm_flags &= ~VM_MERGEABLE; -+ break; -+ } -+ -+ return 0; -+} -+ -+/* Common interface to ksm, actually the same. */ -+struct page *ksm_might_need_to_copy(struct page *page, -+ struct vm_area_struct *vma, unsigned long address) -+{ -+ struct anon_vma *anon_vma = page_anon_vma(page); -+ struct page *new_page; -+ -+ if (PageKsm(page)) { -+ if (page_stable_node(page)) -+ return page; /* no need to copy it */ -+ } else if (!anon_vma) { -+ return page; /* no need to copy it */ -+ } else if (anon_vma->root == vma->anon_vma->root && -+ page->index == linear_page_index(vma, address)) { -+ return page; /* still no need to copy it */ -+ } -+ if (!PageUptodate(page)) -+ return page; /* let do_swap_page report the error */ -+ -+ new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address); -+ if (new_page) { -+ copy_user_highpage(new_page, page, address, vma); -+ -+ SetPageDirty(new_page); -+ __SetPageUptodate(new_page); -+ __SetPageLocked(new_page); -+ } -+ -+ return new_page; -+} -+ -+/* Copied from mm/ksm.c and required from 5.1 */ -+bool reuse_ksm_page(struct page *page, -+ struct vm_area_struct *vma, -+ unsigned long address) -+{ -+#ifdef CONFIG_DEBUG_VM -+ if (WARN_ON(is_zero_pfn(page_to_pfn(page))) || -+ WARN_ON(!page_mapped(page)) || -+ WARN_ON(!PageLocked(page))) { -+ dump_page(page, "reuse_ksm_page"); -+ return false; -+ } -+#endif -+ -+ if (PageSwapCache(page) || !page_stable_node(page)) -+ return false; -+ /* Prohibit parallel get_ksm_page() */ -+ if (!page_ref_freeze(page, 1)) -+ return false; -+ -+ page_move_anon_rmap(page, vma); -+ page->index = linear_page_index(vma, address); -+ page_ref_unfreeze(page, 1); -+ -+ return true; -+} -+ -+static int __init uksm_init(void) -+{ -+ struct task_struct *uksm_thread; -+ int err; -+ -+ uksm_sleep_jiffies = msecs_to_jiffies(100); -+ uksm_sleep_saved = uksm_sleep_jiffies; -+ -+ slot_tree_init(); -+ init_scan_ladder(); -+ -+ -+ err = init_random_sampling(); -+ if (err) -+ goto out_free2; -+ -+ err = uksm_slab_init(); -+ if (err) -+ goto out_free1; -+ -+ err = init_zeropage_hash_table(); -+ if (err) -+ goto out_free0; -+ -+ uksm_thread = kthread_run(uksm_scan_thread, NULL, "uksmd"); -+ if (IS_ERR(uksm_thread)) { -+ pr_err("uksm: creating kthread failed\n"); -+ err = PTR_ERR(uksm_thread); -+ goto out_free; -+ } -+ -+#ifdef CONFIG_SYSFS -+ err = sysfs_create_group(mm_kobj, &uksm_attr_group); -+ if (err) { -+ pr_err("uksm: register sysfs failed\n"); -+ kthread_stop(uksm_thread); -+ goto out_free; -+ } -+#else -+ uksm_run = UKSM_RUN_MERGE; /* no way for user to start it */ -+ -+#endif /* CONFIG_SYSFS */ -+ -+#ifdef CONFIG_MEMORY_HOTREMOVE -+ /* -+ * Choose a high priority since the callback takes uksm_thread_mutex: -+ * later callbacks could only be taking locks which nest within that. -+ */ -+ hotplug_memory_notifier(uksm_memory_callback, 100); -+#endif -+ return 0; -+ -+out_free: -+ kfree(zero_hash_table); -+out_free0: -+ uksm_slab_free(); -+out_free1: -+ kfree(random_nums); -+out_free2: -+ kfree(uksm_scan_ladder); -+ return err; -+} -+ -+#ifdef MODULE -+subsys_initcall(ksm_init); -+#else -+late_initcall(uksm_init); -+#endif -+ -diff --git a/mm/vmstat.c b/mm/vmstat.c -index 3fb23a21f6dd..ac0c5fccf749 100644 ---- a/mm/vmstat.c -+++ b/mm/vmstat.c -@@ -1173,6 +1173,9 @@ const char * const vmstat_text[] = { - "nr_foll_pin_acquired", - "nr_foll_pin_released", - -+#ifdef CONFIG_UKSM -+ "nr_uksm_zero_pages", -+#endif - /* enum writeback_stat_item counters */ - "nr_dirty_threshold", - "nr_dirty_background_threshold", diff --git a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4502_futex-wait-multiple.patch b/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4502_futex-wait-multiple.patch deleted file mode 100644 index a7860f473..000000000 --- a/profiles/templates/3.6/6_ac_install_patch/sys-kernel/calculate-sources/5.8/4502_futex-wait-multiple.patch +++ /dev/null @@ -1,326 +0,0 @@ -# Calculate format=diff merge(sys-kernel/calculate-sources[fsync])!= - -Squashed futex-wait-multiple patchset onto stable release v5.2.1 -https://gitlab.collabora.com/krisman/linux/commits/futex-wait-multiple-master - -diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h -index a89eb0accd5e..c34e52e0f787 100644 ---- a/include/uapi/linux/futex.h -+++ b/include/uapi/linux/futex.h -@@ -21,6 +21,7 @@ - #define FUTEX_WAKE_BITSET 10 - #define FUTEX_WAIT_REQUEUE_PI 11 - #define FUTEX_CMP_REQUEUE_PI 12 -+#define FUTEX_WAIT_MULTIPLE 31 - - #define FUTEX_PRIVATE_FLAG 128 - #define FUTEX_CLOCK_REALTIME 256 -@@ -150,4 +151,10 @@ struct robust_list_head { - (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \ - | ((oparg & 0xfff) << 12) | (cmparg & 0xfff)) - -+struct futex_wait_block { -+ __u32 __user *uaddr; -+ __u32 val; -+ __u32 bitset; -+}; -+ - #endif /* _UAPI_LINUX_FUTEX_H */ -diff --git a/kernel/futex.c b/kernel/futex.c -index 6d50728ef2e7..338ae60bd86c 100644 ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -183,6 +183,7 @@ static int __read_mostly futex_cmpxchg_enabled; - #endif - #define FLAGS_CLOCKRT 0x02 - #define FLAGS_HAS_TIMEOUT 0x04 -+#define FLAGS_WAKE_MULTIPLE 0x08 - - /* - * Priority Inheritance state: -@@ -2631,6 +2632,39 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q, - __set_current_state(TASK_RUNNING); - } - -+static int __futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, -+ struct futex_q *q, struct futex_hash_bucket **hb) -+{ -+ -+ u32 uval; -+ int ret; -+ -+retry_private: -+ *hb = queue_lock(q); -+ -+ ret = get_futex_value_locked(&uval, uaddr); -+ -+ if (ret) { -+ queue_unlock(*hb); -+ -+ ret = get_user(uval, uaddr); -+ if (ret) -+ return ret; -+ -+ if (!(flags & FLAGS_SHARED)) -+ goto retry_private; -+ -+ return 1; -+ } -+ -+ if (uval != val) { -+ queue_unlock(*hb); -+ ret = -EWOULDBLOCK; -+ } -+ -+ return ret; -+} -+ - /** - * futex_wait_setup() - Prepare to wait on a futex - * @uaddr: the futex userspace address -@@ -2651,7 +2685,6 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q, - static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, - struct futex_q *q, struct futex_hash_bucket **hb) - { -- u32 uval; - int ret; - - /* -@@ -2672,38 +2705,161 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, - * absorb a wakeup if *uaddr does not match the desired values - * while the syscall executes. - */ --retry: -- ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, FUTEX_READ); -- if (unlikely(ret != 0)) -- return ret; -+ do { -+ ret = get_futex_key(uaddr, flags & FLAGS_SHARED, -+ &q->key, FUTEX_READ); -+ if (unlikely(ret != 0)) -+ return ret; - --retry_private: -- *hb = queue_lock(q); -+ ret = __futex_wait_setup(uaddr, val, flags, q, hb); - -- ret = get_futex_value_locked(&uval, uaddr); -+ /* Drop key reference if retry or error. */ -+ if (ret) -+ put_futex_key(&q->key); -+ } while (ret > 0); - -- if (ret) { -- queue_unlock(*hb); -+ return ret; -+} - -- ret = get_user(uval, uaddr); -- if (ret) -+static int do_futex_wait_multiple(struct futex_wait_block *wb, -+ u32 count, unsigned int flags, -+ ktime_t *abs_time) -+{ -+ -+ struct hrtimer_sleeper timeout, *to; -+ struct futex_hash_bucket *hb; -+ struct futex_q *qs = NULL; -+ int ret; -+ int i; -+ -+ qs = kcalloc(count, sizeof(struct futex_q), GFP_KERNEL); -+ if (!qs) -+ return -ENOMEM; -+ -+ to = futex_setup_timer(abs_time, &timeout, flags, -+ current->timer_slack_ns); -+ retry: -+ for (i = 0; i < count; i++) { -+ qs[i].key = FUTEX_KEY_INIT; -+ qs[i].bitset = wb[i].bitset; -+ -+ ret = get_futex_key(wb[i].uaddr, flags & FLAGS_SHARED, -+ &qs[i].key, FUTEX_READ); -+ if (unlikely(ret != 0)) { -+ for (--i; i >= 0; i--) -+ put_futex_key(&qs[i].key); - goto out; -+ } -+ } - -- if (!(flags & FLAGS_SHARED)) -- goto retry_private; -+ set_current_state(TASK_INTERRUPTIBLE); -+ -+ for (i = 0; i < count; i++) { -+ ret = __futex_wait_setup(wb[i].uaddr, wb[i].val, -+ flags, &qs[i], &hb); -+ if (ret) { -+ /* Drop the failed key directly. keys 0..(i-1) -+ * will be put by unqueue_me. */ -+ put_futex_key(&qs[i].key); -+ -+ /* Undo the partial work we did. */ -+ for (--i; i >= 0; i--) -+ unqueue_me(&qs[i]); -+ -+ __set_current_state(TASK_RUNNING); -+ if (ret > 0) -+ goto retry; -+ goto out; -+ } -+ -+ /* We can't hold to the bucket lock when dealing with -+ * the next futex. Queue ourselves now so we can unlock -+ * it before moving on. */ -+ queue_me(&qs[i], hb); -+ } -+ -+ if (to) -+ hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); -+ -+ /* There is no easy to way to check if we are wake already on -+ * multiple futexes without waking through each one of them. So -+ * just sleep and let the scheduler handle it. -+ */ -+ if (!to || to->task) -+ freezable_schedule(); -+ -+ __set_current_state(TASK_RUNNING); - -- put_futex_key(&q->key); -+ ret = -ETIMEDOUT; -+ /* If we were woken (and unqueued), we succeeded. */ -+ for (i = 0; i < count; i++) -+ if (!unqueue_me(&qs[i])) -+ ret = i; -+ -+ /* Succeed wakeup */ -+ if (ret >= 0) -+ goto out; -+ -+ /* Woken by triggered timeout */ -+ if (to && !to->task) -+ goto out; -+ -+ /* -+ * We expect signal_pending(current), but we might be the -+ * victim of a spurious wakeup as well. -+ */ -+ if (!signal_pending(current)) - goto retry; -+ -+ ret = -ERESTARTSYS; -+ if (!abs_time) -+ goto out; -+ -+ ret = -ERESTART_RESTARTBLOCK; -+ out: -+ if (to) { -+ hrtimer_cancel(&to->timer); -+ destroy_hrtimer_on_stack(&to->timer); - } - -- if (uval != val) { -- queue_unlock(*hb); -- ret = -EWOULDBLOCK; -+ kfree(qs); -+ return ret; -+} -+ -+static int futex_wait_multiple(u32 __user *uaddr, unsigned int flags, -+ u32 count, ktime_t *abs_time) -+{ -+ struct futex_wait_block *wb; -+ struct restart_block *restart; -+ int ret; -+ -+ if (!count) -+ return -EINVAL; -+ -+ wb = kcalloc(count, sizeof(struct futex_wait_block), GFP_KERNEL); -+ if (!wb) -+ return -ENOMEM; -+ -+ if (copy_from_user(wb, uaddr, -+ count * sizeof(struct futex_wait_block))) { -+ ret = -EFAULT; -+ goto out; -+ } -+ -+ ret = do_futex_wait_multiple(wb, count, flags, abs_time); -+ -+ if (ret == -ERESTART_RESTARTBLOCK) { -+ restart = ¤t->restart_block; -+ restart->fn = futex_wait_restart; -+ restart->futex.uaddr = uaddr; -+ restart->futex.val = count; -+ restart->futex.time = *abs_time; -+ restart->futex.flags = (flags | FLAGS_HAS_TIMEOUT | -+ FLAGS_WAKE_MULTIPLE); - } - - out: -- if (ret) -- put_futex_key(&q->key); -+ kfree(wb); - return ret; - } - -@@ -2784,6 +2940,10 @@ static long futex_wait_restart(struct restart_block *restart) - } - restart->fn = do_no_restart_syscall; - -+ if (restart->futex.flags & FLAGS_WAKE_MULTIPLE) -+ return (long)futex_wait_multiple(uaddr, restart->futex.flags, -+ restart->futex.val, tp); -+ - return (long)futex_wait(uaddr, restart->futex.flags, - restart->futex.val, tp, restart->futex.bitset); - } -@@ -3667,6 +3827,8 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, - uaddr2); - case FUTEX_CMP_REQUEUE_PI: - return futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1); -+ case FUTEX_WAIT_MULTIPLE: -+ return futex_wait_multiple(uaddr, flags, val, timeout); - } - return -ENOSYS; - } -@@ -3683,7 +3845,8 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, - - if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || - cmd == FUTEX_WAIT_BITSET || -- cmd == FUTEX_WAIT_REQUEUE_PI)) { -+ cmd == FUTEX_WAIT_REQUEUE_PI || -+ cmd == FUTEX_WAIT_MULTIPLE)) { - if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG)))) - return -EFAULT; - if (get_timespec64(&ts, utime)) -@@ -3692,7 +3855,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, - return -EINVAL; - - t = timespec64_to_ktime(ts); -- if (cmd == FUTEX_WAIT) -+ if (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_MULTIPLE) - t = ktime_add_safe(ktime_get(), t); - tp = &t; - } -@@ -3876,14 +4039,15 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val, - - if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || - cmd == FUTEX_WAIT_BITSET || -- cmd == FUTEX_WAIT_REQUEUE_PI)) { -+ cmd == FUTEX_WAIT_REQUEUE_PI || -+ cmd == FUTEX_WAIT_MULTIPLE)) { - if (get_old_timespec32(&ts, utime)) - return -EFAULT; - if (!timespec64_valid(&ts)) - return -EINVAL; - - t = timespec64_to_ktime(ts); -- if (cmd == FUTEX_WAIT) -+ if (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_MULTIPLE) - t = ktime_add_safe(ktime_get(), t); - tp = &t; - } diff --git a/sys-kernel/calculate-sources/Manifest b/sys-kernel/calculate-sources/Manifest index 98a4b6304..87bde1266 100644 --- a/sys-kernel/calculate-sources/Manifest +++ b/sys-kernel/calculate-sources/Manifest @@ -1,8 +1,6 @@ DIST linux-4.19.tar.xz 103117552 BLAKE2B 1dbf16cf410867412d17568fe42bc1e90c034183b654d270b650621ff7664a321950943d0639205bc1ee7ef6210be170c1f2c785a042ed8a4ec5e3a486d890e0 SHA512 ab67cc746b375a8b135e8b23e35e1d6787930d19b3c26b2679787d62951cbdbc3bb66f8ededeb9b890e5008b2459397f9018f1a6772fdef67780b06a4cb9f6f4 DIST linux-5.4.tar.xz 109441440 BLAKE2B 193bc4a3147e147d5529956164ec4912fad5d5c6fb07f909ff1056e57235834173194afc686993ccd785c1ff15804de0961b625f3008cca0e27493efc8f27b13 SHA512 9f60f77e8ab972b9438ac648bed17551c8491d6585a5e85f694b2eaa4c623fbc61eb18419b2656b6795eac5deec0edaa04547fc6723fbda52256bd7f3486898f -DIST linux-5.8.tar.xz 114459324 BLAKE2B 7bd97f8fa4527840754434414c07283e89731dc8ebb1e95fa5bc1469a60af1122582c0d3b6e262e77882f023190068df3537bd8b65964b3caa820bb2c8e579c7 SHA512 45a53ecf351096ef6e98242cca4228b8da9b9139ecc6963695791ea6fb7a9484a4e1c19dcca7ce7cbfdfa49de0451b70973bb078f12bdae9cbaddbc3f8092556 DIST linux-5.9.tar.xz 115507140 BLAKE2B e8d11472d63a9f8409ca12a2e8c97c6963a3d4516b5a398b627d6ece565584526f9b5a1377a2fa4bd184c09c7db94c987428bc5d52df0c788464a67e9e8d6dcb SHA512 d3d92ce4246bad74c9a784212f160d98449b1e8793970c2c308276568d852b8effe0528686bdb87d55d691f09a826abf7938d69bdd4759ce65ddd5c05ffe4eca DIST patch-4.19.161.xz 3649928 BLAKE2B d9208f6b07a59c14e9f46acca1b1456bc02e8afd64b2c634a8376d28bdd5df61de66e7cfd42a9482e986d8fb822518b3dbbac9bde4f2e0257fa73b4dba59c51d SHA512 6483da5d53e4660515fd053c3e6ee3083b222db199d8de3b00a80fe7d2414f61e4bfc2abb88d8186943c8aa01e16bf29ef38e352c32e0ccac29ba6555523ae00 DIST patch-5.4.81.xz 2396180 BLAKE2B 3a42b28cb5fb9cdc83171df46854805cc39e83f122f47b00eb823a05c0663880e688d7c44dfd2c21875fdbb0f02e494396df69ce07cc4ca76d03cee521d48ece SHA512 f97b6d8d58d43449491d543dd0c3afe8e4c7f7ea4527c4712b0bb6b7a4817daba61f507e8518a4f72254042472d7b5f8095e5df1c131fd010f4c0453c9d8cde5 -DIST patch-5.8.18.xz 753276 BLAKE2B cc4ab6db80f14cd22f6409c4eb1f344822b79cdbccbae65d53aba444f957ed320719acf0f448e08cc9f1341dafee90527fd035f13a268289c2dc3bf317107142 SHA512 e161e534bcf842de5b2a605f153e6d581030593e99185a5d3c341b40c2c9e6e4a6b3bac38647156f1974768cf730073c0ca34295d847e0dd114de4ca52d72039 DIST patch-5.9.12.xz 612468 BLAKE2B babdf390cba9ede83b9056c90f769b98d58d86b168b8666035bf17e3e7d5f942d45a7392e56b6acd0423d0a4e8a1b3fa629a40ba12ba4a8ced4719b7218cef70 SHA512 eef914d5124dae25d0d5c6162cf0d19cfe6adabd3da5594609275527ac7bca9b8b3c9bdd8ae5cbc061cb93a4559c30daed3f104f789b31caa2596f3da371f2aa diff --git a/sys-kernel/calculate-sources/calculate-sources-5.8.18.ebuild b/sys-kernel/calculate-sources/calculate-sources-5.8.18.ebuild deleted file mode 100644 index 55411e221..000000000 --- a/sys-kernel/calculate-sources/calculate-sources-5.8.18.ebuild +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 1999-2015 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -EAPI=5 -ETYPE="sources" - -inherit calculate-kernel-8 eutils - -DESCRIPTION="Calculate Linux kernel image" -KEYWORDS="~amd64" -HOMEPAGE="http://www.calculate-linux.org" - -SRC_URI="${KERNEL_URI} ${ARCH_URI}" - -IUSE="fsync uksm" - -src_unpack() { - calculate-kernel-8_src_unpack -} - -pkg_postinst() { - calculate-kernel-8_pkg_postinst -} From 7ca56dedd5b38d33fef8455764ead59f1de8a08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=88=D0=B5=20=D0=98=D0=BC=D1=8F?= Date: Wed, 2 Dec 2020 23:01:04 +0300 Subject: [PATCH 6/6] sys-kernel/calculate-sources: 4.19.145 is stable --- sys-kernel/calculate-sources/Manifest | 1 + .../calculate-sources-4.19.145.ebuild | 24 +++++++++++++++++++ .../calculate-sources-4.19.161.ebuild | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 sys-kernel/calculate-sources/calculate-sources-4.19.145.ebuild diff --git a/sys-kernel/calculate-sources/Manifest b/sys-kernel/calculate-sources/Manifest index 87bde1266..692783bdb 100644 --- a/sys-kernel/calculate-sources/Manifest +++ b/sys-kernel/calculate-sources/Manifest @@ -1,6 +1,7 @@ DIST linux-4.19.tar.xz 103117552 BLAKE2B 1dbf16cf410867412d17568fe42bc1e90c034183b654d270b650621ff7664a321950943d0639205bc1ee7ef6210be170c1f2c785a042ed8a4ec5e3a486d890e0 SHA512 ab67cc746b375a8b135e8b23e35e1d6787930d19b3c26b2679787d62951cbdbc3bb66f8ededeb9b890e5008b2459397f9018f1a6772fdef67780b06a4cb9f6f4 DIST linux-5.4.tar.xz 109441440 BLAKE2B 193bc4a3147e147d5529956164ec4912fad5d5c6fb07f909ff1056e57235834173194afc686993ccd785c1ff15804de0961b625f3008cca0e27493efc8f27b13 SHA512 9f60f77e8ab972b9438ac648bed17551c8491d6585a5e85f694b2eaa4c623fbc61eb18419b2656b6795eac5deec0edaa04547fc6723fbda52256bd7f3486898f DIST linux-5.9.tar.xz 115507140 BLAKE2B e8d11472d63a9f8409ca12a2e8c97c6963a3d4516b5a398b627d6ece565584526f9b5a1377a2fa4bd184c09c7db94c987428bc5d52df0c788464a67e9e8d6dcb SHA512 d3d92ce4246bad74c9a784212f160d98449b1e8793970c2c308276568d852b8effe0528686bdb87d55d691f09a826abf7938d69bdd4759ce65ddd5c05ffe4eca +DIST patch-4.19.145.xz 3398080 BLAKE2B 20ae916cdf9a8d2d7642af0316a7fe07b0598f1109c26270e9da9f02b1d8d13cc4aba6cc340a755260f7e417fa33d9d5622b9b11b9e75fb78536dffa221fa474 SHA512 eedf90d3ba9510a091a7d28fe4945535a7f773a75375fe09c15845752ebca37ef27c699ec3a9993f1f01b4820d741da10892a5b76751da8dd0d0e00c6eb65a7b DIST patch-4.19.161.xz 3649928 BLAKE2B d9208f6b07a59c14e9f46acca1b1456bc02e8afd64b2c634a8376d28bdd5df61de66e7cfd42a9482e986d8fb822518b3dbbac9bde4f2e0257fa73b4dba59c51d SHA512 6483da5d53e4660515fd053c3e6ee3083b222db199d8de3b00a80fe7d2414f61e4bfc2abb88d8186943c8aa01e16bf29ef38e352c32e0ccac29ba6555523ae00 DIST patch-5.4.81.xz 2396180 BLAKE2B 3a42b28cb5fb9cdc83171df46854805cc39e83f122f47b00eb823a05c0663880e688d7c44dfd2c21875fdbb0f02e494396df69ce07cc4ca76d03cee521d48ece SHA512 f97b6d8d58d43449491d543dd0c3afe8e4c7f7ea4527c4712b0bb6b7a4817daba61f507e8518a4f72254042472d7b5f8095e5df1c131fd010f4c0453c9d8cde5 DIST patch-5.9.12.xz 612468 BLAKE2B babdf390cba9ede83b9056c90f769b98d58d86b168b8666035bf17e3e7d5f942d45a7392e56b6acd0423d0a4e8a1b3fa629a40ba12ba4a8ced4719b7218cef70 SHA512 eef914d5124dae25d0d5c6162cf0d19cfe6adabd3da5594609275527ac7bca9b8b3c9bdd8ae5cbc061cb93a4559c30daed3f104f789b31caa2596f3da371f2aa diff --git a/sys-kernel/calculate-sources/calculate-sources-4.19.145.ebuild b/sys-kernel/calculate-sources/calculate-sources-4.19.145.ebuild new file mode 100644 index 000000000..e2bc978e7 --- /dev/null +++ b/sys-kernel/calculate-sources/calculate-sources-4.19.145.ebuild @@ -0,0 +1,24 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=5 +ETYPE="sources" + +inherit calculate-kernel-7 eutils + +DESCRIPTION="Calculate Linux kernel image" +KEYWORDS="amd64" +HOMEPAGE="http://www.calculate-linux.org" + +SRC_URI="${KERNEL_URI} ${ARCH_URI}" + +IUSE="uksm" + +src_unpack() { + calculate-kernel-7_src_unpack +} + +pkg_postinst() { + calculate-kernel-7_pkg_postinst +} diff --git a/sys-kernel/calculate-sources/calculate-sources-4.19.161.ebuild b/sys-kernel/calculate-sources/calculate-sources-4.19.161.ebuild index e2bc978e7..2a47ced20 100644 --- a/sys-kernel/calculate-sources/calculate-sources-4.19.161.ebuild +++ b/sys-kernel/calculate-sources/calculate-sources-4.19.161.ebuild @@ -8,7 +8,7 @@ ETYPE="sources" inherit calculate-kernel-7 eutils DESCRIPTION="Calculate Linux kernel image" -KEYWORDS="amd64" +KEYWORDS="~amd64" HOMEPAGE="http://www.calculate-linux.org" SRC_URI="${KERNEL_URI} ${ARCH_URI}"