diff options
-rw-r--r-- | fs/fs-writeback.c | 17 |
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 | ||
259 | static atomic_t isw_nr_in_flight = ATOMIC_INIT(0); | 260 | static atomic_t isw_nr_in_flight = ATOMIC_INIT(0); |
260 | static struct workqueue_struct *isw_wq; | 261 | static 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 | ||
558 | out_free: | 553 | out_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); |
562 | out_unlock: | ||
563 | up_read(&bdi->wb_switch_rwsem); | ||
564 | } | 557 | } |
565 | 558 | ||
566 | /** | 559 | /** |