git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
mem-hotplug: avoid multiple zones sharing same boot strapping boot_pageset
[safe/jmp/linux-2.6]
/
kernel
/
relay.c
diff --git
a/kernel/relay.c
b/kernel/relay.c
index
9d79b78
..
4268287
100644
(file)
--- a/
kernel/relay.c
+++ b/
kernel/relay.c
@@
-60,7
+60,7
@@
static int relay_buf_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
/*
* vm_ops for relay file mappings.
*/
/*
* vm_ops for relay file mappings.
*/
-static struct vm_operations_struct relay_file_mmap_ops = {
+static
const
struct vm_operations_struct relay_file_mmap_ops = {
.fault = relay_buf_fault,
.close = relay_file_mmap_close,
};
.fault = relay_buf_fault,
.close = relay_file_mmap_close,
};
@@
-677,9
+677,7
@@
int relay_late_setup_files(struct rchan *chan,
*/
for_each_online_cpu(i) {
if (unlikely(!chan->buf[i])) {
*/
for_each_online_cpu(i) {
if (unlikely(!chan->buf[i])) {
- printk(KERN_ERR "relay_late_setup_files: CPU %u "
- "has no buffer, it must have!\n", i);
- BUG();
+ WARN_ONCE(1, KERN_ERR "CPU has no buffer!\n");
err = -EINVAL;
break;
}
err = -EINVAL;
break;
}
@@
-750,7
+748,7
@@
size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length)
* from the scheduler (trying to re-grab
* rq->lock), so defer it.
*/
* from the scheduler (trying to re-grab
* rq->lock), so defer it.
*/
-
__
mod_timer(&buf->timer, jiffies + 1);
+ mod_timer(&buf->timer, jiffies + 1);
}
old = buf->data;
}
old = buf->data;
@@
-797,13
+795,15
@@
void relay_subbufs_consumed(struct rchan *chan,
if (!chan)
return;
if (!chan)
return;
- if (cpu >= NR_CPUS || !chan->buf[cpu])
+ if (cpu >= NR_CPUS || !chan->buf[cpu] ||
+ subbufs_consumed > chan->n_subbufs)
return;
buf = chan->buf[cpu];
return;
buf = chan->buf[cpu];
- buf->subbufs_consumed += subbufs_consumed;
- if (buf->subbufs_consumed > buf->subbufs_produced)
+ if (subbufs_consumed > buf->subbufs_produced - buf->subbufs_consumed)
buf->subbufs_consumed = buf->subbufs_produced;
buf->subbufs_consumed = buf->subbufs_produced;
+ else
+ buf->subbufs_consumed += subbufs_consumed;
}
EXPORT_SYMBOL_GPL(relay_subbufs_consumed);
}
EXPORT_SYMBOL_GPL(relay_subbufs_consumed);
@@
-1198,7
+1198,7
@@
static void relay_pipe_buf_release(struct pipe_inode_info *pipe,
relay_consume_bytes(rbuf, buf->private);
}
relay_consume_bytes(rbuf, buf->private);
}
-static struct pipe_buf_operations relay_pipe_buf_ops = {
+static
const
struct pipe_buf_operations relay_pipe_buf_ops = {
.can_merge = 0,
.map = generic_pipe_buf_map,
.unmap = generic_pipe_buf_unmap,
.can_merge = 0,
.map = generic_pipe_buf_map,
.unmap = generic_pipe_buf_unmap,
@@
-1215,14
+1215,14
@@
static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i)
/*
* subbuf_splice_actor - splice up to one subbuf's worth of data
*/
/*
* subbuf_splice_actor - splice up to one subbuf's worth of data
*/
-static
in
t subbuf_splice_actor(struct file *in,
+static
ssize_
t subbuf_splice_actor(struct file *in,
loff_t *ppos,
struct pipe_inode_info *pipe,
size_t len,
unsigned int flags,
int *nonpad_ret)
{
loff_t *ppos,
struct pipe_inode_info *pipe,
size_t len,
unsigned int flags,
int *nonpad_ret)
{
- unsigned int pidx, poff, total_len, subbuf_pages, nr_pages
, ret
;
+ unsigned int pidx, poff, total_len, subbuf_pages, nr_pages;
struct rchan_buf *rbuf = in->private_data;
unsigned int subbuf_size = rbuf->chan->subbuf_size;
uint64_t pos = (uint64_t) *ppos;
struct rchan_buf *rbuf = in->private_data;
unsigned int subbuf_size = rbuf->chan->subbuf_size;
uint64_t pos = (uint64_t) *ppos;
@@
-1231,8
+1231,8
@@
static int subbuf_splice_actor(struct file *in,
size_t read_subbuf = read_start / subbuf_size;
size_t padding = rbuf->padding[read_subbuf];
size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;
size_t read_subbuf = read_start / subbuf_size;
size_t padding = rbuf->padding[read_subbuf];
size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;
- struct page *pages[PIPE_BUFFERS];
- struct partial_page partial[PIPE_BUFFERS];
+ struct page *pages[PIPE_
DEF_
BUFFERS];
+ struct partial_page partial[PIPE_
DEF_
BUFFERS];
struct splice_pipe_desc spd = {
.pages = pages,
.nr_pages = 0,
struct splice_pipe_desc spd = {
.pages = pages,
.nr_pages = 0,
@@
-1241,9
+1241,12
@@
static int subbuf_splice_actor(struct file *in,
.ops = &relay_pipe_buf_ops,
.spd_release = relay_page_release,
};
.ops = &relay_pipe_buf_ops,
.spd_release = relay_page_release,
};
+ ssize_t ret;
if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
return 0;
if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
return 0;
+ if (splice_grow_spd(pipe, &spd))
+ return -ENOMEM;
/*
* Adjust read len, if longer than what is available
/*
* Adjust read len, if longer than what is available
@@
-1254,7
+1257,7
@@
static int subbuf_splice_actor(struct file *in,
subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
pidx = (read_start / PAGE_SIZE) % subbuf_pages;
poff = read_start & ~PAGE_MASK;
subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
pidx = (read_start / PAGE_SIZE) % subbuf_pages;
poff = read_start & ~PAGE_MASK;
- nr_pages = min_t(unsigned int, subbuf_pages,
PIPE_BUFFERS
);
+ nr_pages = min_t(unsigned int, subbuf_pages,
pipe->buffers
);
for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
unsigned int this_len, this_end, private;
for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
unsigned int this_len, this_end, private;
@@
-1288,16
+1291,19
@@
static int subbuf_splice_actor(struct file *in,
}
}
}
}
+ ret = 0;
if (!spd.nr_pages)
if (!spd.nr_pages)
-
return 0
;
+
goto out
;
ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
if (ret < 0 || ret < total_len)
ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
if (ret < 0 || ret < total_len)
-
return re
t;
+
goto ou
t;
if (read_start + ret == nonpad_end)
ret += padding;
if (read_start + ret == nonpad_end)
ret += padding;
+out:
+ splice_shrink_spd(pipe, &spd);
return ret;
}
return ret;
}