summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-05 06:47:02 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-05 06:47:02 +0000
commit99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch)
tree3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /kernel
parente73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff)
Merge with Linux 2.3.38.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/kmod.c33
-rw-r--r--kernel/ksyms.c20
-rw-r--r--kernel/panic.c15
-rw-r--r--kernel/resource.c2
-rw-r--r--kernel/sched.c5
-rw-r--r--kernel/sysctl.c3
7 files changed, 59 insertions, 21 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 00d0dfa69..2c6f4d971 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,7 +8,7 @@
# Note 2! The CFLAGS definitions are now in the main makefile...
.S.s:
- $(CPP) -traditional $< -o $*.s
+ $(CPP) $(CPPFLAGS) -traditional $< -o $*.s
O_TARGET := kernel.o
O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 36d754380..22c7509a8 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -7,6 +7,10 @@
Modified to avoid chroot and file sharing problems.
Mikael Pettersson
+
+ Limit the concurrent number of kmod modprobes to catch loops from
+ "modprobe needs a service that is in a module".
+ Keith Owens <kaos@ocs.com.au> December 1999
*/
#define __KERNEL_SYSCALLS__
@@ -22,6 +26,8 @@
*/
char modprobe_path[256] = "/sbin/modprobe";
+extern int max_threads;
+
static inline void
use_init_fs_context(void)
{
@@ -113,6 +119,10 @@ int request_module(const char * module_name)
int pid;
int waitpid_result;
sigset_t tmpsig;
+ int i;
+ static atomic_t kmod_concurrent = ATOMIC_INIT(0);
+#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
+ static int kmod_loop_msg;
/* Don't allow request_module() before the root fs is mounted! */
if ( ! current->fs->root ) {
@@ -121,9 +131,31 @@ int request_module(const char * module_name)
return -EPERM;
}
+ /* If modprobe needs a service that is in a module, we get a recursive
+ * loop. Limit the number of running kmod threads to max_threads/2 or
+ * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
+ * would be to run the parents of this process, counting how many times
+ * kmod was invoked. That would mean accessing the internals of the
+ * process tables to get the command line, proc_pid_cmdline is static
+ * and it is not worth changing the proc code just to handle this case.
+ * KAO.
+ */
+ i = max_threads/2;
+ if (i > MAX_KMOD_CONCURRENT)
+ i = MAX_KMOD_CONCURRENT;
+ atomic_inc(&kmod_concurrent);
+ if (atomic_read(&kmod_concurrent) > i) {
+ if (kmod_loop_msg++ < 5)
+ printk(KERN_ERR
+ "kmod: runaway modprobe loop assumed and stopped\n");
+ atomic_dec(&kmod_concurrent);
+ return -ENOMEM;
+ }
+
pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
if (pid < 0) {
printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
+ atomic_dec(&kmod_concurrent);
return pid;
}
@@ -135,6 +167,7 @@ int request_module(const char * module_name)
spin_unlock_irq(&current->sigmask_lock);
waitpid_result = waitpid(pid, NULL, __WCLONE);
+ atomic_dec(&kmod_concurrent);
/* Allow signals again.. */
spin_lock_irq(&current->sigmask_lock);
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 600395f49..04690c563 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -52,8 +52,6 @@
extern int console_loglevel;
extern void set_device_ro(kdev_t dev,int flag);
-extern struct file_operations * get_blkfops(unsigned int);
-extern int blkdev_release(struct inode * inode);
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
extern int (*do_nfsservctl)(int, void *, void *);
#endif
@@ -99,6 +97,7 @@ EXPORT_SYMBOL(__free_pages_ok);
#ifndef CONFIG_DISCONTIGMEM
EXPORT_SYMBOL(contig_page_data);
#endif
+EXPORT_SYMBOL(num_physpages);
EXPORT_SYMBOL(kmem_find_general_cachep);
EXPORT_SYMBOL(kmem_cache_create);
EXPORT_SYMBOL(kmem_cache_destroy);
@@ -225,6 +224,13 @@ EXPORT_SYMBOL(page_readlink);
EXPORT_SYMBOL(page_follow_link);
EXPORT_SYMBOL(block_symlink);
+/* for stackable file systems (lofs, wrapfs, etc.) */
+EXPORT_SYMBOL(add_to_page_cache);
+EXPORT_SYMBOL(filemap_nopage);
+EXPORT_SYMBOL(filemap_swapout);
+EXPORT_SYMBOL(filemap_sync);
+EXPORT_SYMBOL(remove_inode_page);
+
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
EXPORT_SYMBOL(do_nfsservctl);
#endif
@@ -251,9 +257,10 @@ EXPORT_SYMBOL(is_read_only);
EXPORT_SYMBOL(set_device_ro);
EXPORT_SYMBOL(bmap);
EXPORT_SYMBOL(sync_dev);
-EXPORT_SYMBOL(get_blkfops);
EXPORT_SYMBOL(blkdev_open);
-EXPORT_SYMBOL(blkdev_release);
+EXPORT_SYMBOL(blkdev_get);
+EXPORT_SYMBOL(blkdev_put);
+EXPORT_SYMBOL(ioctl_by_bdev);
EXPORT_SYMBOL(gendisk_head);
EXPORT_SYMBOL(resetup_one_dev);
EXPORT_SYMBOL(unplug_device);
@@ -412,10 +419,6 @@ EXPORT_SYMBOL(clear_inode);
EXPORT_SYMBOL(nr_async_pages);
EXPORT_SYMBOL(___strtok);
EXPORT_SYMBOL(init_special_inode);
-EXPORT_SYMBOL(init_fifo);
-EXPORT_SYMBOL(fifo_inode_operations);
-EXPORT_SYMBOL(chrdev_inode_operations);
-EXPORT_SYMBOL(blkdev_inode_operations);
EXPORT_SYMBOL(read_ahead);
EXPORT_SYMBOL(get_hash_table);
EXPORT_SYMBOL(get_empty_inode);
@@ -452,4 +455,5 @@ EXPORT_SYMBOL(get_fast_time);
/* library functions */
EXPORT_SYMBOL(strnicmp);
+/* init task, for moving kthread roots - ought to export a function ?? */
EXPORT_SYMBOL(init_task_union);
diff --git a/kernel/panic.c b/kernel/panic.c
index 48168d864..8a68b3ad5 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -16,10 +16,6 @@
#include <linux/sysrq.h>
#include <linux/interrupt.h>
-#ifdef __alpha__
-#include <asm/machvec.h>
-#endif
-
asmlinkage void sys_sync(void); /* it's really int */
extern void unblank_console(void);
extern int C_A_D;
@@ -76,11 +72,12 @@ NORET_TYPE void panic(const char * fmt, ...)
machine_restart(NULL);
}
#ifdef __sparc__
- printk("Press L1-A to return to the boot prom\n");
-#endif
-#ifdef __alpha__
- if (alpha_using_srm)
- halt();
+ {
+ extern int stop_a_enabled;
+ /* Make sure the user can actually press L1-A */
+ stop_a_enabled = 1;
+ printk("Press L1-A to return to the boot prom\n");
+ }
#endif
sti();
for(;;) {
diff --git a/kernel/resource.c b/kernel/resource.c
index bdf9fef31..dd81c462b 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -55,7 +55,7 @@ int get_resource_list(struct resource *root, char *buf, int size)
int retval;
fmt = " %08lx-%08lx : %s\n";
- if (root == &ioport_resource)
+ if (root->end < 0x10000)
fmt = " %04lx-%04lx : %s\n";
read_lock(&resource_lock);
retval = do_resource_list(root->child, fmt, 8, buf, buf + size) - buf;
diff --git a/kernel/sched.c b/kernel/sched.c
index e653fd22c..98feadf65 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -273,6 +273,7 @@ send_now:
tsk = cpu_curr(this_cpu);
if (preemption_goodness(tsk, p, this_cpu) > 0)
tsk->need_resched = 1;
+ spin_unlock_irqrestore(&runqueue_lock, flags);
#endif
}
@@ -672,7 +673,7 @@ static inline void __wake_up_common(wait_queue_head_t *q, unsigned int mode, con
#endif
p = curr->task;
state = p->state;
- if (state & mode) {
+ if (state & (mode & ~TASK_EXCLUSIVE)) {
#if WAITQUEUE_DEBUG
curr->__waker = (long)__builtin_return_address(0);
#endif
@@ -680,7 +681,7 @@ static inline void __wake_up_common(wait_queue_head_t *q, unsigned int mode, con
wake_up_process_synchronous(p);
else
wake_up_process(p);
- if (state & TASK_EXCLUSIVE)
+ if (state & mode & TASK_EXCLUSIVE)
break;
}
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index fa69edbac..c4234a0d6 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -60,6 +60,7 @@ extern int sem_ctls[];
#ifdef __sparc__
extern char reboot_command [];
+extern int stop_a_enabled;
#endif
#ifdef __powerpc__
extern unsigned long htab_reclaim_on, zero_paged_on, powersave_nap;
@@ -185,6 +186,8 @@ static ctl_table kern_table[] = {
#ifdef __sparc__
{KERN_SPARC_REBOOT, "reboot-cmd", reboot_command,
256, 0644, NULL, &proc_dostring, &sysctl_string },
+ {KERN_SPARC_STOP_A, "stop-a", &stop_a_enabled, sizeof (int),
+ 0644, NULL, &proc_dointvec},
#endif
#ifdef __powerpc__
{KERN_PPC_HTABRECLAIM, "htab-reclaim", &htab_reclaim_on, sizeof(int),