cfq-prio #2
Subsystems (6)
PATCH 1/1 cfq-prio #2
Hi,
Changes:
- Moved the hash lists to hlist instead of list
- class_io_data -> io_prio_data
- Account sectors in addition to requests.
- Cleanup the rbtree code
- quantum_io and quantum_idle_io settings. same as quantum and quantum_idle, just for sectors instead of requests.
Against bk-current.
===== arch/i386/kernel/entry.S 1.69 vs edited =====
arch/i386/kernel/entry.S +2 -0
@@ -880,5 +880,7 @@ .long sys_utimes .long sys_fadvise64_64 .long sys_ni_syscall /* sys_vserver */ + .long sys_ioprio_set + .long sys_ioprio_get nr_syscalls=(.-sys_call_table)/4
===== arch/ppc/kernel/misc.S 1.49 vs edited =====
arch/ppc/kernel/misc.S +2 -0
@@ -1385,3 +1385,5 @@ .long sys_statfs64 .long sys_fstatfs64 .long ppc_fadvise64_64 + .long sys_ioprio_set + .long sys_ioprio_get
===== drivers/block/Kconfig.iosched 1.2 vs edited =====
drivers/block/Kconfig.iosched +8 -0
@@ -27,3 +27,11 @@ a disk at any one time, its behaviour is almost identical to the anticipatory I/O scheduler and so is a good choice. +config IOSCHED_CFQ + bool "CFQ I/O scheduler" if EMBEDDED + default y + ---help--- + The CFQ I/O scheduler tries to distribute bandwidth equally + among all processes in the system, with the option of assigning + io priorities a process or process group. It should provide a fair + working environment, suitable for desktop systems.
===== drivers/block/Makefile 1.22 vs edited =====
drivers/block/Makefile +1 -0
@@ -18,6 +18,7 @@ obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o obj-$(CONFIG_IOSCHED_AS) += as-iosched.o obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o +obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o obj-$(CONFIG_BLK_DEV_FD98) += floppy98.o
===== drivers/block/elevator.c 1.52 vs edited =====
drivers/block/elevator.c +9 -1
@@ -302,6 +302,14 @@ e->elevator_put_req_fn (q, rq); } +void elv_set_congested (request_queue_t *q) +{ +elevator_t *e = &q->elevator; + +if (e->elevator_set_congested_fn) + e->elevator_set_congested_fn (q); +} +int elv_may_queue (request_queue_t *q,int rw) {elevator_t *e = &q->elevator;
@@ -309,7 +317,7 @@if (e->elevator_may_queue_fn)return e->elevator_may_queue_fn (q, rw); -return 0 ; +return 1 ; }void elv_completed_request (request_queue_t *q,struct request *rq)
===== drivers/block/ll_rw_blk.c 1.221 vs edited =====
drivers/block/ll_rw_blk.c +41 -12
92 lines not on this page · raw message
===== drivers/ide/Kconfig 1.30 vs edited =====
drivers/ide/Kconfig +7 -3
@@ -249,12 +249,17 @@ tristate "SCSI emulation support" depends on SCSI ---help--- + WARNING: ide-scsi is no longer needed for cd writing applications! + The 2.6 kernel supports direct writing to ide-cd, which eliminates + the need for ide-scsi + the entire scsi stack just for writing a + cd. The new method is more efficient in every way. + This will provide SCSI host adapter emulation for IDE ATAPI devices, and will allow you to use a SCSI device driver instead of a native ATAPI driver. This is useful if you have an ATAPI device for which no native - driver has been written (for example, an ATAPI PD-CD or CDR drive); + driver has been written (for example, an ATAPI PD-CD drive); you can then use this emulation together with an appropriate SCSI device driver. In order to do this, say Y here and to "SCSI support" and "SCSI generic support", below. You must then provide the kernel
@@ -262,8 +267,7 @@ documentation of your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time) for devices if you want the native EIDE sub-drivers to skip over the native support, so that - this SCSI emulation can be used instead. This is required for use of - CD-RW's. + this SCSI emulation can be used instead. Note that this option does NOT allow you to attach SCSI devices to a box that doesn't have a SCSI host adapter installed.
===== drivers/scsi/ide-scsi.c 1.32 vs edited =====
drivers/scsi/ide-scsi.c +6 -0
@@ -950,7 +950,13 @@ {idescsi_scsi_t *idescsi;struct Scsi_Host *host; +static int warned;int err; + +if (!warned && drive->media == ide_cdrom) { +printk (KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n" ); + warned =1 ; + } if (!strstr("ide-scsi", drive->driver_req) || !drive->present ||
===== include/asm-i386/unistd.h 1.30 vs edited =====
include/asm-i386/unistd.h +3 -1
@@ -279,8 +279,10 @@#define __NR_utimes 271#define __NR_fadvise64_64 272#define __NR_vserver 273 +#define __NR_ioprio_set 274 +#define __NR_ioprio_get 275 -#define NR_syscalls 274 +#define NR_syscalls 276/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
===== include/asm-ppc/unistd.h 1.26 vs edited =====
include/asm-ppc/unistd.h +3 -1
@@ -259,8 +259,10 @@#define __NR_statfs64 252#define __NR_fstatfs64 253#define __NR_fadvise64_64 254 +#define __NR_ioprio_set 255 +#define __NR_ioprio_get 256 -#define __NR_syscalls 255 +#define __NR_syscalls 257#define __NR (n) #n
===== include/asm-x86_64/unistd.h 1.18 vs edited =====
include/asm-x86_64/unistd.h +5 -1
@@ -532,8 +532,12 @@ __SYSCALL(__NR_utimes, sys_utimes)#define __NR_vserver 236 __SYSCALL(__NR_vserver, sys_ni_syscall) +#define __NR_ioprio_set 237 +__SYSCALL (__NR_ioprio_set, sys_ioprio_set); +#define __NR_ioprio_get 238 +__SYSCALL (__NR_ioprio_get, sys_ioprio_get); -#define __NR_syscall_max __NR_vserver +#define __NR_syscall_max __ioprio_get#ifndef __NO_STUBS/* user-visible error numbers are in the range -1 - -4095 */
===== include/linux/elevator.h 1.29 vs edited =====
include/linux/elevator.h +10 -0
@@ -17,6 +17,7 @@typedef struct request *(elevator_request_list_fn ) (request_queue_t *,struct request *);typedef void (elevator_completed_req_fn ) (request_queue_t *,struct request *);typedef int (elevator_may_queue_fn ) (request_queue_t *,int ); +typedef void (elevator_set_congested_fn ) (request_queue_t *);typedef int (elevator_set_req_fn ) (request_queue_t *,struct request *,int );typedef void (elevator_put_req_fn ) (request_queue_t *,struct request *);
@@ -45,6 +46,7 @@elevator_put_req_fn *elevator_put_req_fn;elevator_may_queue_fn *elevator_may_queue_fn; +elevator_set_congested_fn *elevator_set_congested_fn;elevator_init_fn *elevator_init_fn;elevator_exit_fn *elevator_exit_fn;
@@ -74,6 +76,7 @@extern int elv_register_queue (request_queue_t *q);extern void elv_unregister_queue (request_queue_t *q);extern int elv_may_queue (request_queue_t *,int ); +extern void elv_set_congested (request_queue_t *);extern void elv_completed_request (request_queue_t *,struct request *);extern int elv_set_request (request_queue_t *,struct request *,int );extern void elv_put_request (request_queue_t *,struct request *);
@@ -94,6 +97,11 @@*/ extern elevator_t iosched_as; +/* +* completely fair queueing I/O scheduler +*/ +extern elevator_t iosched_cfq; +extern int elevator_init (request_queue_t *,elevator_t *);extern void elevator_exit (request_queue_t *);extern inline int elv_rq_merge_ok (struct request *,struct bio *);
@@ -113,5 +121,7 @@#define ELEVATOR_INSERT_FRONT 1#define ELEVATOR_INSERT_BACK 2#define ELEVATOR_INSERT_SORT 3 + +#define RQ_ELV_DATA (rq) (rq)->elevator_private#endif
===== include/linux/fs.h 1.274 vs edited =====
include/linux/fs.h +11 -0
@@ -1408,5 +1408,16 @@return res; } +/* io priorities */ + +#define IOPRIO_NR 21 + +#define IOPRIO_IDLE 0 +#define IOPRIO_NORM 10 +#define IOPRIO_RT 20 + +asmlinkage int sys_ioprio_set(int ioprio); +asmlinkage int sys_ioprio_get(void); +#endif /* __KERNEL__ */ #endif /* _LINUX_FS_H */
===== include/linux/init_task.h 1.27 vs edited =====
include/linux/init_task.h +1 -0
@@ -108,6 +108,7 @@ .proc_lock = SPIN_LOCK_UNLOCKED, \ .switch_lock = SPIN_LOCK_UNLOCKED, \ .journal_info = NULL, \ + .ioprio = IOPRIO_NORM, \ }
===== include/linux/sched.h 1.175 vs edited =====
include/linux/sched.h +2 -0
@@ -462,6 +462,8 @@struct io_context *io_context; +int ioprio; +unsigned long ptrace_message;siginfo_t *last_siginfo;/* For ptrace use. */ };
===== kernel/fork.c 1.145 vs edited =====
kernel/fork.c +1 -0
@@ -1046,6 +1046,7 @@ }else link_pid (p, p->pids +PIDTYPE_TGID , &p->group_leader->pids[PIDTYPE_TGID ].pid); + p->ioprio = current->ioprio; nr_threads++;write_unlock_irq (&tasklist_lock); retval =0 ;
drivers/block/cfq-iosched.c new file +1207 -0
1,207 lines not on this page · raw message
Signature · 1 line
Jens Axboe
Quoted 3 lines · Jens Axboe
Hi,
Hi Jens
Quoted 12 lines
drivers/block/ll_rw_blk.c +4
-0@@ -1553,6 +1559,10 @@struct io_context *ioc =get_io_context (gfp_mask);spin_lock_irq (q->queue_lock); + +if (!elv_may_queue (q, rw)) + goto out_lock; +if (rl->count[rw]+1 >= q->nr_requests) {/* * The queue will fill after this allocation, so set it as
drivers/block/ll_rw_blk.c line 1579
Quoted 6 lines
drivers/block/ll_rw_blk.c +0
-2@@ -1566,15 +1576,12 @@ } } -if (blk_queue_full (q, rw) - && !ioc_batching (ioc) && !elv_may_queue (q, rw)) {
I know I hijacked elv_may_queue from you... any chance we could seperate these so our schedulers can live in peace? ;)
Maybe my version should be called elv_force_queue?
Quoted 25 lines · Nick Piggin
Quoted 3 lines · Jens Axboe
Hi,
Hi Jens
Quoted 15 lines
drivers/block/ll_rw_blk.c +4
-0@@ -1553,6 +1559,10 @@struct io_context *ioc =get_io_context (gfp_mask);spin_lock_irq (q->queue_lock); + +if (!elv_may_queue (q, rw)) + goto out_lock; +if (rl->count[rw]+1 >= q->nr_requests) {/* * The queue will fill after this allocation, so set it as @@ -1566,15 +1576,12 @@ } }
Quoted 6 lines
drivers/block/ll_rw_blk.c line 1585
Quoted 3 lines
drivers/block/ll_rw_blk.c +0
-2-if (blk_queue_full (q, rw) - && !ioc_batching (ioc) && !elv_may_queue (q, rw)) {I know I hijacked
elv_may_queuefrom you... any chance we could seperate these so our schedulers can live in peace? ;)
IOW, you completely broke it! I'm just changing it back to the original. When was this done, btw? Just discovered it when updating the patch. Pretty annoying...
Quoted 1 line
Maybe my version should be called
elv_force_queue?
I just hate to see more of these, really. The original idea for may_queue was just that, may this process queue io or not. We can make it return something else, though, to indicate whether the process must be able to queue. Is it really needed?
Signature · 1 line
Jens Axboe
Quoted 36 lines · Jens Axboe
Quoted 26 lines · Nick Piggin
Quoted 4 lines · Jens Axboe
Hi,
Hi Jens
Quoted 15 lines
drivers/block/ll_rw_blk.c +4
-0@@ -1553,6 +1559,10 @@struct io_context *ioc =get_io_context (gfp_mask);spin_lock_irq (q->queue_lock); + +if (!elv_may_queue (q, rw)) + goto out_lock; +if (rl->count[rw]+1 >= q->nr_requests) {/* * The queue will fill after this allocation, so set it as @@ -1566,15 +1576,12 @@ } }Quoted 7 lines
drivers/block/ll_rw_blk.c
Quoted 4 lines
drivers/block/ll_rw_blk.c +0
-2-if (blk_queue_full (q, rw) - && !ioc_batching (ioc) && !elv_may_queue (q, rw)) {I know I hijacked
elv_may_queuefrom you... any chance we could seperate these so our schedulers can live in peace? ;)
Quoted 4 lines
IOW, you completely broke it! I'm just changing it back to the original. When was this done, btw? Just discovered it when updating the patch. Pretty annoying...
You acked the change actually :P
I guess it was done in mainline when AS was merged.
Quoted 9 lines
Quoted 3 lines
Maybe my version should be called
elv_force_queue?I just hate to see more of these, really. The original idea for
may_queuewas just that, may this process queue io or not. We can make it return something else, though, to indicate whether the process must be able to queue. Is it really needed?
Its quite important. If the queue is full, and AS is waiting for a process to submit a request, its got a long wait.
Maybe a lower limit for per process nr_requests. Ie. you may queue if this queue has less than 128 requests _or_ you have less than 8 requests outstanding. This would solve my problem. It would also give you a much more appropriate scaling for server workloads, I think. Still, thats quite a change in behaviour (simple to code though).
Quoted 40 lines · Nick Piggin
Quoted 36 lines · Jens Axboe
Quoted 33 lines · Nick Piggin
Quoted 4 lines · Jens Axboe
Hi,
Hi Jens
Quoted 12 lines
drivers/block/ll_rw_blk.c +4
-0@@ -1553,6 +1559,10 @@struct io_context *ioc =get_io_context (gfp_mask);spin_lock_irq (q->queue_lock); + +if (!elv_may_queue (q, rw)) + goto out_lock; +if (rl->count[rw]+1 >= q->nr_requests) {/* * The queue will fill after this allocation, so set it as drivers/block/ll_rw_blk.c line 1580
Quoted 7 lines
drivers/block/ll_rw_blk.c +0
-2@@ -1566,15 +1576,12 @@ } } -if (blk_queue_full (q, rw) - && !ioc_batching (ioc) && !elv_may_queue (q, rw)) {I know I hijacked
elv_may_queuefrom you... any chance we could seperate these so our schedulers can live in peace? ;)
Quoted 7 lines
Quoted 4 lines
IOW, you completely broke it! I'm just changing it back to the original. When was this done, btw? Just discovered it when updating the patch. Pretty annoying...
You acked the change actually :P
I guess it was done in mainline when AS was merged.
Probably missed the semantic change of may_queue.
Quoted 9 lines
Quoted 8 lines
Quoted 2 lines
Maybe my version should be called
elv_force_queue?I just hate to see more of these, really. The original idea for
may_queuewas just that, may this process queue io or not. We can make it return something else, though, to indicate whether the process must be able to queue. Is it really needed?
Quoted 8 lines
Its quite important. If the queue is full, and AS is waiting for a process to submit a request, its got a long wait.
Maybe a lower limit for per process
nr_requests. Ie. you may queue if this queue has less than 128 requests _or_ you have less than 8 requests outstanding. This would solve my problem. It would also give you a much more appropriate scaling for server workloads, I think. Still, thats quite a change in behaviour (simple to code though).
That basically belongs inside your may_queue for the io scheduler, imo.
Signature · 1 line
Jens Axboe
Quoted 9 lines · Jens Axboe
Quoted 4 lines · Nick Piggin
You acked the change actually :P
I guess it was done in mainline when AS was merged.Probably missed the semantic change of
may_queue.
Anyway I won't bother digging up the email, its been done now.
Quoted 13 lines
Quoted 13 lines
Quoted 10 lines
Quoted 4 lines
Maybe my version should be called
elv_force_queue?I just hate to see more of these, really. The original idea for
may_queuewas just that, may this process queue io or not. We can make it return something else, though, to indicate whether the process must be able to queue. Is it really needed?Its quite important. If the queue is full, and AS is waiting for a process to submit a request, its got a long wait.
Quoted 9 lines
Quoted 6 lines
Maybe a lower limit for per process
nr_requests. Ie. you may queue if this queue has less than 128 requests _or_ you have less than 8 requests outstanding. This would solve my problem. It would also give you a much more appropriate scaling for server workloads, I think. Still, thats quite a change in behaviour (simple to code though).That basically belongs inside your
may_queuefor the io scheduler, imo.
You can force it to disallow the request, but you can't force it to allow one (depending on a successful memory allocation, of course).
Quoted 7 lines · Nick Piggin
Quoted 3 lines · Jens Axboe
Quoted 1 line · Nick Piggin
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
You acked the change actually :P
I guess it was done in mainline when AS was merged.Probably missed the semantic change of
may_queue.Anyway I won't bother digging up the email, its been done now.
Yeah too late to change now...
Quoted 20 lines
Quoted 20 lines
Quoted 19 lines
Quoted 9 lines
Quoted 3 lines
Maybe my version should be called
elv_force_queue?I just hate to see more of these, really. The original idea for
may_queuewas just that, may this process queue io or not. We can make it return something else, though, to indicate whether the process must be able to queue. Is it really needed?Its quite important. If the queue is full, and AS is waiting for a process to submit a request, its got a long wait.
Maybe a lower limit for per process
nr_requests. Ie. you may queue if this queue has less than 128 requests _or_ you have less than 8 requests outstanding. This would solve my problem. It would also give you a much more
appropriate scaling for server workloads, I think. Still, thats quite a change in behaviour (simple to code though).
Quoted 5 lines
Quoted 2 lines
That basically belongs inside your
may_queuefor the io scheduler, imo.You can force it to disallow the request, but you can't force it to allow one (depending on a successful memory allocation, of course).
Well that's back two mails then, make may_queue return whether you must queue, may queue, or can't queue.
Signature · 1 line
Jens Axboe
Quoted 23 lines · Jens Axboe
Quoted 21 lines · Nick Piggin
Quoted 17 lines · Jens Axboe
Quoted 11 lines · Nick Piggin
Quoted 1 line
Its quite important. If the queue is full, and AS is waiting for a process to submit a request, its got a long wait.
Maybe a lower limit for per process
nr_requests. Ie. you may queue if this queue has less than 128 requests _or_ you have less than 8 requests outstanding. This would solve my problem. It would also give you a much more appropriate scaling for server workloads, I think. Still, thats quite a change in behaviour (simple to code though).That basically belongs inside your
may_queuefor the io scheduler, imo.
Quoted 7 lines
Quoted 3 lines
You can force it to disallow the request, but you can't force it to allow one (depending on a successful memory allocation, of course).
Well that's back two mails then, make
may_queuereturn whether you must queue, may queue, or can't queue.
Yep, sounds good. I'll make a patch for it for 2.6.x > 0 sometime unless you beat me to it.
Quoted 20 lines · Nick Piggin
Quoted 20 lines
Quoted 19 lines
Quoted 13 lines
Quoted 4 lines
Its quite important. If the queue is full, and AS is waiting for a process
to submit a request, its got a long wait.Quoted 9 lines
Maybe a lower limit for per process
nr_requests. Ie. you may queue if this
queue has less than 128 requests _or_ you have less than 8 requests outstanding. This would solve my problem. It would also give you a much more
appropriate scaling for server workloads, I think. Still, thats quite a change in behaviour (simple to code though).Quoted 3 lines
That basically belongs inside your
may_queuefor the io scheduler, imo.You can force it to disallow the request, but you can't force it to allow one (depending on a successful memory allocation, of course).
Quoted 6 lines
Quoted 3 lines
Well that's back two mails then, make
may_queuereturn whether you must queue, may queue, or can't queue.Yep, sounds good. I'll make a patch for it for 2.6.x > 0 sometime unless you beat me to it.
I'll include it in the next cfq patch, then it can be submitted when the freeze unthaws a bit.
Signature · 1 line
Jens Axboe