Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/kernel_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: blktests-ci

on:
pull_request:

jobs:
build-kernel:
runs-on: ubuntu-latest
steps:
- name: Configure git
run: |
git config --global --add safe.directory '*'
- name: Checkout git
run: |
sudo apt-get install -y libelf-dev
mkdir -p linux
cd linux
git init
git remote add origin https://github.com/${{ github.repository }}
git fetch origin --depth=5 ${{ github.event.pull_request.head.sha }}
git reset --hard ${{ github.event.pull_request.head.sha }}
git log -1
- name: Build kernel
run: |
cd linux
make defconfig
make -j 8

3 changes: 1 addition & 2 deletions drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,7 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
*/
static int subbuf_start_callback(struct rchan_buf *buf,
void *subbuf,
void *prev_subbuf,
size_t prev_padding)
void *prev_subbuf)
{
/*
* Use no-overwrite mode by default, where relay will stop accepting
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wwan/iosm/iosm_ipc_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ static int ipc_trace_remove_buf_file_handler(struct dentry *dentry)
}

static int ipc_trace_subbuf_start_handler(struct rchan_buf *buf, void *subbuf,
void *prev_subbuf,
size_t prev_padding)
void *prev_subbuf)
{
if (relay_buf_full(buf)) {
pr_err_ratelimited("Relay_buf full dropping traces");
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wwan/t7xx/t7xx_port_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static int t7xx_trace_remove_buf_file_handler(struct dentry *dentry)
}

static int t7xx_trace_subbuf_start_handler(struct rchan_buf *buf, void *subbuf,
void *prev_subbuf, size_t prev_padding)
void *prev_subbuf)
{
if (relay_buf_full(buf)) {
pr_err_ratelimited("Relay_buf full dropping traces");
Expand Down
24 changes: 19 additions & 5 deletions include/linux/relay.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@
*/
#define RELAYFS_CHANNEL_VERSION 7

/*
* Relay buffer statistics
*/
enum {
RELAY_STATS_BUF_FULL = (1 << 0),
RELAY_STATS_WRT_BIG = (1 << 1),

RELAY_STATS_LAST = RELAY_STATS_WRT_BIG,
};

struct rchan_buf_stats
{
unsigned int full_count; /* counter for buffer full */
unsigned int big_count; /* counter for too big to write */
};

/*
* Per-cpu relay channel buffer
*/
Expand All @@ -43,11 +59,11 @@ struct rchan_buf
struct irq_work wakeup_work; /* reader wakeup */
struct dentry *dentry; /* channel file dentry */
struct kref kref; /* channel buffer refcount */
struct rchan_buf_stats stats; /* buffer stats */
struct page **page_array; /* array of current buffer pages */
unsigned int page_count; /* number of current buffer pages */
unsigned int finalized; /* buffer has been finalized */
size_t *padding; /* padding counts per sub-buffer */
size_t prev_padding; /* temporary variable */
size_t bytes_consumed; /* bytes consumed in cur read subbuf */
size_t early_bytes; /* bytes consumed before VFS inited */
unsigned int cpu; /* this buf's cpu */
Expand All @@ -65,7 +81,6 @@ struct rchan
const struct rchan_callbacks *cb; /* client callbacks */
struct kref kref; /* channel refcount */
void *private_data; /* for user-defined data */
size_t last_toobig; /* tried to log event > subbuf size */
struct rchan_buf * __percpu *buf; /* per-cpu channel buffers */
int is_global; /* One global buffer ? */
struct list_head list; /* for channel list */
Expand All @@ -84,7 +99,6 @@ struct rchan_callbacks
* @buf: the channel buffer containing the new sub-buffer
* @subbuf: the start of the new sub-buffer
* @prev_subbuf: the start of the previous sub-buffer
* @prev_padding: unused space at the end of previous sub-buffer
*
* The client should return 1 to continue logging, 0 to stop
* logging.
Expand All @@ -100,8 +114,7 @@ struct rchan_callbacks
*/
int (*subbuf_start) (struct rchan_buf *buf,
void *subbuf,
void *prev_subbuf,
size_t prev_padding);
void *prev_subbuf);

/*
* create_buf_file - create file to represent a relay channel buffer
Expand Down Expand Up @@ -161,6 +174,7 @@ struct rchan *relay_open(const char *base_filename,
void *private_data);
extern void relay_close(struct rchan *chan);
extern void relay_flush(struct rchan *chan);
size_t relay_stats(struct rchan *chan, int flags);
extern void relay_subbufs_consumed(struct rchan *chan,
unsigned int cpu,
size_t consumed);
Expand Down
66 changes: 53 additions & 13 deletions kernel/relay.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,18 @@ EXPORT_SYMBOL_GPL(relay_buf_full);
*/

static int relay_subbuf_start(struct rchan_buf *buf, void *subbuf,
void *prev_subbuf, size_t prev_padding)
void *prev_subbuf)
{
int full = relay_buf_full(buf);

if (full)
buf->stats.full_count++;

if (!buf->chan->cb->subbuf_start)
return !relay_buf_full(buf);
return !full;

return buf->chan->cb->subbuf_start(buf, subbuf,
prev_subbuf, prev_padding);
prev_subbuf);
}

