Skip to content

Commit ca01a90

Browse files
JasonXingakpm00
authored andcommitted
relayfs: support a counter tracking if per-cpu buffers is full
When using relay mechanism, we often encounter the case where new data are lost or old unconsumed data are overwritten because of slow reader. Add 'full' field in per-cpu buffer structure to detect if the above case is happening. Relay has two modes: 1) non-overwrite mode, 2) overwrite mode. So buffer being full here respectively means: 1) relayfs doesn't intend to accept new data and then simply drop them, or 2) relayfs is going to start over again and overwrite old unread data with new data. Note: this counter doesn't need any explicit lock to protect from being modified by different threads for the better performance consideration. Writers calling __relay_write/relay_write should consider how to use the lock and ensure it performs under the lock protection, thus it's not necessary to add a new small lock here. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Jason Xing <[email protected]> Reviewed-by: Yushan Zhou <[email protected]> Reviewed-by: Jens Axboe <[email protected]> Reviewed-by: Masami Hiramatsu (Google) <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Steven Rostedt <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 2489e95 commit ca01a90

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

include/linux/relay.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
*/
2929
#define RELAYFS_CHANNEL_VERSION 7
3030

31+
/*
32+
* Relay buffer statistics
33+
*/
34+
struct rchan_buf_stats
35+
{
36+
unsigned int full_count; /* counter for buffer full */
37+
};
38+
3139
/*
3240
* Per-cpu relay channel buffer
3341
*/
@@ -43,6 +51,7 @@ struct rchan_buf
4351
struct irq_work wakeup_work; /* reader wakeup */
4452
struct dentry *dentry; /* channel file dentry */
4553
struct kref kref; /* channel buffer refcount */
54+
struct rchan_buf_stats stats; /* buffer stats */
4655
struct page **page_array; /* array of current buffer pages */
4756
unsigned int page_count; /* number of current buffer pages */
4857
unsigned int finalized; /* buffer has been finalized */

kernel/relay.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,13 @@ EXPORT_SYMBOL_GPL(relay_buf_full);
251251
static int relay_subbuf_start(struct rchan_buf *buf, void *subbuf,
252252
void *prev_subbuf)
253253
{
254+
int full = relay_buf_full(buf);
255+
256+
if (full)
257+
buf->stats.full_count++;
258+
254259
if (!buf->chan->cb->subbuf_start)
255-
return !relay_buf_full(buf);
260+
return !full;
256261

257262
return buf->chan->cb->subbuf_start(buf, subbuf,
258263
prev_subbuf);
@@ -297,6 +302,7 @@ static void __relay_reset(struct rchan_buf *buf, unsigned int init)
297302
buf->finalized = 0;
298303
buf->data = buf->start;
299304
buf->offset = 0;
305+
buf->stats.full_count = 0;
300306

301307
for (i = 0; i < buf->chan->n_subbufs; i++)
302308
buf->padding[i] = 0;

0 commit comments

Comments
 (0)