From 53ff9c90f6b1b50e2585d27e41d50f4762548dff Mon Sep 17 00:00:00 2001 From: Marc Fiuczynski Date: Sat, 18 Sep 2004 11:48:31 +0000 Subject: [PATCH] CKRM e15 IO controller framework --- cfq-iosched.c remains unchanged for now, hence the controller does nothing until we get a new, ported version of this file --- arch/i386/kernel/entry.S | 2 ++ arch/ppc/kernel/misc.S | 2 ++ drivers/block/Makefile | 3 ++- drivers/block/elevator.c | 10 ++++++++- drivers/block/ll_rw_blk.c | 45 ++++++++++++++++++++++++++++--------- include/asm-i386/unistd.h | 4 +++- include/asm-ppc/unistd.h | 4 +++- include/asm-x86_64/unistd.h | 6 ++++- include/linux/elevator.h | 5 +++++ include/linux/fs.h | 12 ++++++++++ include/linux/init_task.h | 1 + include/linux/sched.h | 2 ++ init/Kconfig | 13 +++++++++++ kernel/fork.c | 1 + 14 files changed, 94 insertions(+), 16 deletions(-) diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index bb91de327..3ac74183c 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -1030,5 +1030,7 @@ ENTRY(sys_call_table) .long sys_mq_notify .long sys_mq_getsetattr .long sys_ni_syscall /* reserved for kexec */ + .long sys_ioprio_set + .long sys_ioprio_get /* 285 */ syscall_table_size=(.-sys_call_table) diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 017da4476..81a72414a 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1450,3 +1450,5 @@ _GLOBAL(sys_call_table) .long sys_mq_notify .long sys_mq_getsetattr .long sys_ni_syscall /* 268 reserved for sys_kexec_load */ + .long sys_ioprio_set + .long sys_ioprio_get diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 2654b5b76..c66498bad 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -13,12 +13,13 @@ # kblockd threads # -obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o +obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o ckrm-iostub.o 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_CKRM_RES_BLKIO) += ckrm-io.o obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o obj-$(CONFIG_BLK_DEV_FD98) += floppy98.o diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c index 35c9385ac..950eb9923 100644 --- a/drivers/block/elevator.c +++ b/drivers/block/elevator.c @@ -339,6 +339,14 @@ void elv_put_request(request_queue_t *q, struct request *rq) 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; @@ -346,7 +354,7 @@ int elv_may_queue(request_queue_t *q, int rw) 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) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 5a570baa6..49ff5e0b7 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1594,6 +1594,10 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) 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 @@ -1607,15 +1611,12 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) } } - if (blk_queue_full(q, rw) - && !ioc_batching(ioc) && !elv_may_queue(q, rw)) { - /* - * The queue is full and the allocating process is not a - * "batcher", and not exempted by the IO scheduler - */ - spin_unlock_irq(q->queue_lock); - goto out; - } + /* + * The queue is full and the allocating process is not a + * "batcher", and not exempted by the IO scheduler + */ + if (blk_queue_full(q, rw) && !ioc_batching(ioc)) + goto out_lock; rl->count[rw]++; if (rl->count[rw] >= queue_congestion_on_threshold(q)) @@ -1633,8 +1634,7 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) */ spin_lock_irq(q->queue_lock); freed_request(q, rw); - spin_unlock_irq(q->queue_lock); - goto out; + goto out_lock; } if (ioc_batching(ioc)) @@ -1664,6 +1664,11 @@ static struct request *get_request(request_queue_t *q, int rw, int gfp_mask) out: put_io_context(ioc); return rq; +out_lock: + if (!rq) + elv_set_congested(q); + spin_unlock_irq(q->queue_lock); + goto out; } /* @@ -3168,3 +3173,21 @@ void blk_unregister_queue(struct gendisk *disk) kobject_put(&disk->kobj); } } + +asmlinkage int sys_ioprio_set(int ioprio) +{ + if (ioprio < IOPRIO_IDLE || ioprio > IOPRIO_RT) + return -EINVAL; + if (ioprio == IOPRIO_RT && !capable(CAP_SYS_ADMIN)) + return -EACCES; + + printk("%s: set ioprio %d\n", current->comm, ioprio); + current->ioprio = ioprio; + return 0; +} + +asmlinkage int sys_ioprio_get(void) +{ + return current->ioprio; +} + diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 72b388bf5..d27db1931 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -289,8 +289,10 @@ #define __NR_mq_notify (__NR_mq_open+4) #define __NR_mq_getsetattr (__NR_mq_open+5) #define __NR_sys_kexec_load 283 +#define __NR_ioprio_set 284 +#define __NR_ioprio_get 285 -#define NR_syscalls 284 +#define NR_syscalls 286 #ifndef __KERNEL_SYSCALLS_NO_ERRNO__ /* user-visible error numbers are in the range -1 - -124: see */ diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index 21774ed93..64e443d47 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h @@ -273,8 +273,10 @@ #define __NR_mq_notify 266 #define __NR_mq_getsetattr 267 #define __NR_kexec_load 268 +#define __NR_ioprio_set 269 +#define __NR_ioprio_get 270 -#define __NR_syscalls 269 +#define __NR_syscalls 271 #define __NR(n) #n diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 311e25a4f..81e4e85ba 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h @@ -552,8 +552,12 @@ __SYSCALL(__NR_mq_notify, sys_mq_notify) __SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) #define __NR_kexec_load 246 __SYSCALL(__NR_kexec_load, sys_ni_syscall) +#define __NR_ioprio_set 247 +__SYSCALL(__NR_ioprio_set, sys_ioprio_set); +#define __NR_ioprio_get 248 +__SYSCALL(__NR_ioprio_get, sys_ioprio_get); -#define __NR_syscall_max __NR_kexec_load +#define __NR_syscall_max __NR_ioprio_get #ifndef __NO_STUBS /* user-visible error numbers are in the range -1 - -4095 */ diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 27e8183f4..b42a9c4e2 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -17,6 +17,7 @@ typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *); 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 @@ struct elevator_s 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 struct request *elv_latter_request(request_queue_t *, struct request *); 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 *); @@ -119,4 +122,6 @@ extern int elv_try_last_merge(request_queue_t *, struct bio *); #define ELEVATOR_INSERT_BACK 2 #define ELEVATOR_INSERT_SORT 3 +#define RQ_ELV_DATA(rq) (rq)->elevator_private + #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index e83d8e4dd..996b7378e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1592,5 +1592,17 @@ static inline void free_secdata(void *secdata) { } #endif /* CONFIG_SECURITY */ +/* 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 */ diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 9bcf2db6d..3a43ff49b 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -116,6 +116,7 @@ extern struct group_info init_groups; .vx_info = NULL, \ .nid = 0, \ .nx_info = NULL, \ + .ioprio = IOPRIO_NORM, \ } diff --git a/include/linux/sched.h b/include/linux/sched.h index 93f3c3230..2253b0cc6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -570,6 +570,8 @@ struct task_struct { struct io_context *io_context; + int ioprio; + unsigned long ptrace_message; siginfo_t *last_siginfo; /* For ptrace use. */ diff --git a/init/Kconfig b/init/Kconfig index 89ec58c3f..b73e02043 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -178,6 +178,19 @@ config CKRM_CPU_MONITOR Say N if unsure, Y to use the feature. +config CKRM_RES_BLKIO + tristate " Disk I/O Resource Controller" + depends on CKRM_TYPE_TASKCLASS && IOSCHED_CFQ + default m + help + Provides a resource controller for best-effort block I/O + bandwidth control. The controller attempts this by proportional + servicing of requests in the I/O scheduler. However, seek + optimizations and reordering by device drivers/disk controllers may + alter the actual bandwidth delivered to a class. + + Say N if unsure, Y to use the feature. + config CKRM_TYPE_SOCKETCLASS bool "Class Manager for socket groups" depends on CKRM diff --git a/kernel/fork.c b/kernel/fork.c index df85a9daa..144311e8c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1128,6 +1128,7 @@ struct task_struct *copy_process(unsigned long clone_flags, } else link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid); + p->ioprio = current->ioprio; nr_threads++; /* p is copy of current */ vxi = p->vx_info; -- 2.47.0