Commit 3fcfab16 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds
Browse files

[PATCH] separate bdi congestion functions from queue congestion functions



Separate out the concept of "queue congestion" from "backing-dev congestion".
Congestion is a backing-dev concept, not a queue concept.

The blk_* congestion functions are retained, as wrappers around the core
backing-dev congestion functions.

This proper layering is needed so that NFS can cleanly use the congestion
functions, and so that CONFIG_BLOCK=n actually links.

Cc: "Thomas Maier" <balagi@justmail.de>
Cc: "Jens Axboe" <jens.axboe@oracle.com>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: David Howells <dhowells@redhat.com>
Cc: Peter Osterlund <petero2@telia.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 79e2de4b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/highmem.h>
#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/backing-dev.h>
#include <asm/uaccess.h>
#include <asm/mmx.h>

@@ -741,7 +742,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from,

			if (retval == -ENOMEM && is_init(current)) {
				up_read(&current->mm->mmap_sem);
				blk_congestion_wait(WRITE, HZ/50);
				congestion_wait(WRITE, HZ/50);
				goto survive;
			}

+0 −71
Original line number Diff line number Diff line
@@ -56,11 +56,6 @@ static kmem_cache_t *requestq_cachep;
 */
static kmem_cache_t *iocontext_cachep;

static wait_queue_head_t congestion_wqh[2] = {
		__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
		__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
	};

/*
 * Controlling structure to kblockd
 */
@@ -112,37 +107,6 @@ static void blk_queue_congestion_threshold(struct request_queue *q)
	q->nr_congestion_off = nr;
}

/*
 * A queue has just exitted congestion.  Note this in the global counter of
 * congested queues, and wake up anyone who was waiting for requests to be
 * put back.
 */
void blk_clear_queue_congested(request_queue_t *q, int rw)
{
	enum bdi_state bit;
	wait_queue_head_t *wqh = &congestion_wqh[rw];

	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
	clear_bit(bit, &q->backing_dev_info.state);
	smp_mb__after_clear_bit();
	if (waitqueue_active(wqh))
		wake_up(wqh);
}
EXPORT_SYMBOL(blk_clear_queue_congested);

/*
 * A queue has just entered congestion.  Flag that in the queue's VM-visible
 * state flags and increment the global gounter of congested queues.
 */
void blk_set_queue_congested(request_queue_t *q, int rw)
{
	enum bdi_state bit;

	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
	set_bit(bit, &q->backing_dev_info.state);
}
EXPORT_SYMBOL(blk_set_queue_congested);

/**
 * blk_get_backing_dev_info - get the address of a queue's backing_dev_info
 * @bdev:	device
@@ -2755,41 +2719,6 @@ void blk_end_sync_rq(struct request *rq, int error)
}
EXPORT_SYMBOL(blk_end_sync_rq);

/**
 * blk_congestion_wait - wait for a queue to become uncongested
 * @rw: READ or WRITE
 * @timeout: timeout in jiffies
 *
 * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
 * If no queues are congested then just wait for the next request to be
 * returned.
 */
long blk_congestion_wait(int rw, long timeout)
{
	long ret;
	DEFINE_WAIT(wait);
	wait_queue_head_t *wqh = &congestion_wqh[rw];

	prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
	ret = io_schedule_timeout(timeout);
	finish_wait(wqh, &wait);
	return ret;
}

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
 */
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/crypto.h>
#include <linux/workqueue.h>
#include <linux/backing-dev.h>
#include <asm/atomic.h>
#include <linux/scatterlist.h>
#include <asm/page.h>
@@ -602,7 +603,7 @@ static void process_write(struct crypt_io *io)

		/* out of memory -> run queues */
		if (remaining)
			blk_congestion_wait(bio_data_dir(clone), HZ/100);
			congestion_wait(bio_data_dir(clone), HZ/100);
	}
}

+2 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
#include <linux/backing-dev.h>
#include <linux/blkdev.h>

int fat_generic_ioctl(struct inode *inode, struct file *filp,
@@ -118,7 +119,7 @@ static int fat_file_release(struct inode *inode, struct file *filp)
	if ((filp->f_mode & FMODE_WRITE) &&
	     MSDOS_SB(inode->i_sb)->options.flush) {
		fat_flush_inodes(inode->i_sb, inode, NULL);
		blk_congestion_wait(WRITE, HZ/10);
		congestion_wait(WRITE, HZ/10);
	}
	return 0;
}
+3 −1
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs_page.h>
#include <linux/backing-dev.h>

#include <asm/uaccess.h>
#include <linux/smp_lock.h>

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

Loading