aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <graf@amazon.com>2020-09-30 23:10:56 +0200
committerKevin O'Connor <kevin@koconnor.net>2020-10-28 15:18:29 -0400
commit94f0510dc75e910400aad6c169048d672c8c7193 (patch)
tree374a3cf84ce23655d10ac026df5bd520ac73742d
parent01f2736cc905df7abfe4a4160d986b49eb607e7a (diff)
downloadseabios-hppa-94f0510dc75e910400aad6c169048d672c8c7193.zip
seabios-hppa-94f0510dc75e910400aad6c169048d672c8c7193.tar.gz
seabios-hppa-94f0510dc75e910400aad6c169048d672c8c7193.tar.bz2
nvme: Split requests by maximum allowed size
Some NVMe controllers only support small maximum request sizes, such as the AWS EBS NVMe implementation which only supports NVMe requests of up to 32 pages (256kb) at once. BIOS callers can exceed those request sizes by defining sector counts above this threshold. Currently we fall back to the bounce buffer implementation for those. This is slow. This patch introduces splitting logic to the NVMe I/O request code so that every NVMe I/O request gets handled in a chunk size that is consumable by the NVMe adapter, while maintaining the fast path PRPL logic we just introduced. Signed-off-by: Alexander Graf <graf@amazon.com>
-rw-r--r--src/hw/nvme.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/hw/nvme.c b/src/hw/nvme.c
index b92ca52..cc37bca 100644
--- a/src/hw/nvme.c
+++ b/src/hw/nvme.c
@@ -727,6 +727,22 @@ nvme_cmd_readwrite(struct nvme_namespace *ns, struct disk_op_s *op, int write)
u16 const max_blocks = NVME_PAGE_SIZE / ns->block_size;
u16 i;
+ /* Split up requests that are larger than the device can handle */
+ if (op->count > ns->max_req_size) {
+ u16 count = op->count;
+
+ /* Handle the first max_req_size elements */
+ op->count = ns->max_req_size;
+ if (nvme_cmd_readwrite(ns, op, write))
+ return res;
+
+ /* Handle the remainder of the request */
+ op->count = count - ns->max_req_size;
+ op->lba += ns->max_req_size;
+ op->buf_fl += (ns->max_req_size * ns->block_size);
+ return nvme_cmd_readwrite(ns, op, write);
+ }
+
if (!nvme_build_prpl(ns, op)) {
/* Request goes via PRP List logic */
return nvme_io_readwrite(ns, op->lba, ns->prp1, op->count, write);