summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fs-writeback.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 025a63894cf0..fddd8abd839a 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -255,6 +255,7 @@ static void wb_wait_for_completion(struct backing_dev_info *bdi,
255 /* if foreign slots >= 8, switch */ 255 /* if foreign slots >= 8, switch */
256#define WB_FRN_HIST_MAX_SLOTS (WB_FRN_HIST_THR_SLOTS / 2 + 1) 256#define WB_FRN_HIST_MAX_SLOTS (WB_FRN_HIST_THR_SLOTS / 2 + 1)
257 /* one round can affect upto 5 slots */ 257 /* one round can affect upto 5 slots */
258#define WB_FRN_MAX_IN_FLIGHT 1024 /* don't queue too many concurrently */
258 259
259static atomic_t isw_nr_in_flight = ATOMIC_INIT(0); 260static atomic_t isw_nr_in_flight = ATOMIC_INIT(0);
260static struct workqueue_struct *isw_wq; 261static struct workqueue_struct *isw_wq;
@@ -507,18 +508,13 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
507 if (inode->i_state & I_WB_SWITCH) 508 if (inode->i_state & I_WB_SWITCH)
508 return; 509 return;
509 510
510 /* 511 /* avoid queueing a new switch if too many are already in flight */
511 * Avoid starting new switches while sync_inodes_sb() is in 512 if (atomic_read(&isw_nr_in_flight) > WB_FRN_MAX_IN_FLIGHT)
512 * progress. Otherwise, if the down_write protected issue path
513 * blocks heavily, we might end up starting a large number of
514 * switches which will block on the rwsem.
515 */
516 if (!down_read_trylock(&bdi->wb_switch_rwsem))
517 return; 513 return;
518 514
519 isw = kzalloc(sizeof(*isw), GFP_ATOMIC); 515 isw = kzalloc(sizeof(*isw), GFP_ATOMIC);
520 if (!isw) 516 if (!isw)
521 goto out_unlock; 517 return;
522 518
523 /* find and pin the new wb */ 519 /* find and pin the new wb */
524 rcu_read_lock(); 520 rcu_read_lock();
@@ -552,15 +548,12 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
552 call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn); 548 call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
553 549
554 atomic_inc(&isw_nr_in_flight); 550 atomic_inc(&isw_nr_in_flight);
555 551 return;
556 goto out_unlock;
557 552
558out_free: 553out_free:
559 if (isw->new_wb) 554 if (isw->new_wb)
560 wb_put(isw->new_wb); 555 wb_put(isw->new_wb);
561 kfree(isw); 556 kfree(isw);
562out_unlock:
563 up_read(&bdi->wb_switch_rwsem);
564} 557}
565 558
566/** 559/**