From b9c155065d2ca4a6037a0ca4bfc788d6961fdc8e Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Thu, 8 Aug 2019 13:13:01 -0400 Subject: [PATCH 1/1] LU-12518 llite: Accept EBUSY for page unaligned read When doing unaligned strided reads, it's possible for the first and last page of a stride to be read by another thread on the same node, resulting in EBUSY. Also this could potentially happen for sequential read, for example, several MPI split one large file with unaligned page size, sequential read happen with each MPI program. We shouldn't stop readahead in these cases. Signed-off-by: Patrick Farrell Change-Id: I4e832c8859452d0b52f14b5e4fdb64a972bf40a3 Reviewed-on: https://review.whamcloud.com/35457 Reviewed-by: Wang Shilong Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/llite/rw.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 61e8baf..2979d17 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -359,7 +359,8 @@ ll_read_ahead_pages(const struct lu_env *env, struct cl_io *io, struct ra_io_arg *ria, pgoff_t *ra_end) { struct cl_read_ahead ra = { 0 }; - int rc = 0, count = 0; + /* busy page count is per stride */ + int rc = 0, count = 0, busy_page_count = 0; pgoff_t page_idx; LASSERT(ria != NULL); @@ -412,8 +413,20 @@ ll_read_ahead_pages(const struct lu_env *env, struct cl_io *io, /* If the page is inside the read-ahead window */ rc = ll_read_ahead_page(env, io, queue, page_idx); - if (rc < 0) + if (rc < 0 && rc != -EBUSY) break; + if (rc == -EBUSY) { + busy_page_count++; + CDEBUG(D_READA, + "skip busy page: %lu\n", page_idx); + /* For page unaligned readahead the first + * last pages of each region can be read by + * another reader on the same node, and so + * may be busy. So only stop for > 2 busy + * pages. */ + if (busy_page_count > 2) + break; + } *ra_end = page_idx; /* Only subtract from reserve & count the page if we @@ -436,6 +449,7 @@ ll_read_ahead_pages(const struct lu_env *env, struct cl_io *io, pos += (ria->ria_length - offset); if ((pos >> PAGE_SHIFT) >= page_idx + 1) page_idx = (pos >> PAGE_SHIFT) - 1; + busy_page_count = 0; CDEBUG(D_READA, "Stride: jump %llu pages to %lu\n", ria->ria_length - offset, page_idx); -- 1.8.3.1