aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Drokin <green@linuxhacker.ru>2016-12-06 22:53:48 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-12-07 05:41:16 -0500
commitcd15dd6ef4ea11df87f717b8b1b83aaa738ec8af (patch)
treeac4c77c30d7120cef6f6b6b149c2243e1959d2f6
parent0af72df267f2ed865c71a69fb2811ea6fa4736dc (diff)
staging/lustre/osc: Revert erroneous list_for_each_entry_safe use
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: 8adddc36b1fc ("staging: lustre: osc: Use list_for_each_entry_safe") CC: Bhaktipriya Shridhar <bhaktipriya96@gmail.com> Signed-off-by: Oleg Drokin <green@linuxhacker.ru> Cc: stable <stable@vger.kernel.org> # 4.6+ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_page.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index c5129d14f69c..e356e4af08e1 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -537,7 +537,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
537 struct cl_object *clobj = NULL; 537 struct cl_object *clobj = NULL;
538 struct cl_page **pvec; 538 struct cl_page **pvec;
539 struct osc_page *opg; 539 struct osc_page *opg;
540 struct osc_page *temp;
541 int maxscan = 0; 540 int maxscan = 0;
542 long count = 0; 541 long count = 0;
543 int index = 0; 542 int index = 0;
@@ -568,7 +567,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
568 if (force) 567 if (force)
569 cli->cl_lru_reclaim++; 568 cli->cl_lru_reclaim++;
570 maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); 569 maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list));
571 list_for_each_entry_safe(opg, temp, &cli->cl_lru_list, ops_lru) { 570 while (!list_empty(&cli->cl_lru_list)) {
572 struct cl_page *page; 571 struct cl_page *page;
573 bool will_free = false; 572 bool will_free = false;
574 573
@@ -578,6 +577,8 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
578 if (--maxscan < 0) 577 if (--maxscan < 0)
579 break; 578 break;
580 579
580 opg = list_entry(cli->cl_lru_list.next, struct osc_page,
581 ops_lru);
581 page = opg->ops_cl.cpl_page; 582 page = opg->ops_cl.cpl_page;
582 if (lru_page_busy(cli, page)) { 583 if (lru_page_busy(cli, page)) {
583 list_move_tail(&opg->ops_lru, &cli->cl_lru_list); 584 list_move_tail(&opg->ops_lru, &cli->cl_lru_list);