mirror of
https://github.com/adulau/aha.git
synced 2025-01-05 15:43:22 +00:00
[PATCH] relayfs: add support for global relay buffers
This patch adds the optional is_global outparam to the create_buf_file() callback. This can be used by clients to create a single global relayfs buffer instead of the default per-cpu buffers. This was suggested as being useful for certain debugging applications where it's more convenient to be able to get all the data from a single channel without having to go to the bother of dealing with per-cpu files. Signed-off-by: Tom Zanussi <zanussi@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
03d78d11d9
commit
e6c08367b8
2 changed files with 32 additions and 11 deletions
|
@ -86,7 +86,8 @@ static void buf_unmapped_default_callback(struct rchan_buf *buf,
|
||||||
static struct dentry *create_buf_file_default_callback(const char *filename,
|
static struct dentry *create_buf_file_default_callback(const char *filename,
|
||||||
struct dentry *parent,
|
struct dentry *parent,
|
||||||
int mode,
|
int mode,
|
||||||
struct rchan_buf *buf)
|
struct rchan_buf *buf,
|
||||||
|
int *is_global)
|
||||||
{
|
{
|
||||||
return relayfs_create_file(filename, parent, mode,
|
return relayfs_create_file(filename, parent, mode,
|
||||||
&relayfs_file_operations, buf);
|
&relayfs_file_operations, buf);
|
||||||
|
@ -170,14 +171,16 @@ static inline void __relay_reset(struct rchan_buf *buf, unsigned int init)
|
||||||
void relay_reset(struct rchan *chan)
|
void relay_reset(struct rchan *chan)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
struct rchan_buf *prev = NULL;
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for (i = 0; i < NR_CPUS; i++) {
|
||||||
if (!chan->buf[i])
|
if (!chan->buf[i] || chan->buf[i] == prev)
|
||||||
continue;
|
break;
|
||||||
__relay_reset(chan->buf[i], 0);
|
__relay_reset(chan->buf[i], 0);
|
||||||
|
prev = chan->buf[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,18 +191,22 @@ void relay_reset(struct rchan *chan)
|
||||||
*/
|
*/
|
||||||
static struct rchan_buf *relay_open_buf(struct rchan *chan,
|
static struct rchan_buf *relay_open_buf(struct rchan *chan,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
struct dentry *parent)
|
struct dentry *parent,
|
||||||
|
int *is_global)
|
||||||
{
|
{
|
||||||
struct rchan_buf *buf;
|
struct rchan_buf *buf;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
|
||||||
|
if (*is_global)
|
||||||
|
return chan->buf[0];
|
||||||
|
|
||||||
buf = relay_create_buf(chan);
|
buf = relay_create_buf(chan);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Create file in fs */
|
/* Create file in fs */
|
||||||
dentry = chan->cb->create_buf_file(filename, parent, S_IRUSR,
|
dentry = chan->cb->create_buf_file(filename, parent, S_IRUSR,
|
||||||
buf);
|
buf, is_global);
|
||||||
if (!dentry) {
|
if (!dentry) {
|
||||||
relay_destroy_buf(buf);
|
relay_destroy_buf(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -273,6 +280,7 @@ struct rchan *relay_open(const char *base_filename,
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct rchan *chan;
|
struct rchan *chan;
|
||||||
char *tmpname;
|
char *tmpname;
|
||||||
|
int is_global = 0;
|
||||||
|
|
||||||
if (!base_filename)
|
if (!base_filename)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -297,7 +305,8 @@ struct rchan *relay_open(const char *base_filename,
|
||||||
|
|
||||||
for_each_online_cpu(i) {
|
for_each_online_cpu(i) {
|
||||||
sprintf(tmpname, "%s%d", base_filename, i);
|
sprintf(tmpname, "%s%d", base_filename, i);
|
||||||
chan->buf[i] = relay_open_buf(chan, tmpname, parent);
|
chan->buf[i] = relay_open_buf(chan, tmpname, parent,
|
||||||
|
&is_global);
|
||||||
chan->buf[i]->cpu = i;
|
chan->buf[i]->cpu = i;
|
||||||
if (!chan->buf[i])
|
if (!chan->buf[i])
|
||||||
goto free_bufs;
|
goto free_bufs;
|
||||||
|
@ -311,6 +320,8 @@ free_bufs:
|
||||||
if (!chan->buf[i])
|
if (!chan->buf[i])
|
||||||
break;
|
break;
|
||||||
relay_close_buf(chan->buf[i]);
|
relay_close_buf(chan->buf[i]);
|
||||||
|
if (is_global)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
kfree(tmpname);
|
kfree(tmpname);
|
||||||
|
|
||||||
|
@ -420,14 +431,16 @@ void relay_destroy_channel(struct kref *kref)
|
||||||
void relay_close(struct rchan *chan)
|
void relay_close(struct rchan *chan)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
struct rchan_buf *prev = NULL;
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for (i = 0; i < NR_CPUS; i++) {
|
||||||
if (!chan->buf[i])
|
if (!chan->buf[i] || chan->buf[i] == prev)
|
||||||
continue;
|
break;
|
||||||
relay_close_buf(chan->buf[i]);
|
relay_close_buf(chan->buf[i]);
|
||||||
|
prev = chan->buf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan->last_toobig)
|
if (chan->last_toobig)
|
||||||
|
@ -447,14 +460,16 @@ void relay_close(struct rchan *chan)
|
||||||
void relay_flush(struct rchan *chan)
|
void relay_flush(struct rchan *chan)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
struct rchan_buf *prev = NULL;
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for (i = 0; i < NR_CPUS; i++) {
|
||||||
if (!chan->buf[i])
|
if (!chan->buf[i] || chan->buf[i] == prev)
|
||||||
continue;
|
break;
|
||||||
relay_switch_subbuf(chan->buf[i], 0);
|
relay_switch_subbuf(chan->buf[i], 0);
|
||||||
|
prev = chan->buf[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,7 @@ struct rchan_callbacks
|
||||||
* @parent: the parent of the file to create
|
* @parent: the parent of the file to create
|
||||||
* @mode: the mode of the file to create
|
* @mode: the mode of the file to create
|
||||||
* @buf: the channel buffer
|
* @buf: the channel buffer
|
||||||
|
* @is_global: outparam - set non-zero if the buffer should be global
|
||||||
*
|
*
|
||||||
* Called during relay_open(), once for each per-cpu buffer,
|
* Called during relay_open(), once for each per-cpu buffer,
|
||||||
* to allow the client to create a file to be used to
|
* to allow the client to create a file to be used to
|
||||||
|
@ -126,12 +127,17 @@ struct rchan_callbacks
|
||||||
* The callback should return the dentry of the file created
|
* The callback should return the dentry of the file created
|
||||||
* to represent the relay buffer.
|
* to represent the relay buffer.
|
||||||
*
|
*
|
||||||
|
* Setting the is_global outparam to a non-zero value will
|
||||||
|
* cause relay_open() to create a single global buffer rather
|
||||||
|
* than the default set of per-cpu buffers.
|
||||||
|
*
|
||||||
* See Documentation/filesystems/relayfs.txt for more info.
|
* See Documentation/filesystems/relayfs.txt for more info.
|
||||||
*/
|
*/
|
||||||
struct dentry *(*create_buf_file)(const char *filename,
|
struct dentry *(*create_buf_file)(const char *filename,
|
||||||
struct dentry *parent,
|
struct dentry *parent,
|
||||||
int mode,
|
int mode,
|
||||||
struct rchan_buf *buf);
|
struct rchan_buf *buf,
|
||||||
|
int *is_global);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove_buf_file - remove file representing a relayfs channel buffer
|
* remove_buf_file - remove file representing a relayfs channel buffer
|
||||||
|
|
Loading…
Reference in a new issue