Skip to content

Commit

Permalink
oprofile: disable write access to oprofilefs while profiler is running
Browse files Browse the repository at this point in the history
Oprofile counters are setup when profiling is disabled. Thus, writing
to oprofilefs has no immediate effect. Changes are updated only after
oprofile is reenabled.

To keep userland and kernel states synchronized, we now allow
configuration of oprofile only if profiling is disabled.  In this case
it checks if the profiler is running and then disables write access to
oprofilefs by returning -EBUSY. The change should be backward
compatible with current oprofile userland daemon.

Acked-by: Maynard Johnson <[email protected]>
Cc: William Cohen <[email protected]>
Cc: Suravee Suthikulpanit <[email protected]>
Signed-off-by: Robert Richter <[email protected]>
  • Loading branch information
Robert Richter committed Oct 12, 2010
1 parent 0361e02 commit 7df01d9
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 20 deletions.
21 changes: 6 additions & 15 deletions drivers/oprofile/oprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,26 +225,17 @@ void oprofile_shutdown(void)
mutex_unlock(&start_mutex);
}

int oprofile_set_backtrace(unsigned long val)
int oprofile_set_ulong(unsigned long *addr, unsigned long val)
{
int err = 0;
int err = -EBUSY;

mutex_lock(&start_mutex);

if (oprofile_started) {
err = -EBUSY;
goto out;
if (!oprofile_started) {
*addr = val;
err = 0;
}

if (!oprofile_ops.backtrace) {
err = -EINVAL;
goto out;
}

oprofile_backtrace_depth = val;

out:
mutex_unlock(&start_mutex);

return err;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/oprofile/oprof.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void oprofile_create_files(struct super_block *sb, struct dentry *root);
int oprofile_timer_init(struct oprofile_operations *ops);
void oprofile_timer_exit(void);

int oprofile_set_backtrace(unsigned long depth);
int oprofile_set_ulong(unsigned long *addr, unsigned long val);
int oprofile_set_timeout(unsigned long time);

#endif /* OPROF_H */
7 changes: 5 additions & 2 deletions drivers/oprofile/oprofile_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,17 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou
if (*offset)
return -EINVAL;

if (!oprofile_ops.backtrace)
return -EINVAL;

retval = oprofilefs_ulong_from_user(&val, buf, count);
if (retval)
return retval;

retval = oprofile_set_backtrace(val);

retval = oprofile_set_ulong(&oprofile_backtrace_depth, val);
if (retval)
return retval;

return count;
}

Expand Down
8 changes: 6 additions & 2 deletions drivers/oprofile/oprofilefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,20 @@ static ssize_t ulong_read_file(struct file *file, char __user *buf, size_t count

static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_t count, loff_t *offset)
{
unsigned long *value = file->private_data;
unsigned long value;
int retval;

if (*offset)
return -EINVAL;

retval = oprofilefs_ulong_from_user(value, buf, count);
retval = oprofilefs_ulong_from_user(&value, buf, count);
if (retval)
return retval;

retval = oprofile_set_ulong(file->private_data, value);
if (retval)
return retval;

return count;
}

Expand Down

0 comments on commit 7df01d9

Please sign in to comment.