[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] efidisk: Breakup large reads into batches
From: |
Vladimir 'phcoder' Serbinenko |
Subject: |
Re: [PATCH] efidisk: Breakup large reads into batches |
Date: |
Fri, 23 Feb 2024 20:28:15 +0300 |
Why is setting max_agglomerate not enough to achieve the same effect?
On Fri, Feb 23, 2024 at 8:12 PM Mate Kukri <mate.kukri@canonical.com> wrote:
>
> From: David F <davidf@terabyteunlimited.com>
>
> Work around firmware bugs that cause large reads to fail from certain
> devices.
>
> Report-By: David F <davidf@terabyteunlimited.com>
> Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
> ---
> grub-core/disk/efi/efidisk.c | 43 +++++++++++++++++++++++++-----------
> 1 file changed, 30 insertions(+), 13 deletions(-)
>
> diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
> index 3b5ed5691..079b72ab7 100644
> --- a/grub-core/disk/efi/efidisk.c
> +++ b/grub-core/disk/efi/efidisk.c
> @@ -27,6 +27,9 @@
> #include <grub/efi/efi.h>
> #include <grub/efi/disk.h>
>
> +/* break up io to prevent problems under some UEFI envrionments */
> +#define EFIDISK_C_MAXIOSECS 0x100U
> +
> struct grub_efidisk_data
> {
> grub_efi_handle_t handle;
> @@ -599,20 +602,34 @@ grub_efidisk_read (struct grub_disk *disk,
> grub_disk_addr_t sector,
> grub_size_t size, char *buf)
> {
> grub_efi_status_t status;
> + grub_size_t sector_count;
>
> - grub_dprintf ("efidisk",
> - "reading 0x%lx sectors at the sector 0x%llx from %s\n",
> - (unsigned long) size, (unsigned long long) sector,
> disk->name);
> -
> - status = grub_efidisk_readwrite (disk, sector, size, buf, 0);
> -
> - if (status == GRUB_EFI_NO_MEDIA)
> - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"),
> disk->name);
> - else if (status != GRUB_EFI_SUCCESS)
> - return grub_error (GRUB_ERR_READ_ERROR,
> - N_("failure reading sector 0x%llx from `%s'"),
> - (unsigned long long) sector,
> - disk->name);
> + /* break up reads to EFIDISK_C_MAXIOSECS size chunks */
> + do
> + {
> + /* determine number of sectors this cycle */
> + sector_count = (size > EFIDISK_C_MAXIOSECS) ? EFIDISK_C_MAXIOSECS :
> size;
> +
> + /* output debug information */
> + grub_dprintf ("efidisk",
> + "reading 0x%lx sectors at the sector 0x%llx from %s\n",
> + (unsigned long) sector_count, (unsigned long long)
> sector, disk->name);
> +
> + status = grub_efidisk_readwrite (disk, sector, sector_count, buf, 0);
> +
> + if (status == GRUB_EFI_NO_MEDIA)
> + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"),
> disk->name);
> + if (status != GRUB_EFI_SUCCESS)
> + return grub_error (GRUB_ERR_READ_ERROR,
> + N_("failure reading 0x%lx sector(s) from sector
> 0x%llx on `%s'"),
> + (unsigned long) sector_count, (unsigned long long)
> sector, disk->name);
> +
> + /* next cycle */
> + buf += (grub_efi_uintn_t) sector_count << disk->log_sector_size;;
> + sector += sector_count;
> + size -= sector_count;
> + }
> + while (size);
>
> return GRUB_ERR_NONE;
> }
> --
> 2.39.2
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
--
Regards
Vladimir 'phcoder' Serbinenko