diff --git a/0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch b/0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch new file mode 100644 index 0000000..f525abd --- /dev/null +++ b/0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch @@ -0,0 +1,238 @@ +From b353ca96bf002a9262fdf74637f39615d003d069 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 8 Dec 2023 11:51:57 +0800 +Subject: [PATCH 1/2] ofdisk: enhance boot time by focusing on boot disk + relevance + +After a historical review, it's clear that a boot delay regression +coincided with the introduction of the fcp iterating patch. Reverting +this patch has shown promising signs in mitigating the issue. In order +to improve the efficiency, a more refined discovery process is proposed, +aiming to exclude device types differing from the boot disk to curtail +unnecessary iterations. + +This patch extends prior efforts by exclusively targeting root device +discovery linked to the boot disk, verifying device types to prevent +process elongation. + +It is worth noting that grub's opportunistic approach to assembling the +root device, seeking accessible results in parallel during iteration, +sometimes allows even a partially assembled RAID, albeit in a degraded +mode. However, delays stem from unrelated devices appearing before the +actual boot device. + +To streamline the boot process, the patch utilizes parent nodes in +conjunction with block device nodes to extract essential boot-related +information. This refined identification method efficiently limits the +application's scope to devices connected to the chosen boot device, +notably optimizing subsequent device iteration. By adeptly filtering out +devices not linked to the same FCP (Fibre Channel Protocol) device, it +significantly enhances boot efficiency, ensuring a more streamlined and +efficient boot process. + +Signed-off-by: Michael Chang +--- + grub-core/disk/ieee1275/ofdisk.c | 136 +++++++++++++++++++++++++++++-- + 1 file changed, 131 insertions(+), 5 deletions(-) + +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -31,6 +31,13 @@ + static char *last_devpath; + static grub_ieee1275_ihandle_t last_ihandle; + ++#define IEEE1275_DISK_ALIAS "/disk@" ++#define IEEE1275_NVMEOF_DISK_ALIAS "/nvme-of/controller@" ++ ++static char *boot_type; ++static char *boot_parent; ++static int is_boot_nvmeof; ++ + struct ofdisk_hash_ent + { + char *devpath; +@@ -529,12 +536,21 @@ + { + if (grub_strcmp (alias->type, "fcp") == 0) + { +- // Iterate disks +- dev_iterate_fcp_disks(alias); +- +- // Iterate NVMeoF +- dev_iterate_fcp_nvmeof(alias); ++ if (boot_type && ++ grub_strcmp (boot_type, alias->type) != 0) ++ { ++ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n", ++ alias->path, alias->type, boot_type); ++ goto iter_children; ++ } + ++ if (grub_strcmp (boot_parent, alias->path) == 0) ++ { ++ if (is_boot_nvmeof) ++ dev_iterate_fcp_nvmeof(alias); ++ else ++ dev_iterate_fcp_disks(alias); ++ } + } + else if (grub_strcmp (alias->type, "vscsi") == 0) + { +@@ -552,6 +568,14 @@ + char *buf, *bufptr; + unsigned i; + ++ if (boot_type && ++ grub_strcmp (boot_type, alias->type) != 0) ++ { ++ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n", ++ alias->path, alias->type, boot_type); ++ return; ++ } ++ + if (grub_ieee1275_open (alias->path, &ihandle)) + return; + +@@ -615,6 +639,14 @@ + grub_uint16_t table_size; + grub_ieee1275_ihandle_t ihandle; + ++ if (boot_type && ++ grub_strcmp (boot_type, alias->type) != 0) ++ { ++ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n", ++ alias->path, alias->type, boot_type); ++ goto iter_children; ++ } ++ + buf = grub_malloc (grub_strlen (alias->path) + + sizeof ("/disk@7766554433221100")); + if (!buf) +@@ -674,6 +706,7 @@ + return; + } + ++ iter_children: + { + struct grub_ieee1275_devalias child; + +@@ -1046,6 +1079,68 @@ + .next = 0 + }; + ++static char * ++get_parent_devname (const char *devname, int *is_nvmeof) ++{ ++ char *parent, *pptr; ++ ++ if (is_nvmeof) ++ *is_nvmeof = 0; ++ ++ parent = grub_strdup (devname); ++ ++ if (parent == NULL) ++ { ++ grub_print_error (); ++ return NULL; ++ } ++ ++ pptr = grub_strstr (parent, IEEE1275_DISK_ALIAS); ++ ++ if (pptr != NULL) ++ { ++ *pptr = '\0'; ++ return parent; ++ } ++ ++ pptr = grub_strstr (parent, IEEE1275_NVMEOF_DISK_ALIAS); ++ ++ if (pptr != NULL) ++ { ++ *pptr = '\0'; ++ if (is_nvmeof) ++ *is_nvmeof = 1; ++ return parent; ++ } ++ ++ return parent; ++} ++ ++static char * ++get_boot_device_parent (const char *bootpath, int *is_nvmeof) ++{ ++ char *dev, *canon, *parent; ++ ++ dev = grub_ieee1275_get_aliasdevname (bootpath); ++ canon = grub_ieee1275_canonicalise_devname (dev); ++ ++ if (!canon) ++ { ++ /* This should not happen. */ ++ grub_error (GRUB_ERR_BAD_DEVICE, "canonicalise devname failed"); ++ grub_print_error (); ++ return NULL; ++ } ++ else ++ grub_dprintf ("ofdisk", "%s is canonical %s\n", bootpath, canon); ++ ++ parent = get_parent_devname (canon, is_nvmeof); ++ grub_dprintf ("ofdisk", "%s is parent of %s\n", parent, canon); ++ ++ grub_free (canon); ++ return parent; ++} ++ + static void + insert_bootpath (void) + { +@@ -1081,6 +1176,12 @@ + char *device = grub_ieee1275_get_devname (bootpath); + op = ofdisk_hash_add (device, NULL); + op->is_boot = 1; ++ boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof); ++ boot_type = grub_ieee1275_get_device_type (boot_parent); ++ if (boot_type) ++ grub_dprintf ("ofdisk", "the boot device type %s is used for root device discovery, others excluded\n", boot_type); ++ else ++ grub_dprintf ("ofdisk", "unknown boot device type, will use all devices to discover root and may be slow\n"); + } + grub_free (type); + grub_free (bootpath); +@@ -1097,12 +1198,37 @@ + grub_disk_dev_unregister (&grub_ofdisk_dev); + } + ++static const char * ++grub_env_get_boot_type (struct grub_env_var *var __attribute__ ((unused)), ++ const char *val __attribute__ ((unused))) ++{ ++ static char *ret; ++ ++ if (!ret) ++ ret = grub_xasprintf("boot: %s type: %s is_nvmeof: %d", ++ boot_parent, ++ boot_type ? : "unknown", ++ is_boot_nvmeof); ++ ++ return ret; ++} ++ ++static char * ++grub_env_set_boot_type (struct grub_env_var *var __attribute__ ((unused)), ++ const char *val __attribute__ ((unused))) ++{ ++ /* READ ONLY */ ++ return NULL; ++} ++ + void + grub_ofdisk_init (void) + { + grub_disk_firmware_fini = grub_ofdisk_fini; + + insert_bootpath (); ++ grub_register_variable_hook ("ofdisk_boot_type", grub_env_get_boot_type, ++ grub_env_set_boot_type ); + + grub_disk_dev_register (&grub_ofdisk_dev); + } diff --git a/0002-ofdisk-add-early_log-support.patch b/0002-ofdisk-add-early_log-support.patch new file mode 100644 index 0000000..3abfd58 --- /dev/null +++ b/0002-ofdisk-add-early_log-support.patch @@ -0,0 +1,164 @@ +From 8959b9d97b00f791ffe02b5e3ec3fdf6bff25838 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 12 Dec 2023 15:34:18 +0800 +Subject: [PATCH 2/2] ofdisk: add early_log support + +The command ofdisk_early_msg can be used to review debug message logged +before output console is initialized. + +For eg: + + grub> ofdisk_early_msg + /vdevice/v-scsi@71000002/disk@8000000000000000 is canonical + /vdevice/v-scsi@71000002/disk@8000000000000000 + + /vdevice/v-scsi@71000002 is parent of + /vdevice/v-scsi@71000002/disk@80000000 + 00000000 + + the boot device type vscsi is used for root device discovery, others excluded + +We can use it in conjunction with the $ofdisk_boot_type variable to get +better understanding the boot device information. + + grub> echo $ofdisk_boot_type + boot: /vdevice/v-scsi@71000002 type: vscsi is_nvmeof? 0 + +Signed-off-by: Michael Chang +--- + grub-core/disk/ieee1275/ofdisk.c | 75 +++++++++++++++++++++++++++++--- + 1 file changed, 70 insertions(+), 5 deletions(-) + +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #define RETRY_DEFAULT_TIMEOUT 15 + +@@ -60,6 +61,9 @@ + #define OFDISK_HASH_SZ 8 + static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ]; + ++static void early_log (const char *fmt, ...); ++static void print_early_log (void); ++ + static int + ofdisk_hash_fn (const char *devpath) + { +@@ -1132,10 +1136,10 @@ + return NULL; + } + else +- grub_dprintf ("ofdisk", "%s is canonical %s\n", bootpath, canon); ++ early_log ("%s is canonical %s\n", bootpath, canon); + + parent = get_parent_devname (canon, is_nvmeof); +- grub_dprintf ("ofdisk", "%s is parent of %s\n", parent, canon); ++ early_log ("%s is parent of %s\n", parent, canon); + + grub_free (canon); + return parent; +@@ -1179,9 +1183,9 @@ + boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof); + boot_type = grub_ieee1275_get_device_type (boot_parent); + if (boot_type) +- grub_dprintf ("ofdisk", "the boot device type %s is used for root device discovery, others excluded\n", boot_type); ++ early_log ("the boot device type %s is used for root device discovery, others excluded\n", boot_type); + else +- grub_dprintf ("ofdisk", "unknown boot device type, will use all devices to discover root and may be slow\n"); ++ early_log ("unknown boot device type, will use all devices to discover root and may be slow\n"); + } + grub_free (type); + grub_free (bootpath); +@@ -1205,7 +1209,7 @@ + static char *ret; + + if (!ret) +- ret = grub_xasprintf("boot: %s type: %s is_nvmeof: %d", ++ ret = grub_xasprintf("boot: %s type: %s is_nvmeof? %d", + boot_parent, + boot_type ? : "unknown", + is_boot_nvmeof); +@@ -1221,6 +1225,17 @@ + return NULL; + } + ++static grub_err_t ++grub_cmd_early_msg (struct grub_command *cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ print_early_log (); ++ return 0; ++} ++ ++static grub_command_t cmd_early_msg; ++ + void + grub_ofdisk_init (void) + { +@@ -1230,6 +1245,9 @@ + grub_register_variable_hook ("ofdisk_boot_type", grub_env_get_boot_type, + grub_env_set_boot_type ); + ++ cmd_early_msg = ++ grub_register_command ("ofdisk_early_msg", grub_cmd_early_msg, ++ 0, N_("Show early boot message in ofdisk.")); + grub_disk_dev_register (&grub_ofdisk_dev); + } + +@@ -1278,3 +1296,50 @@ + + return 0; + } ++ ++struct ofdisk_early_msg ++{ ++ struct ofdisk_early_msg *next; ++ char *msg; ++}; ++ ++static struct ofdisk_early_msg *early_msg_head; ++static struct ofdisk_early_msg **early_msg_last = &early_msg_head; ++ ++static void ++early_log (const char *fmt, ...) ++{ ++ struct ofdisk_early_msg *n; ++ va_list args; ++ ++ grub_error_push (); ++ n = grub_malloc (sizeof (*n)); ++ if (!n) ++ { ++ grub_errno = 0; ++ grub_error_pop (); ++ return; ++ } ++ n->next = 0; ++ ++ va_start (args, fmt); ++ n->msg = grub_xvasprintf (fmt, args); ++ va_end (args); ++ ++ *early_msg_last = n; ++ early_msg_last = &n->next; ++ ++ grub_errno = 0; ++ grub_error_pop (); ++} ++ ++static void ++print_early_log (void) ++{ ++ struct ofdisk_early_msg *cur; ++ ++ if (!early_msg_head) ++ grub_printf ("no early log is available\n"); ++ for (cur = early_msg_head; cur; cur = cur->next) ++ grub_printf ("%s\n", cur->msg); ++} diff --git a/grub2.changes b/grub2.changes index 68788f8..3b61f7e 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Sat Feb 17 06:59:55 UTC 2024 - Michael Chang + +- Fix PowerPC grub loads 5 to 10 minutes slower on SLE-15-SP5 compared to + SLE-15-SP2 (bsc#1217102) + * add 0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch + * add 0002-ofdisk-add-early_log-support.patch + ------------------------------------------------------------------- Wed Feb 7 18:33:58 UTC 2024 - Bernhard Wiedemann diff --git a/grub2.spec b/grub2.spec index e790f8a..ecb237c 100644 --- a/grub2.spec +++ b/grub2.spec @@ -390,6 +390,8 @@ Patch196: fix_no_extra_deps_in_release_tarball.patch Patch197: 0001-fs-xfs-always-verify-the-total-number-of-entries-is-.patch Patch198: 0001-loader-arm64-efi-linux-Remove-magic-number-header-fi.patch Patch199: 0001-squash-ieee1275-ofpath-enable-NVMeoF-logical-device-.patch +Patch200: 0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch +Patch201: 0002-ofdisk-add-early_log-support.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140