Skip to content

Commit

Permalink
Notification of new events is sent only if there is a waiting thread.…
Browse files Browse the repository at this point in the history
… Whitespace fixes (#45)

* Notification of new events is sent only if there is a waiting thread.

Signed-off-by: Tomasz Rybicki <tomasz.rybicki@intel.com>
  • Loading branch information
Tomasz Rybicki authored and Mariusz Barczak committed Jun 21, 2019
1 parent 5a55cf8 commit d5b4396
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 37 deletions.
7 changes: 6 additions & 1 deletion source/kernel/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
#ifndef SOURCE_KERNEL_INTERNAL_CONTEXT_H
#define SOURCE_KERNEL_INTERNAL_CONTEXT_H

#include <asm/atomic.h>
#include "io_trace.h"
#include "procfs.h"
#include "trace_bdev.h"
#include "trace.h"
#include "trace_bdev.h"
#include "trace_env_kernel.h"

/**
* @brief Tracing global context
Expand All @@ -24,6 +26,9 @@ struct iotrace_context {
/** Tracing state (seq no etc) */
struct iotrace_state trace_state;

/** Is there a process waiting for traces flag */
atomic_t __percpu *waiting_for_trace;

/** Log buffer size */
uint64_t size;
};
Expand Down
23 changes: 15 additions & 8 deletions source/kernel/io_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

#include <linux/types.h>
#include <linux/wait.h>
#include "trace_bio.h"
#include <linux/atomic.h>
#include <linux/tracepoint.h>
#include <trace/events/block.h>
#include "trace_bio.h"
#include "io_trace.h"
#include "context.h"
#include "bio.h"
Expand All @@ -19,10 +20,15 @@
static inline void iotrace_notify_of_new_events(struct iotrace_context *context,
unsigned int cpu)
{
wait_queue_head_t *queue =
&(per_cpu_ptr(context->proc_files, cpu)->poll_wait_queue);
/* If process is waiting for traces, reset the flag, notify the process */
if (atomic_cmpxchg(
per_cpu_ptr(context->waiting_for_trace, cpu), 1, 0)) {

wait_queue_head_t *queue =
&(per_cpu_ptr(context->proc_files, cpu)->poll_wait_queue);

wake_up(queue);
wake_up(queue);
}
}

