2005-04-17 02:20:36 +04:00
/**
* @ file oprofile_files . c
*
* @ remark Copyright 2002 OProfile authors
* @ remark Read the file COPYING
*
* @ author John Levon < levon @ movementarian . org >
*/
# include <linux/fs.h>
# include <linux/oprofile.h>
# include "event_buffer.h"
# include "oprofile_stats.h"
# include "oprof.h"
2008-10-16 17:01:40 +04:00
2008-12-16 18:19:54 +03:00
# define BUFFER_SIZE_DEFAULT 131072
# define CPU_BUFFER_SIZE_DEFAULT 8192
# define BUFFER_WATERSHED_DEFAULT 32768 /* FIXME: tune */
2008-12-09 18:56:01 +03:00
2008-12-16 18:19:54 +03:00
unsigned long oprofile_buffer_size ;
unsigned long oprofile_cpu_buffer_size ;
unsigned long oprofile_buffer_watershed ;
2005-04-17 02:20:36 +04:00
2008-09-05 19:12:36 +04:00
static ssize_t depth_read ( struct file * file , char __user * buf , size_t count , loff_t * offset )
2005-04-17 02:20:36 +04:00
{
2008-12-16 18:19:54 +03:00
return oprofilefs_ulong_to_user ( oprofile_backtrace_depth , buf , count ,
offset ) ;
2005-04-17 02:20:36 +04:00
}
2008-09-05 19:12:36 +04:00
static ssize_t depth_write ( struct file * file , char const __user * buf , size_t count , loff_t * offset )
2005-04-17 02:20:36 +04:00
{
unsigned long val ;
int retval ;
if ( * offset )
return - EINVAL ;
retval = oprofilefs_ulong_from_user ( & val , buf , count ) ;
if ( retval )
return retval ;
retval = oprofile_set_backtrace ( val ) ;
if ( retval )
return retval ;
return count ;
}
2007-02-12 11:55:34 +03:00
static const struct file_operations depth_fops = {
2005-04-17 02:20:36 +04:00
. read = depth_read ,
. write = depth_write
} ;
2008-10-16 17:01:40 +04:00
2008-09-05 19:12:36 +04:00
static ssize_t pointer_size_read ( struct file * file , char __user * buf , size_t count , loff_t * offset )
2005-04-17 02:20:36 +04:00
{
return oprofilefs_ulong_to_user ( sizeof ( void * ) , buf , count , offset ) ;
}
2007-02-12 11:55:34 +03:00
static const struct file_operations pointer_size_fops = {
2005-04-17 02:20:36 +04:00
. read = pointer_size_read ,
} ;
2008-09-05 19:12:36 +04:00
static ssize_t cpu_type_read ( struct file * file , char __user * buf , size_t count , loff_t * offset )
2005-04-17 02:20:36 +04:00
{
return oprofilefs_str_to_user ( oprofile_ops . cpu_type , buf , count , offset ) ;
}
2008-10-16 17:01:40 +04:00
2007-02-12 11:55:34 +03:00
static const struct file_operations cpu_type_fops = {
2005-04-17 02:20:36 +04:00
. read = cpu_type_read ,
} ;
2008-10-16 17:01:40 +04:00
2008-09-05 19:12:36 +04:00
static ssize_t enable_read ( struct file * file , char __user * buf , size_t count , loff_t * offset )
2005-04-17 02:20:36 +04:00
{
return oprofilefs_ulong_to_user ( oprofile_started , buf , count , offset ) ;
}
2008-09-05 19:12:36 +04:00
static ssize_t enable_write ( struct file * file , char const __user * buf , size_t count , loff_t * offset )
2005-04-17 02:20:36 +04:00
{
unsigned long val ;
int retval ;
if ( * offset )
return - EINVAL ;
2008-09-24 13:08:52 +04:00
2005-04-17 02:20:36 +04:00
retval = oprofilefs_ulong_from_user ( & val , buf , count ) ;
if ( retval )
return retval ;
2008-10-16 17:01:40 +04:00
2005-04-17 02:20:36 +04:00
if ( val )
retval = oprofile_start ( ) ;
else
oprofile_stop ( ) ;
if ( retval )
return retval ;
return count ;
}
2008-10-16 17:01:40 +04:00
2007-02-12 11:55:34 +03:00
static const struct file_operations enable_fops = {
2005-04-17 02:20:36 +04:00
. read = enable_read ,
. write = enable_write ,
} ;
2008-09-05 19:12:36 +04:00
static ssize_t dump_write ( struct file * file , char const __user * buf , size_t count , loff_t * offset )
2005-04-17 02:20:36 +04:00
{
wake_up_buffer_waiter ( ) ;
return count ;
}
2007-02-12 11:55:34 +03:00
static const struct file_operations dump_fops = {
2005-04-17 02:20:36 +04:00
. write = dump_write ,
} ;
2008-10-16 17:01:40 +04:00
2008-09-05 19:12:36 +04:00
void oprofile_create_files ( struct super_block * sb , struct dentry * root )
2005-04-17 02:20:36 +04:00
{
2008-12-09 18:56:01 +03:00
/* reinitialize default values */
2008-12-16 18:19:54 +03:00
oprofile_buffer_size = BUFFER_SIZE_DEFAULT ;
oprofile_cpu_buffer_size = CPU_BUFFER_SIZE_DEFAULT ;
oprofile_buffer_watershed = BUFFER_WATERSHED_DEFAULT ;
2008-12-09 18:56:01 +03:00
2005-04-17 02:20:36 +04:00
oprofilefs_create_file ( sb , root , " enable " , & enable_fops ) ;
oprofilefs_create_file_perm ( sb , root , " dump " , & dump_fops , 0666 ) ;
oprofilefs_create_file ( sb , root , " buffer " , & event_buffer_fops ) ;
2008-12-16 18:19:54 +03:00
oprofilefs_create_ulong ( sb , root , " buffer_size " , & oprofile_buffer_size ) ;
oprofilefs_create_ulong ( sb , root , " buffer_watershed " , & oprofile_buffer_watershed ) ;
oprofilefs_create_ulong ( sb , root , " cpu_buffer_size " , & oprofile_cpu_buffer_size ) ;
2008-10-16 17:01:40 +04:00
oprofilefs_create_file ( sb , root , " cpu_type " , & cpu_type_fops ) ;
2005-04-17 02:20:36 +04:00
oprofilefs_create_file ( sb , root , " backtrace_depth " , & depth_fops ) ;
oprofilefs_create_file ( sb , root , " pointer_size " , & pointer_size_fops ) ;
oprofile_create_stats_files ( sb , root ) ;
if ( oprofile_ops . create_files )
oprofile_ops . create_files ( sb , root ) ;
}