Commit 916e75e3 authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] sys_sysinfo cleanup

Looks like sys_sysinfo has not been touched in years.  Among other
things, it uses a global cli() for protection; I switched it to an
existing rwlock.  I also pulled it out of info.c and stuck it in timer.c
(I choose timer.c because it shares dependencies there already).

The details:

        - move sys_sysinfo to kernel/timer.c from kernel/info.c:
          why one small syscall got its own file is beyond me.

        - delete kernel/info.c

        - stop the global cli!  now grab a read_lock on xtime_lock.
          this is safe as we moved the write_unlock on xtime_lock
          down one line to cover the calculating of avenrun.

        - trivial code cleanup
parent 373c84d2
...@@ -13,7 +13,7 @@ export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \ ...@@ -13,7 +13,7 @@ export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
printk.o platform.o suspend.o printk.o platform.o suspend.o
obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \ obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o info.o time.o softirq.o resource.o \ module.o exit.o itimer.o time.o softirq.o resource.o \
sysctl.o capability.o ptrace.o timer.o user.o \ sysctl.o capability.o ptrace.o timer.o user.o \
signal.o sys.o kmod.o context.o futex.o platform.o signal.o sys.o kmod.o context.o futex.o platform.o
......
/*
* linux/kernel/info.c
*
* Copyright (C) 1992 Darren Senn
*/
/* This implements the sysinfo() system call */
#include <linux/mm.h>
#include <linux/unistd.h>
#include <linux/swap.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
asmlinkage long sys_sysinfo(struct sysinfo *info)
{
struct sysinfo val;
memset((char *)&val, 0, sizeof(struct sysinfo));
cli();
val.uptime = jiffies / HZ;
val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
val.procs = nr_threads;
sti();
si_meminfo(&val);
si_swapinfo(&val);
{
unsigned long mem_total, sav_total;
unsigned int mem_unit, bitcount;
/* If the sum of all the available memory (i.e. ram + swap)
* is less than can be stored in a 32 bit unsigned long then
* we can be binary compatible with 2.2.x kernels. If not,
* well, in that case 2.2.x was broken anyways...
*
* -Erik Andersen <andersee@debian.org> */
mem_total = val.totalram + val.totalswap;
if (mem_total < val.totalram || mem_total < val.totalswap)
goto out;
bitcount = 0;
mem_unit = val.mem_unit;
while (mem_unit > 1) {
bitcount++;
mem_unit >>= 1;
sav_total = mem_total;
mem_total <<= 1;
if (mem_total < sav_total)
goto out;
}
/* If mem_total did not overflow, multiply all memory values by
* val.mem_unit and set it to 1. This leaves things compatible
* with 2.2.x, and also retains compatibility with earlier 2.4.x
* kernels... */
val.mem_unit = 1;
val.totalram <<= bitcount;
val.freeram <<= bitcount;
val.sharedram <<= bitcount;
val.bufferram <<= bitcount;
val.totalswap <<= bitcount;
val.freeswap <<= bitcount;
val.totalhigh <<= bitcount;
val.freehigh <<= bitcount;
}
out:
if (copy_to_user(info, &val, sizeof(struct sysinfo)))
return -EFAULT;
return 0;
}
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* serialize accesses to xtime/lost_ticks). * serialize accesses to xtime/lost_ticks).
* Copyright (C) 1998 Andrea Arcangeli * Copyright (C) 1998 Andrea Arcangeli
* 1999-03-10 Improved NTP compatibility by Ulrich Windl * 1999-03-10 Improved NTP compatibility by Ulrich Windl
* 2002-05-31 Move sys_sysinfo here and make its locking sane, Robert Love
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -605,9 +606,15 @@ static unsigned long count_active_tasks(void) ...@@ -605,9 +606,15 @@ static unsigned long count_active_tasks(void)
* imply that avenrun[] is the standard name for this kind of thing. * imply that avenrun[] is the standard name for this kind of thing.
* Nothing else seems to be standardized: the fractional size etc * Nothing else seems to be standardized: the fractional size etc
* all seem to differ on different machines. * all seem to differ on different machines.
*
* Requires xtime_lock to access.
*/ */
unsigned long avenrun[3]; unsigned long avenrun[3];
/*
* calc_load - given tick count, update the avenrun load estimates.
* This is called while holding a write_lock on xtime_lock.
*/
static inline void calc_load(unsigned long ticks) static inline void calc_load(unsigned long ticks)
{ {
unsigned long active_tasks; /* fixed-point */ unsigned long active_tasks; /* fixed-point */
...@@ -627,7 +634,8 @@ static inline void calc_load(unsigned long ticks) ...@@ -627,7 +634,8 @@ static inline void calc_load(unsigned long ticks)
unsigned long wall_jiffies; unsigned long wall_jiffies;
/* /*
* This spinlock protect us from races in SMP while playing with xtime. -arca * This read-write spinlock protects us from races in SMP while
* playing with xtime and avenrun.
*/ */
rwlock_t xtime_lock = RW_LOCK_UNLOCKED; rwlock_t xtime_lock = RW_LOCK_UNLOCKED;
unsigned long last_time_offset; unsigned long last_time_offset;
...@@ -649,8 +657,8 @@ static inline void update_times(void) ...@@ -649,8 +657,8 @@ static inline void update_times(void)
update_wall_time(ticks); update_wall_time(ticks);
} }
last_time_offset = 0; last_time_offset = 0;
write_unlock_irq(&xtime_lock);
calc_load(ticks); calc_load(ticks);
write_unlock_irq(&xtime_lock);
} }
void timer_bh(void) void timer_bh(void)
...@@ -912,3 +920,73 @@ asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp) ...@@ -912,3 +920,73 @@ asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
return 0; return 0;
} }
/*
* sys_sysinfo - fill in sysinfo struct
*/
asmlinkage long sys_sysinfo(struct sysinfo *info)
{
struct sysinfo val;
unsigned long mem_total, sav_total;
unsigned int mem_unit, bitcount;
memset((char *)&val, 0, sizeof(struct sysinfo));
read_lock_irq(&xtime_lock);
val.uptime = jiffies / HZ;
val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
val.procs = nr_threads;
read_unlock_irq(&xtime_lock);
si_meminfo(&val);
si_swapinfo(&val);
/*
* If the sum of all the available memory (i.e. ram + swap)
* is less than can be stored in a 32 bit unsigned long then
* we can be binary compatible with 2.2.x kernels. If not,
* well, in that case 2.2.x was broken anyways...
*
* -Erik Andersen <andersee@debian.org>
*/
mem_total = val.totalram + val.totalswap;
if (mem_total < val.totalram || mem_total < val.totalswap)
goto out;
bitcount = 0;
mem_unit = val.mem_unit;
while (mem_unit > 1) {
bitcount++;
mem_unit >>= 1;
sav_total = mem_total;
mem_total <<= 1;
if (mem_total < sav_total)
goto out;
}
/*
* If mem_total did not overflow, multiply all memory values by
* val.mem_unit and set it to 1. This leaves things compatible
* with 2.2.x, and also retains compatibility with earlier 2.4.x
* kernels...
*/
val.mem_unit = 1;
val.totalram <<= bitcount;
val.freeram <<= bitcount;
val.sharedram <<= bitcount;
val.bufferram <<= bitcount;
val.totalswap <<= bitcount;
val.freeswap <<= bitcount;
val.totalhigh <<= bitcount;
val.freehigh <<= bitcount;
out:
if (copy_to_user(info, &val, sizeof(struct sysinfo)))
return -EFAULT;
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment