]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/fs-writeback.c
power_supply: Add support for tps65217-charger.
[karo-tx-linux.git] / fs / fs-writeback.c
index 24489126f8ca1144441ad853ac48ac275d439e5e..091a36444972fa0b746118b0cc58ca2a3dcaa97f 100644 (file)
@@ -1380,6 +1380,10 @@ static long writeback_chunk_size(struct bdi_writeback *wb,
  * Write a portion of b_io inodes which belong to @sb.
  *
  * Return the number of pages and/or inodes written.
+ *
+ * NOTE! This is called with wb->list_lock held, and will
+ * unlock and relock that for each inode it ends up doing
+ * IO for.
  */
 static long writeback_sb_inodes(struct super_block *sb,
                                struct bdi_writeback *wb,
@@ -1398,9 +1402,7 @@ static long writeback_sb_inodes(struct super_block *sb,
        unsigned long start_time = jiffies;
        long write_chunk;
        long wrote = 0;  /* count both pages and inodes */
-       struct blk_plug plug;
 
-       blk_start_plug(&plug);
        while (!list_empty(&wb->b_io)) {
                struct inode *inode = wb_inode(wb->b_io.prev);
 
@@ -1479,6 +1481,21 @@ static long writeback_sb_inodes(struct super_block *sb,
                wbc_detach_inode(&wbc);
                work->nr_pages -= write_chunk - wbc.nr_to_write;
                wrote += write_chunk - wbc.nr_to_write;
+
+               if (need_resched()) {
+                       /*
+                        * We're trying to balance between building up a nice
+                        * long list of IOs to improve our merge rate, and
+                        * getting those IOs out quickly for anyone throttling
+                        * in balance_dirty_pages().  cond_resched() doesn't
+                        * unplug, so get our IOs out the door before we
+                        * give up the CPU.
+                        */
+                       blk_flush_plug(current);
+                       cond_resched();
+               }
+
+
                spin_lock(&wb->list_lock);
                spin_lock(&inode->i_lock);
                if (!(inode->i_state & I_DIRTY_ALL))
@@ -1486,7 +1503,7 @@ static long writeback_sb_inodes(struct super_block *sb,
                requeue_inode(inode, wb, &wbc);
                inode_sync_complete(inode);
                spin_unlock(&inode->i_lock);
-               cond_resched_lock(&wb->list_lock);
+
                /*
                 * bail out to wb_writeback() often enough to check
                 * background threshold and other termination conditions.
@@ -1498,7 +1515,6 @@ static long writeback_sb_inodes(struct super_block *sb,
                                break;
                }
        }
-       blk_finish_plug(&plug);
        return wrote;
 }
 
@@ -1545,12 +1561,15 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages,
                .range_cyclic   = 1,
                .reason         = reason,
        };
+       struct blk_plug plug;
 
+       blk_start_plug(&plug);
        spin_lock(&wb->list_lock);
        if (list_empty(&wb->b_io))
                queue_io(wb, &work);
        __writeback_inodes_wb(wb, &work);
        spin_unlock(&wb->list_lock);
+       blk_finish_plug(&plug);
 
        return nr_pages - work.nr_pages;
 }
@@ -1578,10 +1597,12 @@ static long wb_writeback(struct bdi_writeback *wb,
        unsigned long oldest_jif;
        struct inode *inode;
        long progress;
+       struct blk_plug plug;
 
        oldest_jif = jiffies;
        work->older_than_this = &oldest_jif;
 
+       blk_start_plug(&plug);
        spin_lock(&wb->list_lock);
        for (;;) {
                /*
@@ -1661,6 +1682,7 @@ static long wb_writeback(struct bdi_writeback *wb,
                }
        }
        spin_unlock(&wb->list_lock);
+       blk_finish_plug(&plug);
 
        return nr_pages - work->nr_pages;
 }