/**
Expand All @@ -37,7 +43,7 @@ static inline void iotrace_notify_of_new_events(struct iotrace_context *context,
* @retval non-zero Error code
*/
int iotrace_trace_desc(struct iotrace_context *iotrace, unsigned cpu,
uint32_t dev_id, const char *dev_name, uint64_t dev_size)
uint32_t dev_id, const char *dev_name, uint64_t dev_size)
{
int result = 0;
struct iotrace_state *state = &iotrace->trace_state;
Expand Down Expand Up @@ -73,7 +79,7 @@ int iotrace_trace_desc(struct iotrace_context *iotrace, unsigned cpu,
*
*/
static void bio_queue_event(void *ignore, struct request_queue *q,
struct bio *bio)
struct bio *bio)
{
uint32_t dev_id;
unsigned cpu = get_cpu();
Expand All @@ -82,6 +88,7 @@ static void bio_queue_event(void *ignore, struct request_queue *q,
if (iotrace_bdev_is_added(&iotrace->bdev, cpu, q)) {
dev_id = disk_devt(bio->bi_bdev->bd_disk);
iotrace_trace_bio(iotrace, cpu, dev_id, bio);

iotrace_notify_of_new_events(iotrace, cpu);
}

Expand Down Expand Up @@ -184,7 +191,7 @@ static int iotrace_set_buffer_size(struct iotrace_context *iotrace, uint64_t siz
uint64_t iotrace_get_buffer_size(struct iotrace_context *iotrace)
{
return iotrace_get_context()->size * num_online_cpus() / 1024ULL /
1024ULL;
1024ULL;
}

/**
Expand Down Expand Up @@ -250,7 +257,7 @@ int iotrace_attach_client(struct iotrace_context *iotrace)
result = register_trace_block_bio_queue(bio_queue_event, NULL);
if (result) {
printk(KERN_ERR "Failed to register trace probe: %d\n",
result);
result);
deinit_tracers(state);
goto exit;
}
Expand Down
88 changes: 60 additions & 28 deletions source/kernel/procfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/

#include <asm/atomic.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/kref.h>
Expand Down Expand Up @@ -82,29 +83,51 @@ static int _iotrace_release(struct inode *inode, struct file *file)
}

static ssize_t _iotrace_read(struct file *file, char __user *data, size_t size,
loff_t *off)
loff_t *off)
{
return -ENOTSUPP;
}

/* This function is called after a process calls select() or poll() on given
* file to wait for it's readiness. The process then blocks and waits until we
* return non-zero value in _iotrace_poll. The 'poll_wait' function used here is
* nonblocking despite it's name, and only registers this function.
* _iotrace_poll can later be invoked again when the supplied wait_queue is
* triggered. This means that one call to select()/poll() can correspond to many
* calls of _iotrace_poll.
* Note also that select()/poll() can be used to watch many files at once, and
* if any of them returns non-zero value, it could trigger this function at any
* time. */
static unsigned int _iotrace_poll(struct file *file, poll_table *wait)
{
/* Get file and trace handle */
struct iotrace_proc_file *proc_file = file->private_data;
octf_trace_t handle = *per_cpu_ptr(
iotrace_get_context()->trace_state.traces, smp_processor_id());

/* Register in poll wait_queue */
poll_wait(file, &proc_file->poll_wait_queue, wait);

if (!octf_trace_is_empty(handle))
/* Traces are present, report readiness */
if (!octf_trace_is_empty(handle)) {
/* No one is waiting for trace now */
atomic_set(
per_cpu_ptr(iotrace_get_context()->waiting_for_trace,
smp_processor_id()), 0);
return POLLIN | POLLRDNORM;
}

/* No events ready - set flag which informs that there is a process
* waiting for traces */
atomic_set(
per_cpu_ptr(iotrace_get_context()->waiting_for_trace
, smp_processor_id()), 1);

/* No events ready */
return 0;
}

static ssize_t _iotrace_write(struct file *file, const char __user *data,
size_t size, loff_t *off)
size_t size, loff_t *off)
{
return -ENOTSUPP;
}
Expand All @@ -116,7 +139,7 @@ static loff_t _iotrace_llseek(struct file *file, loff_t offset, int whence)

#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 10, 0)
int _iotrace_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
bool trace_ring)
bool trace_ring)
#else
int _iotrace_fault(struct vm_fault *vmf, bool trace_ring)
#endif
Expand Down Expand Up @@ -173,7 +196,7 @@ static const struct vm_operations_struct _iotrace_vm_ops_consumer_hdr = {
};

static int _iotrace_mmap_trace_ring(struct file *file,
struct vm_area_struct *vma)
struct vm_area_struct *vma)
{
/* do not allow write-mapping */
if (vma->vm_flags & VM_WRITE)
Expand All @@ -190,7 +213,7 @@ static int _iotrace_mmap_trace_ring(struct file *file,
}

static int _iotrace_mmap_consumer_hdr(struct file *file,
struct vm_area_struct *vma)
struct vm_area_struct *vma)
{
vma->vm_ops = &_iotrace_vm_ops_consumer_hdr;
return 0;
Expand Down Expand Up @@ -363,7 +386,7 @@ static int _add_dev_scanf(const char *buf)
* @retval number of bytes read from @ubuf
*/
static ssize_t add_dev_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
size_t count, loff_t *ppos)
{
return iotrace_mngt_write(file, ubuf, count, ppos, _add_dev_scanf);
}
Expand All @@ -384,7 +407,7 @@ static int _del_dev_scanf(const char *buf)
* @retval number of bytes read from @ubuf
*/
static ssize_t del_dev_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
size_t count, loff_t *ppos)
{
return iotrace_mngt_write(file, ubuf, count, ppos, _del_dev_scanf);
}
Expand Down Expand Up @@ -500,9 +523,9 @@ static ssize_t size_write(struct file *file, const char __user *ubuf,

/* device management files ops */
static struct file_operations add_dev_ops = { .owner = THIS_MODULE,
.write = add_dev_write };
.write = add_dev_write };
static struct file_operations del_dev_ops = { .owner = THIS_MODULE,
.write = del_dev_write };
.write = del_dev_write };
static struct file_operations list_dev_ops = {
.owner = THIS_MODULE,
.read = list_dev_read,
Expand Down Expand Up @@ -534,29 +557,29 @@ static int iotrace_procfs_mngt_init(void)
umode_t mode;
} entries[] = {
{
.name = IOTRACE_PROCFS_DEVICES_FILE_NAME,
.ops = &list_dev_ops,
.mode = S_IRUSR,
.name = IOTRACE_PROCFS_DEVICES_FILE_NAME,
.ops = &list_dev_ops,
.mode = S_IRUSR,
},
{
.name = IOTRACE_PROCFS_ADD_DEVICE_FILE_NAME,
.ops = &add_dev_ops,
.mode = S_IWUSR,
.name = IOTRACE_PROCFS_ADD_DEVICE_FILE_NAME,
.ops = &add_dev_ops,
.mode = S_IWUSR,
},
{
.name = IOTRACE_PROCFS_REMOVE_DEVICE_FILE_NAME,
.ops = &del_dev_ops,
.mode = S_IWUSR,
.name = IOTRACE_PROCFS_REMOVE_DEVICE_FILE_NAME,
.ops = &del_dev_ops,
.mode = S_IWUSR,
},
{
.name = IOTRACE_PROCFS_VERSION_FILE_NAME,
.ops = &get_version_ops,
.mode = S_IRUSR,
.name = IOTRACE_PROCFS_VERSION_FILE_NAME,
.ops = &get_version_ops,
.mode = S_IRUSR,
},
{
.name = IOTRACE_PROCFS_SIZE_FILE_NAME,
.ops = &size_ops,
.mode = S_IRUSR | S_IWUSR,
.name = IOTRACE_PROCFS_SIZE_FILE_NAME,
.ops = &size_ops,
.mode = S_IRUSR | S_IWUSR,
},
};
size_t num_entries = sizeof(entries) / sizeof(entries[0]);
Expand All @@ -573,7 +596,7 @@ static int iotrace_procfs_mngt_init(void)
ent = proc_create(entries[i].name, entries[i].mode, dir, entries[i].ops);
if (!ent) {
printk(KERN_ERR "Cannot create /proc/%s/%s\n",
iotrace_subdir, entries[i].name);
iotrace_subdir, entries[i].name);
break;
}
}
Expand All @@ -589,7 +612,7 @@ static int iotrace_procfs_mngt_init(void)

