Commit 7a787c25 authored by Hongchao Zhang's avatar Hongchao Zhang Committed by Greg Kroah-Hartman

staging: lustre: obdclass: guarantee all keys filled

In keys_fill, the key_set_version could be changed after
the keys are filled, then the keys in this context won't
be refilled by the following lu_context_refill for its
version is equal to the current key_set_version.

In lu_context_refill, the key_set_version should be protected
before comparing it to version stored in the lu_context.
Signed-off-by: default avatarHongchao Zhang <hongchao.zhang@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-8346
Reviewed-on: https://review.whamcloud.com/26099
Reviewed-on: https://review.whamcloud.com/27448
Reviewed-on: https://review.whamcloud.com/27994Reviewed-by: default avatarPatrick Farrell <paf@cray.com>
Reviewed-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: default avatarMike Pershin <mike.pershin@intel.com>
Reviewed-by: default avatarFan Yong <fan.yong@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 369a6fec
...@@ -1396,8 +1396,8 @@ void lu_context_key_degister(struct lu_context_key *key) ...@@ -1396,8 +1396,8 @@ void lu_context_key_degister(struct lu_context_key *key)
lu_context_key_quiesce(key); lu_context_key_quiesce(key);
++key_set_version;
write_lock(&lu_keys_guard); write_lock(&lu_keys_guard);
++key_set_version;
key_fini(&lu_shrink_env.le_ctx, key->lct_index); key_fini(&lu_shrink_env.le_ctx, key->lct_index);
/** /**
...@@ -1556,15 +1556,18 @@ void lu_context_key_quiesce(struct lu_context_key *key) ...@@ -1556,15 +1556,18 @@ void lu_context_key_quiesce(struct lu_context_key *key)
list_for_each_entry(ctx, &lu_context_remembered, lc_remember) list_for_each_entry(ctx, &lu_context_remembered, lc_remember)
key_fini(ctx, key->lct_index); key_fini(ctx, key->lct_index);
write_unlock(&lu_keys_guard);
++key_set_version; ++key_set_version;
write_unlock(&lu_keys_guard);
} }
} }
void lu_context_key_revive(struct lu_context_key *key) void lu_context_key_revive(struct lu_context_key *key)
{ {
write_lock(&lu_keys_guard);
key->lct_tags &= ~LCT_QUIESCENT; key->lct_tags &= ~LCT_QUIESCENT;
++key_set_version; ++key_set_version;
write_unlock(&lu_keys_guard);
} }
static void keys_fini(struct lu_context *ctx) static void keys_fini(struct lu_context *ctx)
...@@ -1583,6 +1586,7 @@ static void keys_fini(struct lu_context *ctx) ...@@ -1583,6 +1586,7 @@ static void keys_fini(struct lu_context *ctx)
static int keys_fill(struct lu_context *ctx) static int keys_fill(struct lu_context *ctx)
{ {
unsigned int pre_version;
unsigned int i; unsigned int i;
/* /*
...@@ -1596,8 +1600,10 @@ static int keys_fill(struct lu_context *ctx) ...@@ -1596,8 +1600,10 @@ static int keys_fill(struct lu_context *ctx)
*/ */
read_lock(&lu_keys_guard); read_lock(&lu_keys_guard);
atomic_inc(&lu_key_initing_cnt); atomic_inc(&lu_key_initing_cnt);
pre_version = key_set_version;
read_unlock(&lu_keys_guard); read_unlock(&lu_keys_guard);
refill:
LINVRNT(ctx->lc_value); LINVRNT(ctx->lc_value);
for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) { for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
struct lu_context_key *key; struct lu_context_key *key;
...@@ -1638,9 +1644,17 @@ static int keys_fill(struct lu_context *ctx) ...@@ -1638,9 +1644,17 @@ static int keys_fill(struct lu_context *ctx)
if (key->lct_exit) if (key->lct_exit)
ctx->lc_tags |= LCT_HAS_EXIT; ctx->lc_tags |= LCT_HAS_EXIT;
} }
ctx->lc_version = key_set_version;
} }
read_lock(&lu_keys_guard);
if (pre_version != key_set_version) {
pre_version = key_set_version;
read_unlock(&lu_keys_guard);
goto refill;
}
ctx->lc_version = key_set_version;
atomic_dec(&lu_key_initing_cnt); atomic_dec(&lu_key_initing_cnt);
read_unlock(&lu_keys_guard);
return 0; return 0;
} }
...@@ -1749,7 +1763,14 @@ EXPORT_SYMBOL(lu_context_exit); ...@@ -1749,7 +1763,14 @@ EXPORT_SYMBOL(lu_context_exit);
*/ */
int lu_context_refill(struct lu_context *ctx) int lu_context_refill(struct lu_context *ctx)
{ {
return likely(ctx->lc_version == key_set_version) ? 0 : keys_fill(ctx); read_lock(&lu_keys_guard);
if (likely(ctx->lc_version == key_set_version)) {
read_unlock(&lu_keys_guard);
return 0;
}
read_unlock(&lu_keys_guard);
return keys_fill(ctx);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment