~ubuntu-branches/ubuntu/saucy/linux-exynos5/saucy-proposed

« back to all changes in this revision

Viewing changes to ubuntu/lttng/lib/ringbuffer/ring_buffer_mmap.c

  • Committer: Package Import Robot
  • Author(s): Tim Gardner
  • Date: 2013-10-11 08:22:11 UTC
  • Revision ID: package-import@ubuntu.com-20131011082211-que2hf43fl0lbggm
Tags: 3.11.0-203.11
No change upload, but with orig tarball this time.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ring_buffer_mmap.c
 
3
 *
 
4
 * Copyright (C) 2002-2005 - Tom Zanussi <zanussi@us.ibm.com>, IBM Corp
 
5
 * Copyright (C) 1999-2005 - Karim Yaghmour <karim@opersys.com>
 
6
 * Copyright (C) 2008-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; only version 2 of the License.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License along
 
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 *
 
21
 * Re-using code from kernel/relay.c, hence the GPLv2 license for this
 
22
 * file.
 
23
 */
 
24
 
 
25
#include <linux/module.h>
 
26
#include <linux/mm.h>
 
27
 
 
28
#include "../../wrapper/ringbuffer/backend.h"
 
29
#include "../../wrapper/ringbuffer/frontend.h"
 
30
#include "../../wrapper/ringbuffer/vfs.h"
 
31
 
 
32
/*
 
33
 * fault() vm_op implementation for ring buffer file mapping.
 
34
 */
 
35
static int lib_ring_buffer_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 
36
{
 
37
        struct lib_ring_buffer *buf = vma->vm_private_data;
 
38
        struct channel *chan = buf->backend.chan;
 
39
        const struct lib_ring_buffer_config *config = &chan->backend.config;
 
40
        pgoff_t pgoff = vmf->pgoff;
 
41
        struct page **page;
 
42
        void **virt;
 
43
        unsigned long offset, sb_bindex;
 
44
 
 
45
        /*
 
46
         * Verify that faults are only done on the range of pages owned by the
 
47
         * reader.
 
48
         */
 
49
        offset = pgoff << PAGE_SHIFT;
 
50
        sb_bindex = subbuffer_id_get_index(config, buf->backend.buf_rsb.id);
 
51
        if (!(offset >= buf->backend.array[sb_bindex]->mmap_offset
 
52
              && offset < buf->backend.array[sb_bindex]->mmap_offset +
 
53
                          buf->backend.chan->backend.subbuf_size))
 
54
                return VM_FAULT_SIGBUS;
 
55
        /*
 
56
         * ring_buffer_read_get_page() gets the page in the current reader's
 
57
         * pages.
 
58
         */
 
59
        page = lib_ring_buffer_read_get_page(&buf->backend, offset, &virt);
 
60
        if (!*page)
 
61
                return VM_FAULT_SIGBUS;
 
62
        get_page(*page);
 
63
        vmf->page = *page;
 
64
 
 
65
        return 0;
 
66
}
 
67
 
 
68
/*
 
69
 * vm_ops for ring buffer file mappings.
 
70
 */
 
71
static const struct vm_operations_struct lib_ring_buffer_mmap_ops = {
 
72
        .fault = lib_ring_buffer_fault,
 
73
};
 
74
 
 
75
/**
 
76
 *      lib_ring_buffer_mmap_buf: - mmap channel buffer to process address space
 
77
 *      @buf: ring buffer to map
 
78
 *      @vma: vm_area_struct describing memory to be mapped
 
79
 *
 
80
 *      Returns 0 if ok, negative on error
 
81
 *
 
82
 *      Caller should already have grabbed mmap_sem.
 
83
 */
 
84
static int lib_ring_buffer_mmap_buf(struct lib_ring_buffer *buf,
 
85
                                    struct vm_area_struct *vma)
 
86
{
 
87
        unsigned long length = vma->vm_end - vma->vm_start;
 
88
        struct channel *chan = buf->backend.chan;
 
89
        const struct lib_ring_buffer_config *config = &chan->backend.config;
 
90
        unsigned long mmap_buf_len;
 
91
 
 
92
        if (config->output != RING_BUFFER_MMAP)
 
93
                return -EINVAL;
 
94
 
 
95
        mmap_buf_len = chan->backend.buf_size;
 
96
        if (chan->backend.extra_reader_sb)
 
97
                mmap_buf_len += chan->backend.subbuf_size;
 
98
 
 
99
        if (length != mmap_buf_len)
 
100
                return -EINVAL;
 
101
 
 
102
        vma->vm_ops = &lib_ring_buffer_mmap_ops;
 
103
        vma->vm_flags |= VM_DONTEXPAND;
 
104
        vma->vm_private_data = buf;
 
105
 
 
106
        return 0;
 
107
}
 
108
 
 
109
int lib_ring_buffer_mmap(struct file *filp, struct vm_area_struct *vma,
 
110
                struct lib_ring_buffer *buf)
 
111
{
 
112
        return lib_ring_buffer_mmap_buf(buf, vma);
 
113
}
 
114
EXPORT_SYMBOL_GPL(lib_ring_buffer_mmap);
 
115
 
 
116
/**
 
117
 *      vfs_lib_ring_buffer_mmap - mmap file op
 
118
 *      @filp: the file
 
119
 *      @vma: the vma describing what to map
 
120
 *
 
121
 *      Calls upon lib_ring_buffer_mmap_buf() to map the file into user space.
 
122
 */
 
123
int vfs_lib_ring_buffer_mmap(struct file *filp, struct vm_area_struct *vma)
 
124
{
 
125
        struct lib_ring_buffer *buf = filp->private_data;
 
126
        return lib_ring_buffer_mmap(filp, vma, buf);
 
127
}
 
128
EXPORT_SYMBOL_GPL(vfs_lib_ring_buffer_mmap);