/**
Expand Down Expand Up @@ -298,11 +303,13 @@ static void __relay_reset(struct rchan_buf *buf, unsigned int init)
buf->finalized = 0;
buf->data = buf->start;
buf->offset = 0;
buf->stats.full_count = 0;
buf->stats.big_count = 0;

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

relay_subbuf_start(buf, buf->data, NULL, 0);
relay_subbuf_start(buf, buf->data, NULL);
}

/**
Expand Down Expand Up @@ -555,9 +562,11 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length)
goto toobig;

if (buf->offset != buf->chan->subbuf_size + 1) {
buf->prev_padding = buf->chan->subbuf_size - buf->offset;
size_t prev_padding;

prev_padding = buf->chan->subbuf_size - buf->offset;
old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
buf->padding[old_subbuf] = buf->prev_padding;
buf->padding[old_subbuf] = prev_padding;
buf->subbufs_produced++;
if (buf->dentry)
d_inode(buf->dentry)->i_size +=
Expand All @@ -582,7 +591,7 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length)
new_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
new = buf->start + new_subbuf * buf->chan->subbuf_size;
buf->offset = 0;
if (!relay_subbuf_start(buf, new, old, buf->prev_padding)) {
if (!relay_subbuf_start(buf, new, old)) {
buf->offset = buf->chan->subbuf_size + 1;
return 0;
}
Expand All @@ -595,7 +604,7 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length)
return length;

toobig:
buf->chan->last_toobig = length;
buf->stats.big_count++;
return 0;
}
EXPORT_SYMBOL_GPL(relay_switch_subbuf);
Expand Down Expand Up @@ -655,11 +664,6 @@ void relay_close(struct rchan *chan)
if ((buf = *per_cpu_ptr(chan->buf, i)))
relay_close_buf(buf);

if (chan->last_toobig)
printk(KERN_WARNING "relay: one or more items not logged "
"[item size (%zd) > sub-buffer size (%zd)]\n",
chan->last_toobig, chan->subbuf_size);

list_del(&chan->list);
kref_put(&chan->kref, relay_destroy_channel);
mutex_unlock(&relay_channels_mutex);
Expand Down Expand Up @@ -693,6 +697,42 @@ void relay_flush(struct rchan *chan)
}
EXPORT_SYMBOL_GPL(relay_flush);

/**
* relay_stats - get channel buffer statistics
* @chan: the channel
* @flags: select particular information to get
*
* Returns the count of certain field that caller specifies.
*/
size_t relay_stats(struct rchan *chan, int flags)
{
unsigned int i, count = 0;
struct rchan_buf *rbuf;

if (!chan || flags > RELAY_STATS_LAST)
return 0;

if (chan->is_global) {
rbuf = *per_cpu_ptr(chan->buf, 0);
if (flags & RELAY_STATS_BUF_FULL)
count = rbuf->stats.full_count;
else if (flags & RELAY_STATS_WRT_BIG)
count = rbuf->stats.big_count;
} else {
for_each_online_cpu(i) {
rbuf = *per_cpu_ptr(chan->buf, i);
if (rbuf) {
if (flags & RELAY_STATS_BUF_FULL)
count += rbuf->stats.full_count;
else if (flags & RELAY_STATS_WRT_BIG)
count += rbuf->stats.big_count;
}
}
}

return count;
}

/**
* relay_file_open - open file op for relay files
* @inode: the inode
Expand Down
22 changes: 2 additions & 20 deletions kernel/trace/blktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,10 @@ static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
size_t count, loff_t *ppos)
{
struct blk_trace *bt = filp->private_data;
size_t dropped = relay_stats(bt->rchan, RELAY_STATS_BUF_FULL);
char buf[16];

snprintf(buf, sizeof(buf), "%u\n", atomic_read(&bt->dropped));
snprintf(buf, sizeof(buf), "%lu\n", dropped);

return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
}
Expand Down Expand Up @@ -456,23 +457,6 @@ static const struct file_operations blk_msg_fops = {
.llseek = noop_llseek,
};

/*
* Keep track of how many times we encountered a full subbuffer, to aid
* the user space app in telling how many lost events there were.
*/
static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
void *prev_subbuf, size_t prev_padding)
{
struct blk_trace *bt;

if (!relay_buf_full(buf))
return 1;

bt = buf->chan->private_data;
atomic_inc(&bt->dropped);
return 0;
}

static int blk_remove_buf_file_callback(struct dentry *dentry)
{
debugfs_remove(dentry);
Expand All @@ -491,7 +475,6 @@ static struct dentry *blk_create_buf_file_callback(const char *filename,
}

static const struct rchan_callbacks blk_relay_callbacks = {
.subbuf_start = blk_subbuf_start_callback,
.create_buf_file = blk_create_buf_file_callback,
.remove_buf_file = blk_remove_buf_file_callback,
};
Expand Down Expand Up @@ -580,7 +563,6 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
}

bt->dev = dev;
atomic_set(&bt->dropped, 0);
INIT_LIST_HEAD(&bt->running_list);

ret = -EIO;
Expand Down