diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 18:25:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 18:25:33 -0400 |
commit | 6e80e8ed5eb92d0112674aabe82951266a6a1051 (patch) | |
tree | 4913d191cd088f355b92109af5ffa7d75e15ae4a /kernel | |
parent | 6969a434737dd82f7343e3fcd529bc320508d9fc (diff) | |
parent | ee9a3607fb03e804ddf624544105f4e34260c380 (diff) |
Merge branch 'for-2.6.35' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.35' of git://git.kernel.dk/linux-2.6-block: (86 commits)
pipe: set lower and upper limit on max pages in the pipe page array
pipe: add support for shrinking and growing pipes
drbd: This is now equivalent to drbd release 8.3.8rc1
drbd: Do not free p_uuid early, this is done in the exit code of the receiver
drbd: Null pointer deref fix to the large "multi bio rewrite"
drbd: Fix: Do not detach, if a bio with a barrier fails
drbd: Ensure to not trigger late-new-UUID creation multiple times
drbd: Do not Oops when C_STANDALONE when uuid gets generated
writeback: fix mixed up arguments to bdi_start_writeback()
writeback: fix problem with !CONFIG_BLOCK compilation
block: improve automatic native capacity unlocking
block: use struct parsed_partitions *state universally in partition check code
block,ide: simplify bdops->set_capacity() to ->unlock_native_capacity()
block: restart partition scan after resizing a device
buffer: make invalidate_bdev() drain all percpu LRU add caches
block: remove all rcu head initializations
writeback: fixups for !dirty_writeback_centisecs
writeback: bdi_writeback_task() must set task state before calling schedule()
writeback: ensure that WB_SYNC_NONE writeback with sb pinned is sync
drivers/block/drbd: Use kzalloc
...
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/relay.c | 15 | ||||
-rw-r--r-- | kernel/sched_clock.c | 1 | ||||
-rw-r--r-- | kernel/sysctl.c | 9 | ||||
-rw-r--r-- | kernel/trace/trace.c | 60 |
4 files changed, 56 insertions, 29 deletions
diff --git a/kernel/relay.c b/kernel/relay.c index 3d97f2821611..4268287148c1 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
@@ -1231,8 +1231,8 @@ static ssize_t subbuf_splice_actor(struct file *in, | |||
1231 | size_t read_subbuf = read_start / subbuf_size; | 1231 | size_t read_subbuf = read_start / subbuf_size; |
1232 | size_t padding = rbuf->padding[read_subbuf]; | 1232 | size_t padding = rbuf->padding[read_subbuf]; |
1233 | size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding; | 1233 | size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding; |
1234 | struct page *pages[PIPE_BUFFERS]; | 1234 | struct page *pages[PIPE_DEF_BUFFERS]; |
1235 | struct partial_page partial[PIPE_BUFFERS]; | 1235 | struct partial_page partial[PIPE_DEF_BUFFERS]; |
1236 | struct splice_pipe_desc spd = { | 1236 | struct splice_pipe_desc spd = { |
1237 | .pages = pages, | 1237 | .pages = pages, |
1238 | .nr_pages = 0, | 1238 | .nr_pages = 0, |
@@ -1245,6 +1245,8 @@ static ssize_t subbuf_splice_actor(struct file *in, | |||
1245 | 1245 | ||
1246 | if (rbuf->subbufs_produced == rbuf->subbufs_consumed) | 1246 | if (rbuf->subbufs_produced == rbuf->subbufs_consumed) |
1247 | return 0; | 1247 | return 0; |
1248 | if (splice_grow_spd(pipe, &spd)) | ||
1249 | return -ENOMEM; | ||
1248 | 1250 | ||
1249 | /* | 1251 | /* |
1250 | * Adjust read len, if longer than what is available | 1252 | * Adjust read len, if longer than what is available |
@@ -1255,7 +1257,7 @@ static ssize_t subbuf_splice_actor(struct file *in, | |||
1255 | subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT; | 1257 | subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT; |
1256 | pidx = (read_start / PAGE_SIZE) % subbuf_pages; | 1258 | pidx = (read_start / PAGE_SIZE) % subbuf_pages; |
1257 | poff = read_start & ~PAGE_MASK; | 1259 | poff = read_start & ~PAGE_MASK; |
1258 | nr_pages = min_t(unsigned int, subbuf_pages, PIPE_BUFFERS); | 1260 | nr_pages = min_t(unsigned int, subbuf_pages, pipe->buffers); |
1259 | 1261 | ||
1260 | for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) { | 1262 | for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) { |
1261 | unsigned int this_len, this_end, private; | 1263 | unsigned int this_len, this_end, private; |
@@ -1289,16 +1291,19 @@ static ssize_t subbuf_splice_actor(struct file *in, | |||
1289 | } | 1291 | } |
1290 | } | 1292 | } |
1291 | 1293 | ||
1294 | ret = 0; | ||
1292 | if (!spd.nr_pages) | 1295 | if (!spd.nr_pages) |
1293 | return 0; | 1296 | goto out; |
1294 | 1297 | ||
1295 | ret = *nonpad_ret = splice_to_pipe(pipe, &spd); | 1298 | ret = *nonpad_ret = splice_to_pipe(pipe, &spd); |
1296 | if (ret < 0 || ret < total_len) | 1299 | if (ret < 0 || ret < total_len) |
1297 | return ret; | 1300 | goto out; |
1298 | 1301 | ||
1299 | if (read_start + ret == nonpad_end) | 1302 | if (read_start + ret == nonpad_end) |
1300 | ret += padding; | 1303 | ret += padding; |
1301 | 1304 | ||
1305 | out: | ||
1306 | splice_shrink_spd(pipe, &spd); | ||
1302 | return ret; | 1307 | return ret; |
1303 | } | 1308 | } |
1304 | 1309 | ||
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c index 5b496132c28a..906a0f718cb3 100644 --- a/kernel/sched_clock.c +++ b/kernel/sched_clock.c | |||
@@ -41,6 +41,7 @@ unsigned long long __attribute__((weak)) sched_clock(void) | |||
41 | return (unsigned long long)(jiffies - INITIAL_JIFFIES) | 41 | return (unsigned long long)(jiffies - INITIAL_JIFFIES) |
42 | * (NSEC_PER_SEC / HZ); | 42 | * (NSEC_PER_SEC / HZ); |
43 | } | 43 | } |
44 | EXPORT_SYMBOL_GPL(sched_clock); | ||
44 | 45 | ||
45 | static __read_mostly int sched_clock_running; | 46 | static __read_mostly int sched_clock_running; |
46 | 47 | ||
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 30acc6c87b1b..4c93486b45d1 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/slow-work.h> | 52 | #include <linux/slow-work.h> |
53 | #include <linux/perf_event.h> | 53 | #include <linux/perf_event.h> |
54 | #include <linux/kprobes.h> | 54 | #include <linux/kprobes.h> |
55 | #include <linux/pipe_fs_i.h> | ||
55 | 56 | ||
56 | #include <asm/uaccess.h> | 57 | #include <asm/uaccess.h> |
57 | #include <asm/processor.h> | 58 | #include <asm/processor.h> |
@@ -1444,6 +1445,14 @@ static struct ctl_table fs_table[] = { | |||
1444 | .child = binfmt_misc_table, | 1445 | .child = binfmt_misc_table, |
1445 | }, | 1446 | }, |
1446 | #endif | 1447 | #endif |
1448 | { | ||
1449 | .procname = "pipe-max-pages", | ||
1450 | .data = &pipe_max_pages, | ||
1451 | .maxlen = sizeof(int), | ||
1452 | .mode = 0644, | ||
1453 | .proc_handler = &proc_dointvec_minmax, | ||
1454 | .extra1 = &two, | ||
1455 | }, | ||
1447 | /* | 1456 | /* |
1448 | * NOTE: do not add new entries to this table unless you have read | 1457 | * NOTE: do not add new entries to this table unless you have read |
1449 | * Documentation/sysctl/ctl_unnumbered.txt | 1458 | * Documentation/sysctl/ctl_unnumbered.txt |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 756d7283318b..8a76339a9e65 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -3309,12 +3309,12 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3309 | size_t len, | 3309 | size_t len, |
3310 | unsigned int flags) | 3310 | unsigned int flags) |
3311 | { | 3311 | { |
3312 | struct page *pages[PIPE_BUFFERS]; | 3312 | struct page *pages_def[PIPE_DEF_BUFFERS]; |
3313 | struct partial_page partial[PIPE_BUFFERS]; | 3313 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; |
3314 | struct trace_iterator *iter = filp->private_data; | 3314 | struct trace_iterator *iter = filp->private_data; |
3315 | struct splice_pipe_desc spd = { | 3315 | struct splice_pipe_desc spd = { |
3316 | .pages = pages, | 3316 | .pages = pages_def, |
3317 | .partial = partial, | 3317 | .partial = partial_def, |
3318 | .nr_pages = 0, /* This gets updated below. */ | 3318 | .nr_pages = 0, /* This gets updated below. */ |
3319 | .flags = flags, | 3319 | .flags = flags, |
3320 | .ops = &tracing_pipe_buf_ops, | 3320 | .ops = &tracing_pipe_buf_ops, |
@@ -3325,6 +3325,9 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3325 | size_t rem; | 3325 | size_t rem; |
3326 | unsigned int i; | 3326 | unsigned int i; |
3327 | 3327 | ||
3328 | if (splice_grow_spd(pipe, &spd)) | ||
3329 | return -ENOMEM; | ||
3330 | |||
3328 | /* copy the tracer to avoid using a global lock all around */ | 3331 | /* copy the tracer to avoid using a global lock all around */ |
3329 | mutex_lock(&trace_types_lock); | 3332 | mutex_lock(&trace_types_lock); |
3330 | if (unlikely(old_tracer != current_trace && current_trace)) { | 3333 | if (unlikely(old_tracer != current_trace && current_trace)) { |
@@ -3355,23 +3358,23 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3355 | trace_access_lock(iter->cpu_file); | 3358 | trace_access_lock(iter->cpu_file); |
3356 | 3359 | ||
3357 | /* Fill as many pages as possible. */ | 3360 | /* Fill as many pages as possible. */ |
3358 | for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) { | 3361 | for (i = 0, rem = len; i < pipe->buffers && rem; i++) { |
3359 | pages[i] = alloc_page(GFP_KERNEL); | 3362 | spd.pages[i] = alloc_page(GFP_KERNEL); |
3360 | if (!pages[i]) | 3363 | if (!spd.pages[i]) |
3361 | break; | 3364 | break; |
3362 | 3365 | ||
3363 | rem = tracing_fill_pipe_page(rem, iter); | 3366 | rem = tracing_fill_pipe_page(rem, iter); |
3364 | 3367 | ||
3365 | /* Copy the data into the page, so we can start over. */ | 3368 | /* Copy the data into the page, so we can start over. */ |
3366 | ret = trace_seq_to_buffer(&iter->seq, | 3369 | ret = trace_seq_to_buffer(&iter->seq, |
3367 | page_address(pages[i]), | 3370 | page_address(spd.pages[i]), |
3368 | iter->seq.len); | 3371 | iter->seq.len); |
3369 | if (ret < 0) { | 3372 | if (ret < 0) { |
3370 | __free_page(pages[i]); | 3373 | __free_page(spd.pages[i]); |
3371 | break; | 3374 | break; |
3372 | } | 3375 | } |
3373 | partial[i].offset = 0; | 3376 | spd.partial[i].offset = 0; |
3374 | partial[i].len = iter->seq.len; | 3377 | spd.partial[i].len = iter->seq.len; |
3375 | 3378 | ||
3376 | trace_seq_init(&iter->seq); | 3379 | trace_seq_init(&iter->seq); |
3377 | } | 3380 | } |
@@ -3382,12 +3385,14 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, | |||
3382 | 3385 | ||
3383 | spd.nr_pages = i; | 3386 | spd.nr_pages = i; |
3384 | 3387 | ||
3385 | return splice_to_pipe(pipe, &spd); | 3388 | ret = splice_to_pipe(pipe, &spd); |
3389 | out: | ||
3390 | splice_shrink_spd(pipe, &spd); | ||
3391 | return ret; | ||
3386 | 3392 | ||
3387 | out_err: | 3393 | out_err: |
3388 | mutex_unlock(&iter->mutex); | 3394 | mutex_unlock(&iter->mutex); |
3389 | 3395 | goto out; | |
3390 | return ret; | ||
3391 | } | 3396 | } |
3392 | 3397 | ||
3393 | static ssize_t | 3398 | static ssize_t |
@@ -3786,11 +3791,11 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3786 | unsigned int flags) | 3791 | unsigned int flags) |
3787 | { | 3792 | { |
3788 | struct ftrace_buffer_info *info = file->private_data; | 3793 | struct ftrace_buffer_info *info = file->private_data; |
3789 | struct partial_page partial[PIPE_BUFFERS]; | 3794 | struct partial_page partial_def[PIPE_DEF_BUFFERS]; |
3790 | struct page *pages[PIPE_BUFFERS]; | 3795 | struct page *pages_def[PIPE_DEF_BUFFERS]; |
3791 | struct splice_pipe_desc spd = { | 3796 | struct splice_pipe_desc spd = { |
3792 | .pages = pages, | 3797 | .pages = pages_def, |
3793 | .partial = partial, | 3798 | .partial = partial_def, |
3794 | .flags = flags, | 3799 | .flags = flags, |
3795 | .ops = &buffer_pipe_buf_ops, | 3800 | .ops = &buffer_pipe_buf_ops, |
3796 | .spd_release = buffer_spd_release, | 3801 | .spd_release = buffer_spd_release, |
@@ -3799,22 +3804,28 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3799 | int entries, size, i; | 3804 | int entries, size, i; |
3800 | size_t ret; | 3805 | size_t ret; |
3801 | 3806 | ||
3807 | if (splice_grow_spd(pipe, &spd)) | ||
3808 | return -ENOMEM; | ||
3809 | |||
3802 | if (*ppos & (PAGE_SIZE - 1)) { | 3810 | if (*ppos & (PAGE_SIZE - 1)) { |
3803 | WARN_ONCE(1, "Ftrace: previous read must page-align\n"); | 3811 | WARN_ONCE(1, "Ftrace: previous read must page-align\n"); |
3804 | return -EINVAL; | 3812 | ret = -EINVAL; |
3813 | goto out; | ||
3805 | } | 3814 | } |
3806 | 3815 | ||
3807 | if (len & (PAGE_SIZE - 1)) { | 3816 | if (len & (PAGE_SIZE - 1)) { |
3808 | WARN_ONCE(1, "Ftrace: splice_read should page-align\n"); | 3817 | WARN_ONCE(1, "Ftrace: splice_read should page-align\n"); |
3809 | if (len < PAGE_SIZE) | 3818 | if (len < PAGE_SIZE) { |
3810 | return -EINVAL; | 3819 | ret = -EINVAL; |
3820 | goto out; | ||
3821 | } | ||
3811 | len &= PAGE_MASK; | 3822 | len &= PAGE_MASK; |
3812 | } | 3823 | } |
3813 | 3824 | ||
3814 | trace_access_lock(info->cpu); | 3825 | trace_access_lock(info->cpu); |
3815 | entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); | 3826 | entries = ring_buffer_entries_cpu(info->tr->buffer, info->cpu); |
3816 | 3827 | ||
3817 | for (i = 0; i < PIPE_BUFFERS && len && entries; i++, len -= PAGE_SIZE) { | 3828 | for (i = 0; i < pipe->buffers && len && entries; i++, len -= PAGE_SIZE) { |
3818 | struct page *page; | 3829 | struct page *page; |
3819 | int r; | 3830 | int r; |
3820 | 3831 | ||
@@ -3869,11 +3880,12 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, | |||
3869 | else | 3880 | else |
3870 | ret = 0; | 3881 | ret = 0; |
3871 | /* TODO: block */ | 3882 | /* TODO: block */ |
3872 | return ret; | 3883 | goto out; |
3873 | } | 3884 | } |
3874 | 3885 | ||
3875 | ret = splice_to_pipe(pipe, &spd); | 3886 | ret = splice_to_pipe(pipe, &spd); |
3876 | 3887 | splice_shrink_spd(pipe, &spd); | |
3888 | out: | ||
3877 | return ret; | 3889 | return ret; |
3878 | } | 3890 | } |
3879 | 3891 | ||