15 #include <linux/errno.h>
16 #include <linux/stddef.h>
17 #include <linux/slab.h>
18 #include <linux/export.h>
19 #include <linux/string.h>
42 static int relay_buf_fault(
struct vm_area_struct *vma,
struct vm_fault *vmf)
53 return VM_FAULT_SIGBUS;
63 static const struct vm_operations_struct relay_file_mmap_ops = {
64 .fault = relay_buf_fault,
65 .close = relay_file_mmap_close,
71 static struct page **relay_alloc_page_array(
unsigned int n_pages)
73 const size_t pa_size = n_pages *
sizeof(
struct page *);
82 static void relay_free_page_array(
struct page **array)
84 if (is_vmalloc_addr(array))
107 if (length != (
unsigned long)buf->
chan->alloc_size)
110 vma->
vm_ops = &relay_file_mmap_ops;
113 buf->
chan->cb->buf_mapped(buf, filp);
126 static void *relay_alloc_buf(
struct rchan_buf *buf,
size_t *
size)
129 unsigned int i,
j, n_pages;
134 buf->
page_array = relay_alloc_page_array(n_pages);
138 for (i = 0; i < n_pages; i++) {
142 set_page_private(buf->
page_array[i], (
unsigned long)buf);
153 for (j = 0; j <
i; j++)
184 kref_get(&buf->
chan->kref);
199 static void relay_destroy_channel(
struct kref *
kref)
209 static void relay_destroy_buf(
struct rchan_buf *buf)
223 kref_put(&chan->
kref, relay_destroy_channel);
234 static void relay_remove_buf(
struct kref *
kref)
238 relay_destroy_buf(buf);
247 static int relay_buf_empty(
struct rchan_buf *buf)
261 return (ready >= buf->
chan->n_subbufs) ? 1 : 0;
277 static int subbuf_start_default_callback (
struct rchan_buf *buf,
291 static void buf_mapped_default_callback(
struct rchan_buf *buf,
299 static void buf_unmapped_default_callback(
struct rchan_buf *buf,
307 static struct dentry *create_buf_file_default_callback(
const char *
filename,
319 static int remove_buf_file_default_callback(
struct dentry *
dentry)
326 .subbuf_start = subbuf_start_default_callback,
327 .buf_mapped = buf_mapped_default_callback,
328 .buf_unmapped = buf_unmapped_default_callback,
329 .create_buf_file = create_buf_file_default_callback,
330 .remove_buf_file = remove_buf_file_default_callback,
339 static void wakeup_readers(
unsigned long data)
352 static void __relay_reset(
struct rchan_buf *buf,
unsigned int init)
358 kref_init(&buf->
kref);
370 for (i = 0; i < buf->
chan->n_subbufs; i++)
395 __relay_reset(chan->
buf[0], 0);
402 __relay_reset(chan->
buf[i], 0);
407 static inline void relay_set_buf_dentry(
struct rchan_buf *buf,
414 static struct dentry *relay_create_buf_file(
struct rchan *chan,
427 dentry = chan->
cb->create_buf_file(tmpname, chan->
parent,
441 static struct rchan_buf *relay_open_buf(
struct rchan *chan,
unsigned int cpu)
444 struct dentry *dentry;
449 buf = relay_create_buf(chan);
454 dentry = relay_create_buf_file(chan, buf, cpu);
457 relay_set_buf_dentry(buf, dentry);
461 __relay_reset(buf, 1);
471 relay_destroy_buf(buf);
483 static void relay_close_buf(
struct rchan_buf *buf)
487 kref_put(&buf->
kref, relay_remove_buf);
490 static void setup_callbacks(
struct rchan *chan,
494 chan->
cb = &default_channel_callbacks;
523 unsigned int hotcpu = (
unsigned long)hcpu;
531 if (chan->
buf[hotcpu])
533 chan->
buf[hotcpu] = relay_open_buf(chan, hotcpu);
534 if(!chan->
buf[hotcpu]) {
536 "relay_hotcpu_callback: cpu %d buffer "
537 "creation failed\n", hotcpu);
539 return notifier_from_errno(-
ENOMEM);
579 if (!(subbuf_size && n_subbufs))
581 if (subbuf_size >
UINT_MAX / n_subbufs)
598 setup_callbacks(chan, cb);
599 kref_init(&chan->
kref);
603 chan->
buf[
i] = relay_open_buf(chan, i);
607 list_add(&chan->
list, &relay_channels);
615 relay_close_buf(chan->
buf[i]);
618 kref_put(&chan->
kref, relay_destroy_channel);
630 static void __relay_set_buf_dentry(
void *
info)
649 const char *base_filename,
650 struct dentry *parent)
653 unsigned int i, curr_cpu;
655 struct dentry *dentry;
658 if (!chan || !base_filename)
684 dentry = relay_create_buf_file(chan, chan->
buf[i], i);
692 relay_set_buf_dentry(chan->
buf[i], dentry);
700 __relay_set_buf_dentry,
725 size_t old_subbuf, new_subbuf;
730 if (buf->
offset != buf->
chan->subbuf_size + 1) {
736 buf->
dentry->d_inode->i_size +=
737 buf->
chan->subbuf_size -
755 new = buf->
start + new_subbuf * buf->
chan->subbuf_size;
790 size_t subbufs_consumed)
824 relay_close_buf(chan->
buf[0]);
828 relay_close_buf(chan->
buf[i]);
832 "[item size (%Zd) > sub-buffer size (%Zd)]\n",
836 kref_put(&chan->
kref, relay_destroy_channel);
874 static int relay_file_open(
struct inode *
inode,
struct file *filp)
877 kref_get(&buf->
kref);
893 return relay_mmap_buf(buf, vma);
905 unsigned int mask = 0;
913 if (!relay_buf_empty(buf))
928 static int relay_file_release(
struct inode *
inode,
struct file *filp)
931 kref_put(&buf->
kref, relay_remove_buf);
939 static void relay_file_read_consume(
struct rchan_buf *buf,
943 size_t subbuf_size = buf->
chan->subbuf_size;
944 size_t n_subbufs = buf->
chan->n_subbufs;
960 read_subbuf = read_pos / buf->
chan->subbuf_size;
963 (buf->
offset == subbuf_size))
973 static int relay_file_read_avail(
struct rchan_buf *buf,
size_t read_pos)
975 size_t subbuf_size = buf->
chan->subbuf_size;
976 size_t n_subbufs = buf->
chan->n_subbufs;
980 relay_file_read_consume(buf, read_pos, 0);
985 if (produced == consumed)
990 if (
unlikely(produced - consumed >= n_subbufs)) {
991 consumed = produced - n_subbufs + 1;
996 produced = (produced % n_subbufs) * subbuf_size + buf->
offset;
997 consumed = (consumed % n_subbufs) * subbuf_size + buf->
bytes_consumed;
999 if (consumed > produced)
1000 produced += n_subbufs * subbuf_size;
1002 if (consumed == produced) {
1003 if (buf->
offset == subbuf_size &&
1017 static size_t relay_file_read_subbuf_avail(
size_t read_pos,
1021 size_t read_subbuf, read_offset, write_subbuf, write_offset;
1022 size_t subbuf_size = buf->
chan->subbuf_size;
1024 write_subbuf = (buf->
data - buf->
start) / subbuf_size;
1025 write_offset = buf->
offset > subbuf_size ? subbuf_size : buf->
offset;
1026 read_subbuf = read_pos / subbuf_size;
1027 read_offset = read_pos % subbuf_size;
1028 padding = buf->
padding[read_subbuf];
1030 if (read_subbuf == write_subbuf) {
1031 if (read_offset + padding < write_offset)
1032 avail = write_offset - (read_offset +
padding);
1034 avail = (subbuf_size -
padding) - read_offset;
1048 static size_t relay_file_read_start_pos(
size_t read_pos,
1051 size_t read_subbuf,
padding, padding_start, padding_end;
1052 size_t subbuf_size = buf->
chan->subbuf_size;
1053 size_t n_subbufs = buf->
chan->n_subbufs;
1058 read_subbuf = read_pos / subbuf_size;
1059 padding = buf->
padding[read_subbuf];
1060 padding_start = (read_subbuf + 1) * subbuf_size - padding;
1061 padding_end = (read_subbuf + 1) * subbuf_size;
1062 if (read_pos >= padding_start && read_pos < padding_end) {
1063 read_subbuf = (read_subbuf + 1) % n_subbufs;
1064 read_pos = read_subbuf * subbuf_size;
1076 static size_t relay_file_read_end_pos(
struct rchan_buf *buf,
1080 size_t read_subbuf,
padding, end_pos;
1081 size_t subbuf_size = buf->
chan->subbuf_size;
1082 size_t n_subbufs = buf->
chan->n_subbufs;
1084 read_subbuf = read_pos / subbuf_size;
1085 padding = buf->
padding[read_subbuf];
1086 if (read_pos % subbuf_size + count + padding == subbuf_size)
1087 end_pos = (read_subbuf + 1) * subbuf_size;
1089 end_pos = read_pos +
count;
1090 if (end_pos >= subbuf_size * n_subbufs)
1099 static int subbuf_read_actor(
size_t read_start,
1108 from = buf->
start + read_start;
1130 static ssize_t relay_file_read_subbufs(
struct file *filp, loff_t *ppos,
1136 size_t read_start,
avail;
1144 if (!relay_file_read_avail(buf, *ppos))
1147 read_start = relay_file_read_start_pos(*ppos, buf);
1148 avail = relay_file_read_subbuf_avail(read_start, buf);
1153 ret = subbuf_actor(read_start, buf, avail, desc, actor);
1154 if (desc->
error < 0)
1158 relay_file_read_consume(buf, read_start, ret);
1159 *ppos = relay_file_read_end_pos(buf, read_start, ret);
1161 }
while (desc->
count && ret);
1177 return relay_file_read_subbufs(filp, ppos, subbuf_read_actor,
1181 static void relay_consume_bytes(
struct rchan_buf *rbuf,
int bytes_consumed)
1197 relay_consume_bytes(rbuf, buf->
private);
1205 .release = relay_pipe_buf_release,
1210 static void relay_page_release(
struct splice_pipe_desc *spd,
unsigned int i)
1224 unsigned int pidx, poff,
total_len, subbuf_pages, nr_pages;
1226 unsigned int subbuf_size = rbuf->
chan->subbuf_size;
1229 size_t read_start = (
size_t)
do_div(pos, alloc_size);
1230 size_t read_subbuf = read_start / subbuf_size;
1231 size_t padding = rbuf->
padding[read_subbuf];
1232 size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size -
padding;
1241 .ops = &relay_pipe_buf_ops,
1242 .spd_release = relay_page_release,
1254 if (len > (subbuf_size - read_start % subbuf_size))
1255 len = subbuf_size - read_start % subbuf_size;
1258 pidx = (read_start /
PAGE_SIZE) % subbuf_pages;
1260 nr_pages =
min_t(
unsigned int, subbuf_pages, pipe->
buffers);
1263 unsigned int this_len, this_end,
private;
1264 unsigned int cur_pos = read_start +
total_len;
1275 this_end = cur_pos + this_len;
1276 if (this_end >= nonpad_end) {
1277 this_len = nonpad_end - cur_pos;
1284 total_len += this_len;
1286 pidx = (pidx + 1) % subbuf_pages;
1288 if (this_end >= nonpad_end) {
1299 if (ret < 0 || ret < total_len)
1302 if (read_start + ret == nonpad_end)
1310 static ssize_t relay_file_splice_read(
struct file *in,
1323 while (len && !spliced) {
1324 ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
1338 spliced += nonpad_ret;
1349 .open = relay_file_open,
1350 .poll = relay_file_poll,
1351 .mmap = relay_file_mmap,
1352 .read = relay_file_read,
1354 .release = relay_file_release,
1355 .splice_read = relay_file_splice_read,
1359 static __init int relay_init(
void)