diff options
Diffstat (limited to 'fs/proc/array.c')
-rw-r--r-- | fs/proc/array.c | 105 |
1 files changed, 89 insertions, 16 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 20cac345a..4671f1a98 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -46,6 +46,8 @@ #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/swap.h> +#include <linux/slab.h> +#include <linux/smp.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -67,7 +69,7 @@ static long read_core(struct inode * inode, struct file * file, int count1; char * pnt; struct user dump; -#ifdef __i386__ +#if defined (__i386__) || defined (__mc68000__) # define FIRST_MAPPED PAGE_SIZE /* we don't have page 0 mapped on x86.. */ #else # define FIRST_MAPPED 0 @@ -121,7 +123,6 @@ struct inode_operations proc_kcore_inode_operations = { &proc_kcore_operations, }; - /* * This function accesses profiling information. The returned data is * binary: the sampling step and the actual contents of the profile @@ -142,7 +143,7 @@ static long read_profile(struct inode *inode, struct file *file, count = (prof_len+1)*sizeof(unsigned int) - p; read = 0; - while (p < sizeof(unsigned int) && count > 0) { + while (p < sizeof(unsigned long) && count > 0) { put_user(*((char *)(&sample_step)+p),buf); buf++; p++; count--; read++; } @@ -153,16 +154,38 @@ static long read_profile(struct inode *inode, struct file *file, return read; } -/* Writing to /proc/profile resets the counters */ +#ifdef __SMP__ + +extern int setup_profiling_timer (unsigned int multiplier); + +/* + * Writing to /proc/profile resets the counters + * + * Writing a 'profiling multiplier' value into it also re-sets the profiling + * interrupt frequency, on architectures that support this. + */ static long write_profile(struct inode * inode, struct file * file, const char * buf, unsigned long count) { - int i=prof_len; + int i=prof_len; + + if (count==sizeof(int)) { + unsigned int multiplier; - while (i--) - prof_buffer[i]=0UL; - return count; + if (copy_from_user(&multiplier, buf, sizeof(int))) + return -EFAULT; + + if (setup_profiling_timer(multiplier)) + return -EINVAL; + } + + while (i--) + prof_buffer[i]=0UL; + return count; } +#else +#define write_profile NULL +#endif static struct file_operations proc_profile_operations = { NULL, /* lseek */ @@ -194,7 +217,9 @@ static int get_kstat(char * buffer) int i, len; unsigned sum = 0; extern unsigned long total_forks; + unsigned long ticks; + ticks = jiffies * smp_num_cpus; for (i = 0 ; i < NR_IRQS ; i++) sum += kstat.interrupts[i]; len = sprintf(buffer, @@ -210,7 +235,7 @@ static int get_kstat(char * buffer) kstat.cpu_user, kstat.cpu_nice, kstat.cpu_system, - jiffies - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system), + ticks - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system), kstat.dk_drive[0], kstat.dk_drive[1], kstat.dk_drive[2], kstat.dk_drive[3], kstat.dk_drive_rio[0], kstat.dk_drive_rio[1], @@ -468,6 +493,30 @@ static unsigned long get_wchan(struct task_struct *p) } return pc; } +#elif defined(__mc68000__) + { + unsigned long fp, pc; + unsigned long stack_page; + int count = 0; + extern int sys_pause (void); + + stack_page = p->kernel_stack_page; + if (!stack_page) + return 0; + fp = ((struct switch_stack *)p->tss.ksp)->a6; + do { + if (fp < stack_page || fp >= 4088+stack_page) + return 0; + pc = ((unsigned long *)fp)[1]; + /* FIXME: This depends on the order of these functions. */ + if ((pc < (unsigned long) __down + || pc >= (unsigned long) add_timer) + && (pc < (unsigned long) schedule + || pc >= (unsigned long) sys_pause)) + return pc; + fp = *(unsigned long *) fp; + } while (count++ < 16); + } #endif return 0; @@ -484,11 +533,21 @@ static unsigned long get_wchan(struct task_struct *p) + (long)&((struct pt_regs *)0)->reg) # define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc))) # define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp) +#elif defined(__mc68000__) +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->tss.esp0 > PAGE_SIZE && \ + MAP_NR((tsk)->tss.esp0) < max_mapnr) \ + eip = ((struct pt_regs *) (tsk)->tss.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp) +#elif defined (__sparc_v9__) +# define KSTK_EIP(tsk) ((tsk)->tss.kregs->tpc) +# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP]) #elif defined(__sparc__) -# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \ - + (long)&((struct pt_regs *)0)->reg) -# define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc))) -# define KSTK_ESP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(u_regs[UREG_FP]))) +# define KSTK_EIP(tsk) ((tsk)->tss.kregs->pc) +# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP]) #elif defined(__mips__) # define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg \ - sizeof(struct pt_regs)) @@ -784,7 +843,7 @@ static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned ++*dirty; if (MAP_NR(pte_page(page)) >= max_mapnr) continue; - if (mem_map[MAP_NR(pte_page(page))].count > 1) + if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) > 1) ++*shared; } while (address < end); } @@ -997,9 +1056,13 @@ extern int get_pci_list(char*); extern int get_md_status (char *); extern int get_rtc_status (char *); extern int get_locks_status (char *); +extern int get_swaparea_info (char *); #ifdef __SMP_PROF__ extern int get_smp_prof_list(char *); #endif +#ifdef CONFIG_ZORRO +extern int zorro_get_list(char *); +#endif static long get_root_array(char * page, int type, char **start, off_t offset, unsigned long length) @@ -1041,6 +1104,9 @@ static long get_root_array(char * page, int type, char **start, case PROC_STAT: return get_kstat(page); + case PROC_SLABINFO: + return get_slabinfo(page); + case PROC_DEVICES: return get_device_list(page); @@ -1068,12 +1134,19 @@ static long get_root_array(char * page, int type, char **start, case PROC_MTAB: return get_filesystem_info( page ); + + case PROC_SWAP: + return get_swaparea_info(page); #ifdef CONFIG_RTC case PROC_RTC: return get_rtc_status(page); #endif case PROC_LOCKS: return get_locks_status(page); +#ifdef CONFIG_ZORRO + case PROC_ZORRO: + return zorro_get_list(page); +#endif } return -EBADF; } @@ -1160,7 +1233,7 @@ static struct file_operations proc_array_operations = { array_read, NULL, /* array_write */ NULL, /* array_readdir */ - NULL, /* array_select */ + NULL, /* array_poll */ NULL, /* array_ioctl */ NULL, /* mmap */ NULL, /* no special open code */ @@ -1206,7 +1279,7 @@ static struct file_operations proc_arraylong_operations = { arraylong_read, NULL, /* array_write */ NULL, /* array_readdir */ - NULL, /* array_select */ + NULL, /* array_poll */ NULL, /* array_ioctl */ NULL, /* mmap */ NULL, /* no special open code */ |