/* Allocate buffer for traces */
int iotrace_procfs_trace_file_alloc(struct iotrace_proc_file *proc_file,
uint64_t size, int cpu)
uint64_t size, int cpu)
{
void *buffer;
uint64_t allocation_size;
Expand Down Expand Up @@ -739,6 +762,13 @@ int iotrace_procfs_init(struct iotrace_context *iotrace)
if (!iotrace->proc_files)
return -ENOMEM;

/* For each cpu (and thus trace file) allocate atomic flag */
iotrace->waiting_for_trace = alloc_percpu(atomic_t);
if (!iotrace->waiting_for_trace) {
result = -ENOMEM;
goto error;
}

result = iotrace_procfs_mngt_init();
if (result)
goto error;
Expand Down Expand Up @@ -766,6 +796,7 @@ int iotrace_procfs_init(struct iotrace_context *iotrace)

error:
free_percpu(iotrace->proc_files);
free_percpu(iotrace->waiting_for_trace);
return result;
}

Expand All @@ -784,6 +815,7 @@ void iotrace_procfs_deinit(struct iotrace_context *iotrace)
per_cpu_ptr(iotrace->proc_files, i));

free_percpu(iotrace->proc_files);
free_percpu(iotrace->waiting_for_trace);

iotrace_procfs_mngt_deinit();
}

0 comments on commit d5b4396

Please sign in to comment.