diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-28 16:50:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-28 16:50:42 -0500 |
commit | d4928196fe9ec07d18139ba2735876b0c8aa738f (patch) | |
tree | a999ee3f18b0d724b2adb15ec72854e7ade164fa /kernel/fork.c | |
parent | bb04af0e2e5bcd8d1a5d7f7d5c704f7eb328f241 (diff) | |
parent | febffd61816ef6d4f84189468c1d47f1df55921e (diff) |
Merge branch 'cfq-ioc-share' of git://git.kernel.dk/linux-2.6-block
* 'cfq-ioc-share' of git://git.kernel.dk/linux-2.6-block:
cfq-iosched: kill some big inlines
cfq-iosched: relax IOPRIO_CLASS_IDLE restrictions
kernel: add CLONE_IO to specifically request sharing of IO contexts
io_context sharing - anticipatory changes
block: cfq: make the io contect sharing lockless
io_context sharing - cfq changes
io context sharing: preliminary support
ioprio: move io priority from task_struct to io_context
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 39d22b3357de..314f5101d2b0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/random.h> | 51 | #include <linux/random.h> |
52 | #include <linux/tty.h> | 52 | #include <linux/tty.h> |
53 | #include <linux/proc_fs.h> | 53 | #include <linux/proc_fs.h> |
54 | #include <linux/blkdev.h> | ||
54 | 55 | ||
55 | #include <asm/pgtable.h> | 56 | #include <asm/pgtable.h> |
56 | #include <asm/pgalloc.h> | 57 | #include <asm/pgalloc.h> |
@@ -791,6 +792,31 @@ out: | |||
791 | return error; | 792 | return error; |
792 | } | 793 | } |
793 | 794 | ||
795 | static int copy_io(unsigned long clone_flags, struct task_struct *tsk) | ||
796 | { | ||
797 | #ifdef CONFIG_BLOCK | ||
798 | struct io_context *ioc = current->io_context; | ||
799 | |||
800 | if (!ioc) | ||
801 | return 0; | ||
802 | /* | ||
803 | * Share io context with parent, if CLONE_IO is set | ||
804 | */ | ||
805 | if (clone_flags & CLONE_IO) { | ||
806 | tsk->io_context = ioc_task_link(ioc); | ||
807 | if (unlikely(!tsk->io_context)) | ||
808 | return -ENOMEM; | ||
809 | } else if (ioprio_valid(ioc->ioprio)) { | ||
810 | tsk->io_context = alloc_io_context(GFP_KERNEL, -1); | ||
811 | if (unlikely(!tsk->io_context)) | ||
812 | return -ENOMEM; | ||
813 | |||
814 | tsk->io_context->ioprio = ioc->ioprio; | ||
815 | } | ||
816 | #endif | ||
817 | return 0; | ||
818 | } | ||
819 | |||
794 | /* | 820 | /* |
795 | * Helper to unshare the files of the current task. | 821 | * Helper to unshare the files of the current task. |
796 | * We don't want to expose copy_files internals to | 822 | * We don't want to expose copy_files internals to |
@@ -1156,15 +1182,17 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1156 | goto bad_fork_cleanup_mm; | 1182 | goto bad_fork_cleanup_mm; |
1157 | if ((retval = copy_namespaces(clone_flags, p))) | 1183 | if ((retval = copy_namespaces(clone_flags, p))) |
1158 | goto bad_fork_cleanup_keys; | 1184 | goto bad_fork_cleanup_keys; |
1185 | if ((retval = copy_io(clone_flags, p))) | ||
1186 | goto bad_fork_cleanup_namespaces; | ||
1159 | retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); | 1187 | retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); |
1160 | if (retval) | 1188 | if (retval) |
1161 | goto bad_fork_cleanup_namespaces; | 1189 | goto bad_fork_cleanup_io; |
1162 | 1190 | ||
1163 | if (pid != &init_struct_pid) { | 1191 | if (pid != &init_struct_pid) { |
1164 | retval = -ENOMEM; | 1192 | retval = -ENOMEM; |
1165 | pid = alloc_pid(task_active_pid_ns(p)); | 1193 | pid = alloc_pid(task_active_pid_ns(p)); |
1166 | if (!pid) | 1194 | if (!pid) |
1167 | goto bad_fork_cleanup_namespaces; | 1195 | goto bad_fork_cleanup_io; |
1168 | 1196 | ||
1169 | if (clone_flags & CLONE_NEWPID) { | 1197 | if (clone_flags & CLONE_NEWPID) { |
1170 | retval = pid_ns_prepare_proc(task_active_pid_ns(p)); | 1198 | retval = pid_ns_prepare_proc(task_active_pid_ns(p)); |
@@ -1234,9 +1262,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1234 | /* Need tasklist lock for parent etc handling! */ | 1262 | /* Need tasklist lock for parent etc handling! */ |
1235 | write_lock_irq(&tasklist_lock); | 1263 | write_lock_irq(&tasklist_lock); |
1236 | 1264 | ||
1237 | /* for sys_ioprio_set(IOPRIO_WHO_PGRP) */ | ||
1238 | p->ioprio = current->ioprio; | ||
1239 | |||
1240 | /* | 1265 | /* |
1241 | * The task hasn't been attached yet, so its cpus_allowed mask will | 1266 | * The task hasn't been attached yet, so its cpus_allowed mask will |
1242 | * not be changed, nor will its assigned CPU. | 1267 | * not be changed, nor will its assigned CPU. |
@@ -1328,6 +1353,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1328 | bad_fork_free_pid: | 1353 | bad_fork_free_pid: |
1329 | if (pid != &init_struct_pid) | 1354 | if (pid != &init_struct_pid) |
1330 | free_pid(pid); | 1355 | free_pid(pid); |
1356 | bad_fork_cleanup_io: | ||
1357 | put_io_context(p->io_context); | ||
1331 | bad_fork_cleanup_namespaces: | 1358 | bad_fork_cleanup_namespaces: |
1332 | exit_task_namespaces(p); | 1359 | exit_task_namespaces(p); |
1333 | bad_fork_cleanup_keys: | 1360 | bad_fork_cleanup_keys: |