summaryrefslogtreecommitdiffstats
path: root/fs/proc/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/array.c')
-rw-r--r--fs/proc/array.c105
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 */