From bcabadc92e1212b8397438e798ba7d47ee67f5fc Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Tue, 25 Nov 2014 05:02:28 +0800 Subject: [PATCH] LU-6138 lfsck: set async windows size properly If the async windows size is set as zero, then the LFSCK main engine on the MDT will pre-load objects as fast as possible. Under such case, if the peer server(s) cannot handle the pre-load requests in time, it will cause a lot of pre-load requests waiting on the MDT as to memory pressure. To avoid such trouble, we will forbid to set the LFSCK async windows size as zero or other too large (> LFSCK_ASYNC_WIN_MAX) valid. Signed-off-by: Fan Yong Change-Id: I3468236a4a0705ea60b49704583b051c99c77cd5 Reviewed-on: http://review.whamcloud.com/13818 Tested-by: Jenkins Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Tested-by: Maloo --- lustre/lfsck/lfsck_bookmark.c | 18 +++++++++++++++++- lustre/lfsck/lfsck_engine.c | 5 +---- lustre/lfsck/lfsck_layout.c | 1 - lustre/lfsck/lfsck_lib.c | 10 ++++------ lustre/lfsck/lfsck_namespace.c | 1 - lustre/utils/lustre_lfsck.c | 11 ++++------- 6 files changed, 26 insertions(+), 20 deletions(-) diff --git a/lustre/lfsck/lfsck_bookmark.c b/lustre/lfsck/lfsck_bookmark.c index 15a0afd..0b055db 100644 --- a/lustre/lfsck/lfsck_bookmark.c +++ b/lustre/lfsck/lfsck_bookmark.c @@ -182,8 +182,20 @@ int lfsck_bookmark_setup(const struct lu_env *env, lfsck->li_bookmark_obj = obj; rc = lfsck_bookmark_load(env, lfsck); - if (rc == -ENODATA) + if (rc == 0) { + struct lfsck_bookmark *mb = &lfsck->li_bookmark_ram; + + /* It is upgraded from old release, set it as + * LFSCK_ASYNC_WIN_DEFAULT to avoid memory pressure. */ + if (unlikely(mb->lb_async_windows == 0)) { + mb->lb_async_windows = LFSCK_ASYNC_WIN_DEFAULT; + mutex_lock(&lfsck->li_mutex); + rc = lfsck_bookmark_store(env, lfsck); + mutex_unlock(&lfsck->li_mutex); + } + } else if (rc == -ENODATA) { rc = lfsck_bookmark_init(env, lfsck); + } RETURN(rc); } @@ -314,6 +326,10 @@ int lfsck_set_param(const struct lu_env *env, struct lfsck_instance *lfsck, } if (start->ls_valid & LSV_ASYNC_WINDOWS) { + if (start->ls_async_windows < 1 || + start->ls_async_windows > LFSCK_ASYNC_WIN_MAX) + return -EINVAL; + if (bk->lb_async_windows != start->ls_async_windows) { bk->lb_async_windows = start->ls_async_windows; dirty = true; diff --git a/lustre/lfsck/lfsck_engine.c b/lustre/lfsck/lfsck_engine.c index 0ed0b35..7f1e1bc 100644 --- a/lustre/lfsck/lfsck_engine.c +++ b/lustre/lfsck/lfsck_engine.c @@ -1636,10 +1636,7 @@ int lfsck_assistant_engine(void *args) /* Wake up the main engine thread only when the list * is empty or half of the prefetched items have been * handled to avoid too frequent thread schedule. */ - if (lad->lad_prefetched == 0 || - (bk->lb_async_windows != 0 && - bk->lb_async_windows / 2 == - lad->lad_prefetched)) + if (lad->lad_prefetched <= (bk->lb_async_windows / 2)) wakeup = true; spin_unlock(&lad->lad_lock); if (wakeup) diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c index 70d6932..bd2e1d7 100644 --- a/lustre/lfsck/lfsck_layout.c +++ b/lustre/lfsck/lfsck_layout.c @@ -4218,7 +4218,6 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env, continue; l_wait_event(mthread->t_ctl_waitq, - bk->lb_async_windows == 0 || lad->lad_prefetched < bk->lb_async_windows || !thread_is_running(mthread) || thread_is_stopped(athread), diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index b64354d..6a9e7e0 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -2451,12 +2451,10 @@ int lfsck_set_windows(struct dt_device *key, int val) lfsck = lfsck_instance_find(key, true, false); if (likely(lfsck != NULL)) { - if (val > LFSCK_ASYNC_WIN_MAX) { - CWARN("%s: Too large async window size, which " - "may cause memory issues. The valid range " - "is [0 - %u]. If you do not want to restrict " - "the window size for async requests pipeline, " - "just set it as 0.\n", + if (val < 1 || val > LFSCK_ASYNC_WIN_MAX) { + CWARN("%s: invalid async windows size that may " + "cause memory issues. The valid range is " + "[1 - %u].\n", lfsck_lfsck2name(lfsck), LFSCK_ASYNC_WIN_MAX); rc = -EINVAL; } else if (lfsck->li_bookmark_ram.lb_async_windows != val) { diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index 73358a5..83250b6 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -4118,7 +4118,6 @@ static int lfsck_namespace_exec_dir(const struct lu_env *env, bool wakeup = false; l_wait_event(mthread->t_ctl_waitq, - bk->lb_async_windows == 0 || lad->lad_prefetched < bk->lb_async_windows || !thread_is_running(mthread) || thread_is_stopped(athread), diff --git a/lustre/utils/lustre_lfsck.c b/lustre/utils/lustre_lfsck.c index abaa539..3237680 100644 --- a/lustre/utils/lustre_lfsck.c +++ b/lustre/utils/lustre_lfsck.c @@ -272,14 +272,11 @@ bad_type: } case 'w': val = atoi(optarg); - if (val < 0 || val > LFSCK_ASYNC_WIN_MAX) { + if (val < 1 || val > LFSCK_ASYNC_WIN_MAX) { fprintf(stderr, - "Too large async window size, " - "which may cause memory issues. " - "The valid range is [0 - %u]. " - "If you do not want to restrict " - "the window size for async reqeusts " - "pipeline, just set it as 0.\n", + "Invalid async window size that " + "may cause memory issues. The valid " + "range is [1 - %u].\n", LFSCK_ASYNC_WIN_MAX); return -EINVAL; } -- 1.8.3.1