From: Andrew Morton <akpm@zip.com.au>
To: "Jeff V. Merkey" <jmerkey@vger.timpanogas.org>
Cc: linux-kernel@vger.kernel.org, Jens Axboe <axboe@suse.de>
Subject: Re: queue_nr_requests needs to be selective
Date: Fri, 01 Mar 2002 16:49:47 -0800 [thread overview]
Message-ID: <3C8021A9.BB16E3FC@zip.com.au> (raw)
In-Reply-To: <20020301132254.A11528@vger.timpanogas.org> <3C7FE7DD.98121E87@zip.com.au>, <3C7FE7DD.98121E87@zip.com.au>; <20020301162016.A12413@vger.timpanogas.org> <3C800D66.F613BBAA@zip.com.au>, <3C800D66.F613BBAA@zip.com.au>; from akpm@zip.com.au on Fri, Mar 01, 2002 at 03:23:18PM -0800 <20020301172701.A12718@vger.timpanogas.org>
"Jeff V. Merkey" wrote:
>
> ...
> > OK. So would it suffice to make queue_nr_requests an argument to
> > a new blk_init_queue()?
> >
> > - blk_init_queue(q, sci_request);
> > + blk_init_queue_ng(q, sci_request, 1024);
> >
>
> Andrew,
>
> Yep. This will do it.
OK. The requirement seems eminently sensible to me. Could
you please verify the suitability of this patch? And if Jens
is OK with it, I'll stick it in the pile marked "Brazil".
--- 2.4.19-pre2/drivers/block/ll_rw_blk.c~blk-queue Fri Mar 1 15:30:13 2002
+++ 2.4.19-pre2-akpm/drivers/block/ll_rw_blk.c Fri Mar 1 15:57:07 2002
@@ -117,16 +117,6 @@ int * max_readahead[MAX_BLKDEV];
*/
int * max_sectors[MAX_BLKDEV];
-/*
- * The total number of requests in each queue.
- */
-static int queue_nr_requests;
-
-/*
- * The threshold around which we make wakeup decisions
- */
-static int batch_requests;
-
static inline int get_max_sectors(kdev_t dev)
{
if (!max_sectors[MAJOR(dev)])
@@ -180,7 +170,7 @@ static int __blk_cleanup_queue(struct re
**/
void blk_cleanup_queue(request_queue_t * q)
{
- int count = queue_nr_requests;
+ int count = q->nr_requests;
count -= __blk_cleanup_queue(&q->rq[READ]);
count -= __blk_cleanup_queue(&q->rq[WRITE]);
@@ -330,9 +320,11 @@ void generic_unplug_device(void *data)
spin_unlock_irqrestore(&io_request_lock, flags);
}
-static void blk_init_free_list(request_queue_t *q)
+static void blk_init_free_list(request_queue_t *q, int nr_requests)
{
struct request *rq;
+ struct sysinfo si;
+ int megs; /* Total memory, in megabytes */
int i;
INIT_LIST_HEAD(&q->rq[READ].free);
@@ -340,10 +332,17 @@ static void blk_init_free_list(request_q
q->rq[READ].count = 0;
q->rq[WRITE].count = 0;
+ si_meminfo(&si);
+ megs = si.totalram >> (20 - PAGE_SHIFT);
+ q->nr_requests = nr_requests;
+ if (megs < 32)
+ q->nr_requests /= 2;
+ q->batch_requests = q->nr_requests / 4;
+
/*
* Divide requests in half between read and write
*/
- for (i = 0; i < queue_nr_requests; i++) {
+ for (i = 0; i < nr_requests; i++) {
rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
if (rq == NULL) {
/* We'll get a `leaked requests' message from blk_cleanup_queue */
@@ -364,15 +363,17 @@ static void blk_init_free_list(request_q
static int __make_request(request_queue_t * q, int rw, struct buffer_head * bh);
/**
- * blk_init_queue - prepare a request queue for use with a block device
+ * __blk_init_queue - prepare a request queue for use with a block device
* @q: The &request_queue_t to be initialised
* @rfn: The function to be called to process requests that have been
* placed on the queue.
+ * @nr_requests: the number of request structures on each of the device's
+ * read and write request lists.
*
* Description:
* If a block device wishes to use the standard request handling procedures,
* which sorts requests and coalesces adjacent requests, then it must
- * call blk_init_queue(). The function @rfn will be called when there
+ * call __blk_init_queue(). The function @rfn will be called when there
* are requests on the queue that need to be processed. If the device
* supports plugging, then @rfn may not be called immediately when requests
* are available on the queue, but may be called at some time later instead.
@@ -392,15 +393,21 @@ static int __make_request(request_queue_
* whenever the given queue is unplugged. This behaviour can be changed with
* blk_queue_headactive().
*
+ * Your selected value of nr_requests will be scaled down for small
+ * machines. See blk_init_free_list().
+ *
+ * If nr_requests is less than 16, things will probably fail mysteriously.
+ *
* Note:
- * blk_init_queue() must be paired with a blk_cleanup_queue() call
+ * __blk_init_queue() must be paired with a blk_cleanup_queue() call
* when the block device is deactivated (such as at module unload).
**/
-void blk_init_queue(request_queue_t * q, request_fn_proc * rfn)
+void __blk_init_queue(request_queue_t * q,
+ request_fn_proc * rfn, int nr_requests)
{
INIT_LIST_HEAD(&q->queue_head);
elevator_init(&q->elevator, ELEVATOR_LINUS);
- blk_init_free_list(q);
+ blk_init_free_list(q, nr_requests);
q->request_fn = rfn;
q->back_merge_fn = ll_back_merge_fn;
q->front_merge_fn = ll_front_merge_fn;
@@ -610,7 +617,7 @@ void blkdev_release_request(struct reque
*/
if (q) {
list_add(&req->queue, &q->rq[rw].free);
- if (++q->rq[rw].count >= batch_requests &&
+ if (++q->rq[rw].count >= q->batch_requests &&
waitqueue_active(&q->wait_for_requests[rw]))
wake_up(&q->wait_for_requests[rw]);
}
@@ -802,7 +809,7 @@ get_rq:
* See description above __get_request_wait()
*/
if (rw_ahead) {
- if (q->rq[rw].count < batch_requests) {
+ if (q->rq[rw].count < q->batch_requests) {
spin_unlock_irq(&io_request_lock);
goto end_io;
}
@@ -1149,12 +1156,9 @@ void end_that_request_last(struct reques
blkdev_release_request(req);
}
-#define MB(kb) ((kb) << 10)
-
int __init blk_dev_init(void)
{
struct blk_dev_struct *dev;
- int total_ram;
request_cachep = kmem_cache_create("blkdev_requests",
sizeof(struct request),
@@ -1170,22 +1174,6 @@ int __init blk_dev_init(void)
memset(max_readahead, 0, sizeof(max_readahead));
memset(max_sectors, 0, sizeof(max_sectors));
- total_ram = nr_free_pages() << (PAGE_SHIFT - 10);
-
- /*
- * Free request slots per queue.
- * (Half for reads, half for writes)
- */
- queue_nr_requests = 64;
- if (total_ram > MB(32))
- queue_nr_requests = 128;
-
- /*
- * Batch frees according to queue length
- */
- batch_requests = queue_nr_requests/4;
- printk("block: %d slots per queue, batch=%d\n", queue_nr_requests, batch_requests);
-
#ifdef CONFIG_AMIGA_Z2RAM
z2_init();
#endif
@@ -1296,7 +1284,7 @@ int __init blk_dev_init(void)
EXPORT_SYMBOL(io_request_lock);
EXPORT_SYMBOL(end_that_request_first);
EXPORT_SYMBOL(end_that_request_last);
-EXPORT_SYMBOL(blk_init_queue);
+EXPORT_SYMBOL(__blk_init_queue);
EXPORT_SYMBOL(blk_get_queue);
EXPORT_SYMBOL(blk_cleanup_queue);
EXPORT_SYMBOL(blk_queue_headactive);
--- 2.4.19-pre2/include/linux/blkdev.h~blk-queue Fri Mar 1 15:31:09 2002
+++ 2.4.19-pre2-akpm/include/linux/blkdev.h Fri Mar 1 15:41:50 2002
@@ -79,6 +79,16 @@ struct request_queue
struct request_list rq[2];
/*
+ * The total number of requests on each queue
+ */
+ int nr_requests;
+
+ /*
+ * Batching threshold for sleep/wakeup decisions
+ */
+ int batch_requests;
+
+ /*
* Together with queue_head for cacheline sharing
*/
struct list_head queue_head;
@@ -157,7 +167,8 @@ extern void blkdev_release_request(struc
/*
* Access functions for manipulating queue properties
*/
-extern void blk_init_queue(request_queue_t *, request_fn_proc *);
+#define blk_init_queue(q, fn) __blk_init_queue(q, fn, 128)
+extern void __blk_init_queue(request_queue_t *, request_fn_proc *, int);
extern void blk_cleanup_queue(request_queue_t *);
extern void blk_queue_headactive(request_queue_t *, int);
extern void blk_queue_make_request(request_queue_t *, make_request_fn *);
-
next prev parent reply other threads:[~2002-03-02 0:51 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-03-01 20:22 queue_nr_requests needs to be selective Jeff V. Merkey
2002-03-01 20:43 ` Andrew Morton
2002-03-01 21:03 ` Alan Cox
2002-03-01 23:22 ` Jeff V. Merkey
2002-03-01 23:20 ` Jeff V. Merkey
2002-03-01 23:23 ` Andrew Morton
2002-03-02 0:27 ` Jeff V. Merkey
2002-03-02 0:49 ` Andrew Morton [this message]
2002-03-02 2:16 ` Jeff V. Merkey
2002-03-02 3:50 ` Andrew Morton
2002-03-02 4:34 ` Jeff V. Merkey
2002-03-02 7:33 ` Jeff V. Merkey
2002-03-02 9:10 ` Jens Axboe
2002-03-02 9:22 ` Andrew Morton
2002-03-04 9:09 ` Jens Axboe
2002-03-02 0:51 ` Mike Anderson
2002-03-02 4:39 ` Jeff V. Merkey
2002-03-02 5:59 ` Jeff V. Merkey
2002-03-02 6:01 ` Jeff V. Merkey
2002-03-02 6:16 ` Jeff V. Merkey
2002-03-04 7:16 ` Mike Anderson
2002-03-04 17:39 ` Jeff V. Merkey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3C8021A9.BB16E3FC@zip.com.au \
--to=akpm@zip.com.au \
--cc=axboe@suse.de \
--cc=jmerkey@vger.timpanogas.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox