4 * (C) Copyright 2009 - Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
9 * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)
11 * Dual LGPL v2.1/GPL v2 license.
14 #include <linux/module.h>
16 #include <linux/debugfs.h>
17 #include <linux/ltt-channels.h>
18 #include <asm/atomic.h>
20 #include "ltt-tracer.h"
21 #include "ltt-relay.h"
22 #include "ltt-relay-lockless.h"
25 * ltt_open - open file op for ltt files
26 * @inode: opened inode
29 * Open implementation. Makes sure only one open instance of a buffer is
30 * done at a given moment.
32 static int ltt_open(struct inode
*inode
, struct file
*file
)
34 struct ltt_chanbuf
*buf
= inode
->i_private
;
37 ret
= ltt_chanbuf_open_read(buf
);
41 file
->private_data
= buf
;
42 ret
= nonseekable_open(inode
, file
);
44 * Let LTTng splice operation must believe that the file descriptor is
45 * seekable. This is a temporary fix to follow new checks added to
46 * splice.c. We should probably do the proper thing and implement a
47 * llseek function eventually, which involves modifying the lttng splice
48 * actors accordingly. TODO
50 file
->f_mode
|= FMODE_PREAD
;
56 * ltt_release - release file op for ltt files
57 * @inode: opened inode
60 * Release implementation.
62 static int ltt_release(struct inode
*inode
, struct file
*file
)
64 struct ltt_chanbuf
*buf
= inode
->i_private
;
66 ltt_chanbuf_release_read(buf
);
72 * ltt_poll - file op for ltt files
76 * Poll implementation.
78 static unsigned int ltt_poll(struct file
*filp
, poll_table
*wait
)
80 unsigned int mask
= 0;
81 struct inode
*inode
= filp
->f_dentry
->d_inode
;
82 struct ltt_chanbuf
*buf
= inode
->i_private
;
83 struct ltt_chan
*chan
= container_of(buf
->a
.chan
, struct ltt_chan
, a
);
85 if (filp
->f_mode
& FMODE_READ
) {
86 poll_wait_set_exclusive(wait
);
87 poll_wait(filp
, &buf
->read_wait
, wait
);
89 WARN_ON(atomic_long_read(&buf
->active_readers
) != 1);
90 if (SUBBUF_TRUNC(ltt_chanbuf_get_offset(buf
), chan
)
91 - SUBBUF_TRUNC(ltt_chanbuf_get_consumed(buf
), chan
)
98 if (SUBBUF_TRUNC(ltt_chanbuf_get_offset(buf
), chan
)
99 - SUBBUF_TRUNC(ltt_chanbuf_get_consumed(buf
), chan
)
101 return POLLPRI
| POLLRDBAND
;
103 return POLLIN
| POLLRDNORM
;
110 * ltt_ioctl - control on the debugfs file
117 * This ioctl implements three commands necessary for a minimal
118 * producer/consumer implementation :
120 * Get the next sub-buffer that can be read. It never blocks.
122 * Release the currently read sub-buffer. Parameter is the last
123 * put subbuffer (returned by GET_SUBBUF).
125 * returns the number of sub-buffers in the per cpu channel.
127 * returns the size of the current sub-buffer.
128 * RELAY_GET_MAX_SB_SIZE
129 * returns the maximum size for sub-buffers.
132 int ltt_ioctl(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
135 struct ltt_chanbuf
*buf
= inode
->i_private
;
136 u32 __user
*argp
= (u32 __user
*)arg
;
141 unsigned long consumed
;
144 ret
= ltt_chanbuf_get_subbuf(buf
, &consumed
);
148 return put_user((u32
)consumed
, argp
);
157 ret
= get_user(uconsumed_old
, argp
);
159 return ret
; /* will return -EFAULT */
161 consumed_old
= ltt_chanbuf_get_consumed(buf
);
162 consumed_old
= consumed_old
& (~0xFFFFFFFFL
);
163 consumed_old
= consumed_old
| uconsumed_old
;
164 ret
= ltt_chanbuf_put_subbuf(buf
, consumed_old
);
170 return put_user((u32
)buf
->a
.chan
->n_sb
, argp
);
172 case RELAY_GET_SB_SIZE
:
173 return put_user(get_read_sb_size(buf
), argp
);
175 case RELAY_GET_MAX_SB_SIZE
:
176 return put_user((u32
)buf
->a
.chan
->sb_size
, argp
);
186 long ltt_compat_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
188 long ret
= -ENOIOCTLCMD
;
191 ret
= ltt_ioctl(file
->f_dentry
->d_inode
, file
, cmd
, arg
);
198 static const struct file_operations ltt_file_operations
= {
200 .release
= ltt_release
,
202 .splice_read
= ltt_relay_file_splice_read
,
204 .llseek
= ltt_relay_no_llseek
,
206 .compat_ioctl
= ltt_compat_ioctl
,
210 int ltt_chanbuf_create_file(const char *filename
, struct dentry
*parent
,
211 int mode
, struct ltt_chanbuf
*buf
)
213 struct ltt_chan
*chan
= container_of(buf
->a
.chan
, struct ltt_chan
, a
);
217 tmpname
= kzalloc(NAME_MAX
+ 1, GFP_KERNEL
);
223 snprintf(tmpname
, NAME_MAX
, "%s%s_%d",
224 chan
->overwrite
? LTT_FLIGHT_PREFIX
: "",
225 chan
->a
.filename
, buf
->a
.cpu
);
227 buf
->a
.dentry
= debugfs_create_file(tmpname
, mode
, parent
, buf
,
228 <t_file_operations
);
229 if (!buf
->a
.dentry
) {
239 int ltt_chanbuf_remove_file(struct ltt_chanbuf
*buf
)
241 debugfs_remove(buf
->a
.dentry
);