summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-06-22 22:01:51 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-06-22 22:01:51 -0700
commit2e7f53ec14475d56559bcdd07acfb737b7bff1e9 (patch)
tree964fee6f7bfc40bae796fe137e293c6831103919 /kernel
parent5cb7db89366c7c64c5476bec0a2939c7c75af4c9 (diff)
parent8514206eb4e65262f50d6f18293dc3175ab05693 (diff)
Merge home.transmeta.com:/home/torvalds/v2.5/xfs
into home.transmeta.com:/home/torvalds/v2.5/linux
Diffstat (limited to 'kernel')
-rw-r--r--kernel/acct.c14
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/fork.c10
-rw-r--r--kernel/kmod.c12
-rw-r--r--kernel/ksyms.c1
-rw-r--r--kernel/sched.c26
-rw-r--r--kernel/timer.c4
-rw-r--r--kernel/workqueue.c85
8 files changed, 80 insertions, 74 deletions
diff --git a/kernel/acct.c b/kernel/acct.c
index 9f7cdf9a826b..e63095525ac2 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -54,6 +54,7 @@
#include <linux/jiffies.h>
#include <asm/uaccess.h>
#include <asm/div64.h>
+#include <linux/blkdev.h> /* sector_div */
/*
* These constants control the amount of freespace that suspend and
@@ -100,9 +101,11 @@ static void acct_timeout(unsigned long unused)
*/
static int check_free_space(struct file *file)
{
- struct statfs sbuf;
+ struct kstatfs sbuf;
int res;
int act;
+ sector_t resume;
+ sector_t suspend;
spin_lock(&acct_globals.lock);
res = acct_globals.active;
@@ -113,10 +116,15 @@ static int check_free_space(struct file *file)
/* May block */
if (vfs_statfs(file->f_dentry->d_inode->i_sb, &sbuf))
return res;
+ suspend = sbuf.f_blocks * SUSPEND;
+ resume = sbuf.f_blocks * RESUME;
- if (sbuf.f_bavail <= SUSPEND * sbuf.f_blocks / 100)
+ sector_div(suspend, 100);
+ sector_div(resume, 100);
+
+ if (sbuf.f_bavail <= suspend)
act = -1;
- else if (sbuf.f_bavail >= RESUME * sbuf.f_blocks / 100)
+ else if (sbuf.f_bavail >= resume)
act = 1;
else
act = 0;
diff --git a/kernel/exit.c b/kernel/exit.c
index c5b8ec241a83..7dee095b31bd 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -698,7 +698,7 @@ NORET_TYPE void do_exit(long code)
acct_process(code);
__exit_mm(tsk);
- sem_exit();
+ exit_sem(tsk);
__exit_files(tsk);
__exit_fs(tsk);
exit_namespace(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index fba722be316e..5ef2dca02354 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -39,7 +39,7 @@
#include <asm/tlbflush.h>
extern int copy_semundo(unsigned long clone_flags, struct task_struct *tsk);
-extern void exit_semundo(struct task_struct *tsk);
+extern void exit_sem(struct task_struct *tsk);
/* The idle threads do not count..
* Protected by write_lock_irq(&tasklist_lock)
@@ -887,13 +887,11 @@ struct task_struct *copy_process(unsigned long clone_flags,
if (retval)
goto bad_fork_cleanup_namespace;
- if (clone_flags & CLONE_CHILD_SETTID)
- p->set_child_tid = child_tidptr;
+ p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
* Clear TID on mm_release()?
*/
- if (clone_flags & CLONE_CHILD_CLEARTID)
- p->clear_child_tid = child_tidptr;
+ p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
/*
* Syscall tracing should be turned off in the child regardless
@@ -1034,7 +1032,7 @@ bad_fork_cleanup_fs:
bad_fork_cleanup_files:
exit_files(p); /* blocking */
bad_fork_cleanup_semundo:
- exit_semundo(p);
+ exit_sem(p);
bad_fork_cleanup_security:
security_task_free(p);
bad_fork_cleanup:
diff --git a/kernel/kmod.c b/kernel/kmod.c
index d9e4299a8765..e011611afb7d 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -183,12 +183,15 @@ static int wait_for_helper(void *data)
struct subprocess_info *sub_info = data;
pid_t pid;
- pid = kernel_thread(____call_usermodehelper, sub_info,
- CLONE_VFORK | SIGCHLD);
+ sub_info->retval = 0;
+ pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
if (pid < 0)
sub_info->retval = pid;
else
- sys_wait4(pid, (unsigned int *)&sub_info->retval, 0, NULL);
+ /* We don't have a SIGCHLD signal handler, so this
+ * always returns -ECHILD, but the important thing is
+ * that it blocks. */
+ sys_wait4(pid, NULL, 0, NULL);
complete(sub_info->complete);
return 0;
@@ -231,8 +234,7 @@ static void __call_usermodehelper(void *data)
* (ie. it runs with full root capabilities).
*
* Must be called from process context. Returns a negative error code
- * if program was not execed successfully, or (exitcode << 8 + signal)
- * of the application (0 if wait is not set).
+ * if program was not execed successfully, or 0.
*/
int call_usermodehelper(char *path, char **argv, char **envp, int wait)
{
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index ab547345372e..cbb2313433ce 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -592,7 +592,6 @@ EXPORT_SYMBOL(__tasklet_hi_schedule);
/* init task, for moving kthread roots - ought to export a function ?? */
EXPORT_SYMBOL(init_task);
-EXPORT_SYMBOL(init_thread_union);
EXPORT_SYMBOL(tasklist_lock);
EXPORT_SYMBOL(find_task_by_pid);
diff --git a/kernel/sched.c b/kernel/sched.c
index c603aaa67790..9566cd11de18 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1880,10 +1880,6 @@ asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
return -EFAULT;
- new_mask &= cpu_online_map;
- if (!new_mask)
- return -EINVAL;
-
read_lock(&tasklist_lock);
p = find_process_by_pid(pid);
@@ -1905,8 +1901,7 @@ asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
!capable(CAP_SYS_NICE))
goto out_unlock;
- retval = 0;
- set_cpus_allowed(p, new_mask);
+ retval = set_cpus_allowed(p, new_mask);
out_unlock:
put_task_struct(p);
@@ -2182,10 +2177,7 @@ static void show_task(task_t * p)
else
printk(" (NOTLB)\n");
- {
- extern void show_trace_task(task_t *tsk);
- show_trace_task(p);
- }
+ show_stack(p, NULL);
}
void show_state(void)
@@ -2272,17 +2264,14 @@ typedef struct {
* task must not exit() & deallocate itself prematurely. The
* call is not atomic; no spinlocks may be held.
*/
-void set_cpus_allowed(task_t *p, unsigned long new_mask)
+int set_cpus_allowed(task_t *p, unsigned long new_mask)
{
unsigned long flags;
migration_req_t req;
runqueue_t *rq;
-#if 0 /* FIXME: Grab cpu_lock, return error on this case. --RR */
- new_mask &= cpu_online_map;
- if (!new_mask)
- BUG();
-#endif
+ if (any_online_cpu(new_mask) == NR_CPUS)
+ return -EINVAL;
rq = task_rq_lock(p, &flags);
p->cpus_allowed = new_mask;
@@ -2292,7 +2281,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
*/
if (new_mask & (1UL << task_cpu(p))) {
task_rq_unlock(rq, &flags);
- return;
+ return 0;
}
/*
* If the task is not on a runqueue (and not running), then
@@ -2301,7 +2290,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
if (!p->array && !task_running(rq, p)) {
set_task_cpu(p, any_online_cpu(p->cpus_allowed));
task_rq_unlock(rq, &flags);
- return;
+ return 0;
}
init_completion(&req.done);
req.task = p;
@@ -2311,6 +2300,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
wake_up_process(rq->migration_thread);
wait_for_completion(&req.done);
+ return 0;
}
/* Move (not current) task off this cpu, onto dest cpu. */
diff --git a/kernel/timer.c b/kernel/timer.c
index 5136630693b4..ad3758c663d4 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -439,8 +439,8 @@ repeat:
/*
* Timekeeping variables
*/
-unsigned long tick_usec = TICK_USEC; /* ACTHZ period (usec) */
-unsigned long tick_nsec = TICK_NSEC; /* USER_HZ period (nsec) */
+unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */
+unsigned long tick_nsec = TICK_NSEC; /* ACTHZ period (nsec) */
/*
* The current time
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 968837218657..efeaaa4f0274 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -259,15 +259,41 @@ void flush_workqueue(struct workqueue_struct *wq)
}
}
-struct workqueue_struct *create_workqueue(const char *name)
+static int create_workqueue_thread(struct workqueue_struct *wq,
+ const char *name,
+ int cpu)
{
- int ret, cpu, destroy = 0;
- struct cpu_workqueue_struct *cwq;
startup_t startup;
+ struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+ int ret;
+
+ spin_lock_init(&cwq->lock);
+ cwq->wq = wq;
+ cwq->thread = NULL;
+ cwq->insert_sequence = 0;
+ cwq->remove_sequence = 0;
+ INIT_LIST_HEAD(&cwq->worklist);
+ init_waitqueue_head(&cwq->more_work);
+ init_waitqueue_head(&cwq->work_done);
+ init_completion(&cwq->exit);
+
+ init_completion(&startup.done);
+ startup.cwq = cwq;
+ startup.name = name;
+ ret = kernel_thread(worker_thread, &startup, CLONE_FS | CLONE_FILES);
+ if (ret >= 0) {
+ wait_for_completion(&startup.done);
+ BUG_ON(!cwq->thread);
+ }
+ return ret;
+}
+
+struct workqueue_struct *create_workqueue(const char *name)
+{
+ int cpu, destroy = 0;
struct workqueue_struct *wq;
BUG_ON(strlen(name) > 10);
- startup.name = name;
wq = kmalloc(sizeof(*wq), GFP_KERNEL);
if (!wq)
@@ -276,27 +302,8 @@ struct workqueue_struct *create_workqueue(const char *name)
for (cpu = 0; cpu < NR_CPUS; cpu++) {
if (!cpu_online(cpu))
continue;
- cwq = wq->cpu_wq + cpu;
-
- spin_lock_init(&cwq->lock);
- cwq->wq = wq;
- cwq->thread = NULL;
- cwq->insert_sequence = 0;
- cwq->remove_sequence = 0;
- INIT_LIST_HEAD(&cwq->worklist);
- init_waitqueue_head(&cwq->more_work);
- init_waitqueue_head(&cwq->work_done);
-
- init_completion(&startup.done);
- startup.cwq = cwq;
- ret = kernel_thread(worker_thread, &startup,
- CLONE_FS | CLONE_FILES);
- if (ret < 0)
+ if (create_workqueue_thread(wq, name, cpu) < 0)
destroy = 1;
- else {
- wait_for_completion(&startup.done);
- BUG_ON(!cwq->thread);
- }
}
/*
* Was there any error during startup? If yes then clean up:
@@ -308,28 +315,30 @@ struct workqueue_struct *create_workqueue(const char *name)
return wq;
}
-void destroy_workqueue(struct workqueue_struct *wq)
+static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu)
{
struct cpu_workqueue_struct *cwq;
- int cpu;
- flush_workqueue(wq);
-
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- if (!cpu_online(cpu))
- continue;
- cwq = wq->cpu_wq + cpu;
- if (!cwq->thread)
- continue;
- /*
- * Initiate an exit and wait for it:
- */
- init_completion(&cwq->exit);
+ cwq = wq->cpu_wq + cpu;
+ if (cwq->thread) {
+ /* Tell thread to exit and wait for it. */
cwq->thread = NULL;
wake_up(&cwq->more_work);
wait_for_completion(&cwq->exit);
}
+}
+
+void destroy_workqueue(struct workqueue_struct *wq)
+{
+ int cpu;
+
+ flush_workqueue(wq);
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (cpu_online(cpu))
+ cleanup_workqueue_thread(wq, cpu);
+ }
kfree(wq);
}