^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Public API and common code for kernel->userspace relay file support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * See Documentation/filesystems/relay.rst for an overview.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2002-2005 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1999-2005 - Karim Yaghmour (karim@opersys.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Moved to kernel/relay.c by Paul Mundt, 2006.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * November 2006 - CPU hotplug support by Mathieu Desnoyers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * (mathieu.desnoyers@polymtl.ca)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This file is released under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/relay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/splice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* list of open channels, for cpu hotplug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static DEFINE_MUTEX(relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static LIST_HEAD(relay_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * close() vm_op implementation for relay file mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static void relay_file_mmap_close(struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct rchan_buf *buf = vma->vm_private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) buf->chan->cb->buf_unmapped(buf, vma->vm_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * fault() vm_op implementation for relay file mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static vm_fault_t relay_buf_fault(struct vm_fault *vmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct rchan_buf *buf = vmf->vma->vm_private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) pgoff_t pgoff = vmf->pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return VM_FAULT_OOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) page = vmalloc_to_page(buf->start + (pgoff << PAGE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return VM_FAULT_SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) get_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) vmf->page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * vm_ops for relay file mappings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static const struct vm_operations_struct relay_file_mmap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .fault = relay_buf_fault,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .close = relay_file_mmap_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * allocate an array of pointers of struct page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct page **relay_alloc_page_array(unsigned int n_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) const size_t pa_size = n_pages * sizeof(struct page *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (pa_size > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return vzalloc(pa_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return kzalloc(pa_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * free an array of pointers of struct page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static void relay_free_page_array(struct page **array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) kvfree(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * relay_mmap_buf: - mmap channel buffer to process address space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @buf: relay channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @vma: vm_area_struct describing memory to be mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Returns 0 if ok, negative on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Caller should already have grabbed mmap_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned long length = vma->vm_end - vma->vm_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct file *filp = vma->vm_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (length != (unsigned long)buf->chan->alloc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) vma->vm_ops = &relay_file_mmap_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) vma->vm_flags |= VM_DONTEXPAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) vma->vm_private_data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) buf->chan->cb->buf_mapped(buf, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * relay_alloc_buf - allocate a channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @buf: the buffer struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @size: total size of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Returns a pointer to the resulting buffer, %NULL if unsuccessful. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * passed in size will get page aligned, if it isn't already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) void *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int i, j, n_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *size = PAGE_ALIGN(*size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) n_pages = *size >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) buf->page_array = relay_alloc_page_array(n_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!buf->page_array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) for (i = 0; i < n_pages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) buf->page_array[i] = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (unlikely(!buf->page_array[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto depopulate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) set_page_private(buf->page_array[i], (unsigned long)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (!mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) goto depopulate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) memset(mem, 0, *size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) buf->page_count = n_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) depopulate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for (j = 0; j < i; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) __free_page(buf->page_array[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) relay_free_page_array(buf->page_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * relay_create_buf - allocate and initialize a channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @chan: the relay channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Returns channel buffer if successful, %NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static struct rchan_buf *relay_create_buf(struct rchan *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (!buf->padding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) goto free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) buf->start = relay_alloc_buf(buf, &chan->alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (!buf->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) buf->chan = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) kref_get(&buf->chan->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) free_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) kfree(buf->padding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * relay_destroy_channel - free the channel struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * @kref: target kernel reference that contains the relay channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Should only be called from kref_put().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static void relay_destroy_channel(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct rchan *chan = container_of(kref, struct rchan, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) free_percpu(chan->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) kfree(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * relay_destroy_buf - destroy an rchan_buf struct and associated buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @buf: the buffer struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static void relay_destroy_buf(struct rchan_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct rchan *chan = buf->chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (likely(buf->start)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) vunmap(buf->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) for (i = 0; i < buf->page_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) __free_page(buf->page_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) relay_free_page_array(buf->page_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *per_cpu_ptr(chan->buf, buf->cpu) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) kfree(buf->padding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) kref_put(&chan->kref, relay_destroy_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * relay_remove_buf - remove a channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * @kref: target kernel reference that contains the relay buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * Removes the file from the filesystem, which also frees the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * rchan_buf_struct and the channel buffer. Should only be called from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * kref_put().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void relay_remove_buf(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) relay_destroy_buf(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * relay_buf_empty - boolean, is the channel buffer empty?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @buf: channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Returns 1 if the buffer is empty, 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int relay_buf_empty(struct rchan_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return (buf->subbufs_produced - buf->subbufs_consumed) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * relay_buf_full - boolean, is the channel buffer full?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * @buf: channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * Returns 1 if the buffer is full, 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int relay_buf_full(struct rchan_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) size_t ready = buf->subbufs_produced - buf->subbufs_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return (ready >= buf->chan->n_subbufs) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) EXPORT_SYMBOL_GPL(relay_buf_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * High-level relay kernel API and associated functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * rchan_callback implementations defining default channel behavior. Used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * in place of corresponding NULL values in client callback struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * subbuf_start() default callback. Does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int subbuf_start_default_callback (struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) void *subbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) void *prev_subbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) size_t prev_padding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (relay_buf_full(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * buf_mapped() default callback. Does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static void buf_mapped_default_callback(struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * buf_unmapped() default callback. Does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void buf_unmapped_default_callback(struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * create_buf_file_create() default callback. Does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static struct dentry *create_buf_file_default_callback(const char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int *is_global)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * remove_buf_file() default callback. Does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int remove_buf_file_default_callback(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* relay channel default callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static struct rchan_callbacks default_channel_callbacks = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .subbuf_start = subbuf_start_default_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .buf_mapped = buf_mapped_default_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .buf_unmapped = buf_unmapped_default_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .create_buf_file = create_buf_file_default_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .remove_buf_file = remove_buf_file_default_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * wakeup_readers - wake up readers waiting on a channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * @work: contains the channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * This is the function used to defer reader waking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static void wakeup_readers(struct irq_work *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) buf = container_of(work, struct rchan_buf, wakeup_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) wake_up_interruptible(&buf->read_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * __relay_reset - reset a channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * @buf: the channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * @init: 1 if this is a first-time initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * See relay_reset() for description of effect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static void __relay_reset(struct rchan_buf *buf, unsigned int init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) init_waitqueue_head(&buf->read_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) kref_init(&buf->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) init_irq_work(&buf->wakeup_work, wakeup_readers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) irq_work_sync(&buf->wakeup_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) buf->subbufs_produced = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) buf->subbufs_consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) buf->bytes_consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) buf->finalized = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) buf->data = buf->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) buf->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) for (i = 0; i < buf->chan->n_subbufs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) buf->padding[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) buf->chan->cb->subbuf_start(buf, buf->data, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * relay_reset - reset the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * @chan: the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * This has the effect of erasing all data from all channel buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * and restarting the channel in its initial state. The buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * are not freed, so any mappings are still in effect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * NOTE. Care should be taken that the channel isn't actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * being used by anything when this call is made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) void relay_reset(struct rchan *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (!chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (chan->is_global && (buf = *per_cpu_ptr(chan->buf, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) __relay_reset(buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) mutex_lock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) for_each_possible_cpu(i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if ((buf = *per_cpu_ptr(chan->buf, i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) __relay_reset(buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) EXPORT_SYMBOL_GPL(relay_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static inline void relay_set_buf_dentry(struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) buf->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) d_inode(buf->dentry)->i_size = buf->early_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static struct dentry *relay_create_buf_file(struct rchan *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) char *tmpname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) tmpname = kzalloc(NAME_MAX + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!tmpname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) snprintf(tmpname, NAME_MAX, "%s%d", chan->base_filename, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Create file in fs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dentry = chan->cb->create_buf_file(tmpname, chan->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) S_IRUSR, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) &chan->is_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (IS_ERR(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) kfree(tmpname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * relay_open_buf - create a new relay channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * used by relay_open() and CPU hotplug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct rchan_buf *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (chan->is_global)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return *per_cpu_ptr(chan->buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) buf = relay_create_buf(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (chan->has_base_filename) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dentry = relay_create_buf_file(chan, buf, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) goto free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) relay_set_buf_dentry(buf, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Only retrieve global info, nothing more, nothing less */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dentry = chan->cb->create_buf_file(NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) S_IRUSR, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) &chan->is_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (IS_ERR_OR_NULL(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) goto free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) buf->cpu = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) __relay_reset(buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if(chan->is_global) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) *per_cpu_ptr(chan->buf, 0) = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) buf->cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) free_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) relay_destroy_buf(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * relay_close_buf - close a channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * @buf: channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * Marks the buffer finalized and restores the default callbacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * The channel buffer and channel buffer data structure are then freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * automatically when the last reference is given up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static void relay_close_buf(struct rchan_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) buf->finalized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) irq_work_sync(&buf->wakeup_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) buf->chan->cb->remove_buf_file(buf->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) kref_put(&buf->kref, relay_remove_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static void setup_callbacks(struct rchan *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct rchan_callbacks *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!cb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) chan->cb = &default_channel_callbacks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!cb->subbuf_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) cb->subbuf_start = subbuf_start_default_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!cb->buf_mapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) cb->buf_mapped = buf_mapped_default_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!cb->buf_unmapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) cb->buf_unmapped = buf_unmapped_default_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (!cb->create_buf_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) cb->create_buf_file = create_buf_file_default_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (!cb->remove_buf_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cb->remove_buf_file = remove_buf_file_default_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) chan->cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int relay_prepare_cpu(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct rchan *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mutex_lock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) list_for_each_entry(chan, &relay_channels, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if ((buf = *per_cpu_ptr(chan->buf, cpu)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) buf = relay_open_buf(chan, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) pr_err("relay: cpu %d buffer creation failed\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) *per_cpu_ptr(chan->buf, cpu) = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * relay_open - create a new relay channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * @base_filename: base name of files to create, %NULL for buffering only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * @parent: dentry of parent directory, %NULL for root directory or buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * @subbuf_size: size of sub-buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * @n_subbufs: number of sub-buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * @cb: client callback functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * @private_data: user-defined data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * Returns channel pointer if successful, %NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Creates a channel buffer for each cpu using the sizes and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * attributes specified. The created channel buffer files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * will be named base_filename0...base_filenameN-1. File
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * permissions will be %S_IRUSR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * If opening a buffer (@parent = NULL) that you later wish to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * in a filesystem, call relay_late_setup_files() once the @parent dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct rchan *relay_open(const char *base_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct dentry *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) size_t subbuf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) size_t n_subbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct rchan_callbacks *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) void *private_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct rchan *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (!(subbuf_size && n_subbufs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (subbuf_size > UINT_MAX / n_subbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (!chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) chan->buf = alloc_percpu(struct rchan_buf *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (!chan->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) kfree(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) chan->version = RELAYFS_CHANNEL_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) chan->n_subbufs = n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) chan->subbuf_size = subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) chan->alloc_size = PAGE_ALIGN(subbuf_size * n_subbufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) chan->parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) chan->private_data = private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (base_filename) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) chan->has_base_filename = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) strlcpy(chan->base_filename, base_filename, NAME_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) setup_callbacks(chan, cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) kref_init(&chan->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) mutex_lock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) for_each_online_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) buf = relay_open_buf(chan, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) goto free_bufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) *per_cpu_ptr(chan->buf, i) = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) list_add(&chan->list, &relay_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) free_bufs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if ((buf = *per_cpu_ptr(chan->buf, i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) relay_close_buf(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) kref_put(&chan->kref, relay_destroy_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) EXPORT_SYMBOL_GPL(relay_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct rchan_percpu_buf_dispatcher {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* Called in atomic context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static void __relay_set_buf_dentry(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct rchan_percpu_buf_dispatcher *p = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) relay_set_buf_dentry(p->buf, p->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * relay_late_setup_files - triggers file creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * @chan: channel to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * @base_filename: base name of files to create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * @parent: dentry of parent directory, %NULL for root directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * Returns 0 if successful, non-zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * Use to setup files for a previously buffer-only channel created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * by relay_open() with a NULL parent dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * For example, this is useful for perfomring early tracing in kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * before VFS is up and then exposing the early results once the dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int relay_late_setup_files(struct rchan *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) const char *base_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct dentry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) unsigned int i, curr_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct rchan_percpu_buf_dispatcher disp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (!chan || !base_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) strlcpy(chan->base_filename, base_filename, NAME_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) mutex_lock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* Is chan already set up? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (unlikely(chan->has_base_filename)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) chan->has_base_filename = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) chan->parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (chan->is_global) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) buf = *per_cpu_ptr(chan->buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (!WARN_ON_ONCE(!buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) dentry = relay_create_buf_file(chan, buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (dentry && !WARN_ON_ONCE(!chan->is_global)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) relay_set_buf_dentry(buf, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) curr_cpu = get_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * The CPU hotplug notifier ran before us and created buffers with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * no files associated. So it's safe to call relay_setup_buf_file()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * on all currently online CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) for_each_online_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) buf = *per_cpu_ptr(chan->buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (unlikely(!buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) WARN_ONCE(1, KERN_ERR "CPU has no buffer!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dentry = relay_create_buf_file(chan, buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (unlikely(!dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (curr_cpu == i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) relay_set_buf_dentry(buf, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) disp.buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) disp.dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) smp_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* relay_channels_mutex must be held, so wait. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) err = smp_call_function_single(i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) __relay_set_buf_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) &disp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) EXPORT_SYMBOL_GPL(relay_late_setup_files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * relay_switch_subbuf - switch to a new sub-buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * @buf: channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * @length: size of current event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * Returns either the length passed in or 0 if full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * Performs sub-buffer-switch tasks such as invoking callbacks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * updating padding counts, waking up readers, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) void *old, *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) size_t old_subbuf, new_subbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (unlikely(length > buf->chan->subbuf_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) goto toobig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (buf->offset != buf->chan->subbuf_size + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) buf->prev_padding = buf->chan->subbuf_size - buf->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) buf->padding[old_subbuf] = buf->prev_padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) buf->subbufs_produced++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (buf->dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) d_inode(buf->dentry)->i_size +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) buf->chan->subbuf_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) buf->padding[old_subbuf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) buf->early_bytes += buf->chan->subbuf_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) buf->padding[old_subbuf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) smp_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (waitqueue_active(&buf->read_wait)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * Calling wake_up_interruptible() from here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * will deadlock if we happen to be logging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * from the scheduler (trying to re-grab
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * rq->lock), so defer it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) irq_work_queue(&buf->wakeup_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) old = buf->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) new_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) new = buf->start + new_subbuf * buf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) buf->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (!buf->chan->cb->subbuf_start(buf, new, old, buf->prev_padding)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) buf->offset = buf->chan->subbuf_size + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) buf->data = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) buf->padding[new_subbuf] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (unlikely(length + buf->offset > buf->chan->subbuf_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) goto toobig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) toobig:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) buf->chan->last_toobig = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) EXPORT_SYMBOL_GPL(relay_switch_subbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * relay_subbufs_consumed - update the buffer's sub-buffers-consumed count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * @chan: the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * @cpu: the cpu associated with the channel buffer to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * @subbufs_consumed: number of sub-buffers to add to current buf's count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * Adds to the channel buffer's consumed sub-buffer count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * subbufs_consumed should be the number of sub-buffers newly consumed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * not the total consumed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * NOTE. Kernel clients don't need to call this function if the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * mode is 'overwrite'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) void relay_subbufs_consumed(struct rchan *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) unsigned int cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) size_t subbufs_consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (!chan || cpu >= NR_CPUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) buf = *per_cpu_ptr(chan->buf, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (!buf || subbufs_consumed > chan->n_subbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (subbufs_consumed > buf->subbufs_produced - buf->subbufs_consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) buf->subbufs_consumed = buf->subbufs_produced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) buf->subbufs_consumed += subbufs_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) EXPORT_SYMBOL_GPL(relay_subbufs_consumed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * relay_close - close the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * @chan: the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * Closes all channel buffers and frees the channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) void relay_close(struct rchan *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) mutex_lock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (chan->is_global && (buf = *per_cpu_ptr(chan->buf, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) relay_close_buf(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) for_each_possible_cpu(i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if ((buf = *per_cpu_ptr(chan->buf, i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) relay_close_buf(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (chan->last_toobig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) printk(KERN_WARNING "relay: one or more items not logged "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) "[item size (%zd) > sub-buffer size (%zd)]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) chan->last_toobig, chan->subbuf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) list_del(&chan->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) kref_put(&chan->kref, relay_destroy_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) EXPORT_SYMBOL_GPL(relay_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * relay_flush - close the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * @chan: the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * Flushes all channel buffers, i.e. forces buffer switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) void relay_flush(struct rchan *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct rchan_buf *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (!chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (chan->is_global && (buf = *per_cpu_ptr(chan->buf, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) relay_switch_subbuf(buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) mutex_lock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) for_each_possible_cpu(i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if ((buf = *per_cpu_ptr(chan->buf, i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) relay_switch_subbuf(buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) mutex_unlock(&relay_channels_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) EXPORT_SYMBOL_GPL(relay_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * relay_file_open - open file op for relay files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * @inode: the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * @filp: the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * Increments the channel buffer refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static int relay_file_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct rchan_buf *buf = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) kref_get(&buf->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) filp->private_data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return nonseekable_open(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * relay_file_mmap - mmap file op for relay files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * @filp: the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * @vma: the vma describing what to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * Calls upon relay_mmap_buf() to map the file into user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static int relay_file_mmap(struct file *filp, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct rchan_buf *buf = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return relay_mmap_buf(buf, vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * relay_file_poll - poll file op for relay files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * @filp: the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * @wait: poll table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) * Poll implemention.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static __poll_t relay_file_poll(struct file *filp, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) __poll_t mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct rchan_buf *buf = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (buf->finalized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return EPOLLERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (filp->f_mode & FMODE_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) poll_wait(filp, &buf->read_wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!relay_buf_empty(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) mask |= EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * relay_file_release - release file op for relay files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * @inode: the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * @filp: the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * Decrements the channel refcount, as the filesystem is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * no longer using it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static int relay_file_release(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct rchan_buf *buf = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) kref_put(&buf->kref, relay_remove_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * relay_file_read_consume - update the consumed count for the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static void relay_file_read_consume(struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) size_t read_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) size_t bytes_consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) size_t subbuf_size = buf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) size_t n_subbufs = buf->chan->n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) size_t read_subbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (buf->subbufs_produced == buf->subbufs_consumed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) buf->offset == buf->bytes_consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (buf->bytes_consumed + bytes_consumed > subbuf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) relay_subbufs_consumed(buf->chan, buf->cpu, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) buf->bytes_consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) buf->bytes_consumed += bytes_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (!read_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) read_subbuf = buf->subbufs_consumed % n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) read_subbuf = read_pos / buf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (buf->bytes_consumed + buf->padding[read_subbuf] == subbuf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if ((read_subbuf == buf->subbufs_produced % n_subbufs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) (buf->offset == subbuf_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) relay_subbufs_consumed(buf->chan, buf->cpu, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) buf->bytes_consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * relay_file_read_avail - boolean, are there unconsumed bytes available?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int relay_file_read_avail(struct rchan_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) size_t subbuf_size = buf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) size_t n_subbufs = buf->chan->n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) size_t produced = buf->subbufs_produced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) size_t consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) relay_file_read_consume(buf, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) consumed = buf->subbufs_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (unlikely(buf->offset > subbuf_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (produced == consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (unlikely(produced - consumed >= n_subbufs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) consumed = produced - n_subbufs + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) buf->subbufs_consumed = consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) buf->bytes_consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) produced = (produced % n_subbufs) * subbuf_size + buf->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) consumed = (consumed % n_subbufs) * subbuf_size + buf->bytes_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (consumed > produced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) produced += n_subbufs * subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (consumed == produced) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (buf->offset == subbuf_size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) buf->subbufs_produced > buf->subbufs_consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * relay_file_read_subbuf_avail - return bytes available in sub-buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * @read_pos: file read position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * @buf: relay channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static size_t relay_file_read_subbuf_avail(size_t read_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct rchan_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) size_t padding, avail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) size_t read_subbuf, read_offset, write_subbuf, write_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) size_t subbuf_size = buf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) write_subbuf = (buf->data - buf->start) / subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) write_offset = buf->offset > subbuf_size ? subbuf_size : buf->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) read_subbuf = read_pos / subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) read_offset = read_pos % subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) padding = buf->padding[read_subbuf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (read_subbuf == write_subbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (read_offset + padding < write_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) avail = write_offset - (read_offset + padding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) avail = (subbuf_size - padding) - read_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * relay_file_read_start_pos - find the first available byte to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * @buf: relay channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * If the read_pos is in the middle of padding, return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * position of the first actually available byte, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * return the original value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static size_t relay_file_read_start_pos(struct rchan_buf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) size_t read_subbuf, padding, padding_start, padding_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) size_t subbuf_size = buf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) size_t n_subbufs = buf->chan->n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) size_t consumed = buf->subbufs_consumed % n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) size_t read_pos = consumed * subbuf_size + buf->bytes_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) read_subbuf = read_pos / subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) padding = buf->padding[read_subbuf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) padding_start = (read_subbuf + 1) * subbuf_size - padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) padding_end = (read_subbuf + 1) * subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (read_pos >= padding_start && read_pos < padding_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) read_subbuf = (read_subbuf + 1) % n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) read_pos = read_subbuf * subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return read_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * relay_file_read_end_pos - return the new read position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * @read_pos: file read position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * @buf: relay channel buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * @count: number of bytes to be read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static size_t relay_file_read_end_pos(struct rchan_buf *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) size_t read_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) size_t read_subbuf, padding, end_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) size_t subbuf_size = buf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) size_t n_subbufs = buf->chan->n_subbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) read_subbuf = read_pos / subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) padding = buf->padding[read_subbuf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (read_pos % subbuf_size + count + padding == subbuf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) end_pos = (read_subbuf + 1) * subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) end_pos = read_pos + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (end_pos >= subbuf_size * n_subbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) end_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return end_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static ssize_t relay_file_read(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) struct rchan_buf *buf = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) size_t read_start, avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) size_t written = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) inode_lock(file_inode(filp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) void *from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (!relay_file_read_avail(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) read_start = relay_file_read_start_pos(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) avail = relay_file_read_subbuf_avail(read_start, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (!avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) avail = min(count, avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) from = buf->start + read_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) ret = avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (copy_to_user(buffer, from, avail))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) buffer += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) written += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) count -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) relay_file_read_consume(buf, read_start, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) *ppos = relay_file_read_end_pos(buf, read_start, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) } while (count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) inode_unlock(file_inode(filp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) rbuf->bytes_consumed += bytes_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (rbuf->bytes_consumed >= rbuf->chan->subbuf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) rbuf->bytes_consumed %= rbuf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) static void relay_pipe_buf_release(struct pipe_inode_info *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct pipe_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct rchan_buf *rbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) rbuf = (struct rchan_buf *)page_private(buf->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) relay_consume_bytes(rbuf, buf->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static const struct pipe_buf_operations relay_pipe_buf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) .release = relay_pipe_buf_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) .try_steal = generic_pipe_buf_try_steal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) .get = generic_pipe_buf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * subbuf_splice_actor - splice up to one subbuf's worth of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static ssize_t subbuf_splice_actor(struct file *in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) loff_t *ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct pipe_inode_info *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) int *nonpad_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) unsigned int pidx, poff, total_len, subbuf_pages, nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct rchan_buf *rbuf = in->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) unsigned int subbuf_size = rbuf->chan->subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) uint64_t pos = (uint64_t) *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) uint32_t alloc_size = (uint32_t) rbuf->chan->alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) size_t read_start = (size_t) do_div(pos, alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) size_t read_subbuf = read_start / subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) size_t padding = rbuf->padding[read_subbuf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) struct page *pages[PIPE_DEF_BUFFERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) struct partial_page partial[PIPE_DEF_BUFFERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct splice_pipe_desc spd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .pages = pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .nr_pages = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .nr_pages_max = PIPE_DEF_BUFFERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .partial = partial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .ops = &relay_pipe_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .spd_release = relay_page_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (splice_grow_spd(pipe, &spd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * Adjust read len, if longer than what is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (len > (subbuf_size - read_start % subbuf_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) len = subbuf_size - read_start % subbuf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) pidx = (read_start / PAGE_SIZE) % subbuf_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) poff = read_start & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) nr_pages = min_t(unsigned int, subbuf_pages, spd.nr_pages_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) unsigned int this_len, this_end, private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) unsigned int cur_pos = read_start + total_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) this_len = min_t(unsigned long, len, PAGE_SIZE - poff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) private = this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) spd.pages[spd.nr_pages] = rbuf->page_array[pidx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) spd.partial[spd.nr_pages].offset = poff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) this_end = cur_pos + this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (this_end >= nonpad_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) this_len = nonpad_end - cur_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) private = this_len + padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) spd.partial[spd.nr_pages].len = this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) spd.partial[spd.nr_pages].private = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) len -= this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) total_len += this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) poff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) pidx = (pidx + 1) % subbuf_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (this_end >= nonpad_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) spd.nr_pages++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (!spd.nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (ret < 0 || ret < total_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (read_start + ret == nonpad_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) ret += padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) splice_shrink_spd(&spd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static ssize_t relay_file_splice_read(struct file *in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) loff_t *ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct pipe_inode_info *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ssize_t spliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) int nonpad_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) spliced = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) while (len && !spliced) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) else if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (flags & SPLICE_F_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) *ppos += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (ret > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) len -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) spliced += nonpad_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) nonpad_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (spliced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return spliced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) const struct file_operations relay_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .open = relay_file_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .poll = relay_file_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) .mmap = relay_file_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) .read = relay_file_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .release = relay_file_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .splice_read = relay_file_splice_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) EXPORT_SYMBOL_GPL(relay_file_operations);