Bläddra i källkod

Add a real API for dealing with blk_congestion_wait()

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Trond Myklebust 18 år sedan
förälder
incheckning
275a082fe9
5 ändrade filer med 24 tillägg och 0 borttagningar
  1. 12 0
      block/ll_rw_blk.c
  2. 1 0
      fs/nfs/write.c
  3. 1 0
      include/linux/blkdev.h
  4. 1 0
      include/linux/writeback.h
  5. 9 0
      mm/page-writeback.c

+ 12 - 0
block/ll_rw_blk.c

@@ -2734,6 +2734,18 @@ long blk_congestion_wait(int rw, long timeout)
 
 
 EXPORT_SYMBOL(blk_congestion_wait);
 EXPORT_SYMBOL(blk_congestion_wait);
 
 
+/**
+ * blk_congestion_end - wake up sleepers on a congestion queue
+ * @rw: READ or WRITE
+ */
+void blk_congestion_end(int rw)
+{
+	wait_queue_head_t *wqh = &congestion_wqh[rw];
+
+	if (waitqueue_active(wqh))
+		wake_up(wqh);
+}
+
 /*
 /*
  * Has to be called with the request spinlock acquired
  * Has to be called with the request spinlock acquired
  */
  */

+ 1 - 0
fs/nfs/write.c

@@ -396,6 +396,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
 out:
 out:
 	clear_bit(BDI_write_congested, &bdi->state);
 	clear_bit(BDI_write_congested, &bdi->state);
 	wake_up_all(&nfs_write_congestion);
 	wake_up_all(&nfs_write_congestion);
+	writeback_congestion_end();
 	return err;
 	return err;
 }
 }
 
 

+ 1 - 0
include/linux/blkdev.h

@@ -746,6 +746,7 @@ extern void blk_queue_free_tags(request_queue_t *);
 extern int blk_queue_resize_tags(request_queue_t *, int);
 extern int blk_queue_resize_tags(request_queue_t *, int);
 extern void blk_queue_invalidate_tags(request_queue_t *);
 extern void blk_queue_invalidate_tags(request_queue_t *);
 extern long blk_congestion_wait(int rw, long timeout);
 extern long blk_congestion_wait(int rw, long timeout);
+extern void blk_congestion_end(int rw);
 
 
 extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
 extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
 extern int blkdev_issue_flush(struct block_device *, sector_t *);
 extern int blkdev_issue_flush(struct block_device *, sector_t *);

+ 1 - 0
include/linux/writeback.h

@@ -85,6 +85,7 @@ int wakeup_pdflush(long nr_pages);
 void laptop_io_completion(void);
 void laptop_io_completion(void);
 void laptop_sync_completion(void);
 void laptop_sync_completion(void);
 void throttle_vm_writeout(void);
 void throttle_vm_writeout(void);
+void writeback_congestion_end(void);
 
 
 /* These are exported to sysctl. */
 /* These are exported to sysctl. */
 extern int dirty_background_ratio;
 extern int dirty_background_ratio;

+ 9 - 0
mm/page-writeback.c

@@ -802,6 +802,15 @@ int test_set_page_writeback(struct page *page)
 }
 }
 EXPORT_SYMBOL(test_set_page_writeback);
 EXPORT_SYMBOL(test_set_page_writeback);
 
 
+/*
+ * Wakes up tasks that are being throttled due to writeback congestion
+ */
+void writeback_congestion_end(void)
+{
+	blk_congestion_end(WRITE);
+}
+EXPORT_SYMBOL(writeback_congestion_end);
+
 /*
 /*
  * Return true if any of the pages in the mapping are marged with the
  * Return true if any of the pages in the mapping are marged with the
  * passed tag.
  * passed tag.