From 2070e9bcc0c1bd212c61c8d2911074f308deb1f0 Mon Sep 17 00:00:00 2001 From: Andriy Skulysh Date: Thu, 24 Oct 2019 15:11:25 +0300 Subject: [PATCH] LU-13100 lov: grant deadlock if same OSC in two components The same osc can be involved in several components but osc layer leaves active last used extent, so an RPC can't be sent if grants are required from the same OST for another component. Add cl_io_extent_release() to release active extent before switching to the next component. Change-Id: Idadda6eaecd1d47b78880c81e1fb7513d5be2419 Cray-bug-id: LUS-8038 Signed-off-by: Andriy Skulysh Reviewed-by: Vitaly Fertman Reviewed-by: Alexander Zarochentsev Reviewed-by: Andrew Perepechko Reviewed-on: https://review.whamcloud.com/37095 Tested-by: jenkins Reviewed-by: Andrew Perepechko Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Mike Pershin Reviewed-by: Oleg Drokin --- lustre/include/cl_object.h | 6 ++++++ lustre/include/lustre_osc.h | 2 ++ lustre/lov/lov_io.c | 4 ++++ lustre/mdc/mdc_dev.c | 1 + lustre/obdclass/cl_io.c | 14 ++++++++++++++ lustre/osc/osc_io.c | 15 ++++++++++++++- 6 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 05c89eb..c5acbf9 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -1604,6 +1604,11 @@ struct cl_io_operations { struct cl_page_list *queue, int from, int to, cl_commit_cbt cb); /** + * Release active extent. + */ + void (*cio_extent_release)(const struct lu_env *env, + const struct cl_io_slice *slice); + /** * Decide maximum read ahead extent * * \pre io->ci_type == CIT_READ @@ -2415,6 +2420,7 @@ int cl_io_submit_sync (const struct lu_env *env, struct cl_io *io, int cl_io_commit_async (const struct lu_env *env, struct cl_io *io, struct cl_page_list *queue, int from, int to, cl_commit_cbt cb); +void cl_io_extent_release (const struct lu_env *env, struct cl_io *io); int cl_io_read_ahead (const struct lu_env *env, struct cl_io *io, pgoff_t start, struct cl_read_ahead *ra); void cl_io_rw_advance (const struct lu_env *env, struct cl_io *io, diff --git a/lustre/include/lustre_osc.h b/lustre/include/lustre_osc.h index de848ae..ebce916 100644 --- a/lustre/include/lustre_osc.h +++ b/lustre/include/lustre_osc.h @@ -679,6 +679,8 @@ int osc_io_commit_async(const struct lu_env *env, const struct cl_io_slice *ios, struct cl_page_list *qin, int from, int to, cl_commit_cbt cb); +void osc_io_extent_release(const struct lu_env *env, + const struct cl_io_slice *ios); int osc_io_iter_init(const struct lu_env *env, const struct cl_io_slice *ios); void osc_io_iter_fini(const struct lu_env *env, const struct cl_io_slice *ios); diff --git a/lustre/lov/lov_io.c b/lustre/lov/lov_io.c index 6f561e7..3a13802 100644 --- a/lustre/lov/lov_io.c +++ b/lustre/lov/lov_io.c @@ -1348,6 +1348,10 @@ static int lov_io_commit_async(const struct lu_env *env, break; from = 0; + + if (lov_comp_entry(index) != + lov_comp_entry(page->cp_lov_index)) + cl_io_extent_release(sub->sub_env, &sub->sub_io); } /* for error case, add the page back into the qin list */ diff --git a/lustre/mdc/mdc_dev.c b/lustre/mdc/mdc_dev.c index 75d44ba..24f3a27 100644 --- a/lustre/mdc/mdc_dev.c +++ b/lustre/mdc/mdc_dev.c @@ -1355,6 +1355,7 @@ static struct cl_io_operations mdc_io_ops = { .cio_read_ahead = mdc_io_read_ahead, .cio_submit = osc_io_submit, .cio_commit_async = osc_io_commit_async, + .cio_extent_release = osc_io_extent_release, }; int mdc_io_init(const struct lu_env *env, struct cl_object *obj, diff --git a/lustre/obdclass/cl_io.c b/lustre/obdclass/cl_io.c index e7eb452..7d42ff0 100644 --- a/lustre/obdclass/cl_io.c +++ b/lustre/obdclass/cl_io.c @@ -609,6 +609,20 @@ int cl_io_commit_async(const struct lu_env *env, struct cl_io *io, } EXPORT_SYMBOL(cl_io_commit_async); +void cl_io_extent_release(const struct lu_env *env, struct cl_io *io) +{ + const struct cl_io_slice *scan; + ENTRY; + + list_for_each_entry(scan, &io->ci_layers, cis_linkage) { + if (scan->cis_iop->cio_extent_release == NULL) + continue; + scan->cis_iop->cio_extent_release(env, scan); + } + EXIT; +} +EXPORT_SYMBOL(cl_io_extent_release); + /** * Submits a list of pages for immediate io. * diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index 47e56a7..9f964c1 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -373,6 +373,18 @@ int osc_io_commit_async(const struct lu_env *env, } EXPORT_SYMBOL(osc_io_commit_async); +void osc_io_extent_release(const struct lu_env *env, + const struct cl_io_slice *ios) +{ + struct osc_io *oio = cl2osc_io(env, ios); + + if (oio->oi_active != NULL) { + osc_extent_release(env, oio->oi_active); + oio->oi_active = NULL; + } +} +EXPORT_SYMBOL(osc_io_extent_release); + static bool osc_import_not_healthy(struct obd_import *imp) { return imp->imp_invalid || imp->imp_deactive || @@ -1231,7 +1243,8 @@ static const struct cl_io_operations osc_io_ops = { }, .cio_read_ahead = osc_io_read_ahead, .cio_submit = osc_io_submit, - .cio_commit_async = osc_io_commit_async + .cio_commit_async = osc_io_commit_async, + .cio_extent_release = osc_io_extent_release }; /***************************************************************************** -- 1.8.3.1