CKRM e15 IO controller framework --- cfq-iosched.c remains unchanged for now, hence...
authorMarc Fiuczynski <mef@cs.princeton.edu>
Sat, 18 Sep 2004 11:48:31 +0000 (11:48 +0000)
committerMarc Fiuczynski <mef@cs.princeton.edu>
Sat, 18 Sep 2004 11:48:31 +0000 (11:48 +0000)
14 files changed:
arch/i386/kernel/entry.S
arch/ppc/kernel/misc.S
drivers/block/Makefile
drivers/block/elevator.c
drivers/block/ll_rw_blk.c
include/asm-i386/unistd.h
include/asm-ppc/unistd.h
include/asm-x86_64/unistd.h
include/linux/elevator.h
include/linux/fs.h
include/linux/init_task.h
include/linux/sched.h
init/Kconfig
kernel/fork.c

index bb91de3..3ac7418 100644 (file)
@@ -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)
index 017da44..81a7241 100644 (file)
@@ -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            
index 2654b5b..c66498b 100644 (file)
 # 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
index 35c9385..950eb99 100644 (file)
@@ -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)
index 5a570ba..49ff5e0 100644 (file)
@@ -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;
+}
+
index 72b388b..d27db19 100644 (file)
 #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 <asm-i386/errno.h> */
index 21774ed..64e443d 100644 (file)
 #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
 
index 311e25a..81e4e85 100644 (file)
@@ -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 */
index 27e8183..b42a9c4 100644 (file)
@@ -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
index e83d8e4..996b737 100644 (file)
@@ -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 */
index 9bcf2db..3a43ff4 100644 (file)
@@ -116,6 +116,7 @@ extern struct group_info init_groups;
        .vx_info        = NULL,                                         \
        .nid            = 0,                                            \
        .nx_info        = NULL,                                         \
+       .ioprio         = IOPRIO_NORM,                                  \
 }
 
 
index 93f3c32..2253b0c 100644 (file)
@@ -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.  */
 
index 89ec58c..b73e020 100644 (file)
@@ -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
index df85a9d..144311e 100644 (file)
@@ -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;