Commit 38b2dc0b authored by Oleg Drokin's avatar Oleg Drokin Committed by Greg Kroah-Hartman

staging/lustre/osc: Revert erroneous list_for_each_entry_safe use

commit cd15dd6e upstream.

I have been having a lot of unexplainable crashes in osc_lru_shrink
lately that I could not see a good explanation for and then I found
this patch that slip under the radar somehow that incorrectly
converted while loop for lru list iteration into
list_for_each_entry_safe totally ignoring that in the body of
the loop we drop spinlocks guarding this list and move list entries
around.
Not sure why it was not showing up right away, perhaps some of the
more recent LRU changes committed caused some extra pressure on this
code that finally highlighted the breakage.

Reverts: 8adddc36 ("staging: lustre: osc: Use list_for_each_entry_safe")
CC: Bhaktipriya Shridhar <bhaktipriya96@gmail.com>
Signed-off-by: default avatarOleg Drokin <green@linuxhacker.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bf6a9b31
...@@ -542,7 +542,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, ...@@ -542,7 +542,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
struct cl_object *clobj = NULL; struct cl_object *clobj = NULL;
struct cl_page **pvec; struct cl_page **pvec;
struct osc_page *opg; struct osc_page *opg;
struct osc_page *temp;
int maxscan = 0; int maxscan = 0;
long count = 0; long count = 0;
int index = 0; int index = 0;
...@@ -569,13 +568,15 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, ...@@ -569,13 +568,15 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
spin_lock(&cli->cl_lru_list_lock); spin_lock(&cli->cl_lru_list_lock);
maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list));
list_for_each_entry_safe(opg, temp, &cli->cl_lru_list, ops_lru) { while (!list_empty(&cli->cl_lru_list)) {
struct cl_page *page; struct cl_page *page;
bool will_free = false; bool will_free = false;
if (--maxscan < 0) if (--maxscan < 0)
break; break;
opg = list_entry(cli->cl_lru_list.next, struct osc_page,
ops_lru);
page = opg->ops_cl.cpl_page; page = opg->ops_cl.cpl_page;
if (lru_page_busy(cli, page)) { if (lru_page_busy(cli, page)) {
list_move_tail(&opg->ops_lru, &cli->cl_lru_list); list_move_tail(&opg->ops_lru, &cli->cl_lru_list);
......
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