This patch enables the maximum size of the ACPI thread pool to be configured by a /proc filesystem entry. This limit is imposed in case a rogue BIOS DSDT tries to create too many threads. Peter Signed-off-by: Peter Wainwright <prw@xxxxxxxxxxxxxxxxxxxxx>
diff -u -r linux-2.6.16.11-prw2-old/drivers/acpi/osl.c linux-2.6.16.11-prw2/drivers/acpi/osl.c --- linux-2.6.16.11-prw2-old/drivers/acpi/osl.c 2006-05-03 21:14:05.000000000 +0100 +++ linux-2.6.16.11-prw2/drivers/acpi/osl.c 2006-05-03 21:16:30.000000000 +0100 @@ -47,6 +47,8 @@ #include <linux/efi.h> #include <linux/kthread.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME("osl") @@ -109,6 +111,66 @@ struct list_head list; }; +static int acpi_osl_pool_size_read(struct seq_file *seq, void *offset) +{ + struct list_head *l; + + ACPI_FUNCTION_TRACE("acpi_osl_pool_size_read"); + + seq_printf(seq, "max_pool_size=%d\n", max_pool_size); + seq_printf(seq, "current_pool_size=%d\n", current_pool_size); + /* FIXME: Need lock? */ + list_for_each(l, &thread_pool) { + struct thread_pool_entry *e = list_entry(l, struct thread_pool_entry, list); + seq_printf(seq, "entry=(%p,%d,%p,%p,%lu)\n", + e->thread, e->active, e->function, e->context, e->jiffies); + } + return_VALUE(0); +} + +static int acpi_osl_pool_size_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_osl_pool_size_read, PDE(inode)->data); +} + +static ssize_t +acpi_osl_pool_size_write(struct file *file, + const char __user * buffer, + size_t count, loff_t * ppos) +{ + char *size_string; + + ACPI_FUNCTION_TRACE("acpi_osl_pool_size_write"); + + size_string = kmalloc(4096, GFP_KERNEL); + if (!size_string) + return_VALUE(-ENOMEM); + + memset(size_string, 0, 4096); + + if (copy_from_user(size_string, buffer, count)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n")); + count = -EFAULT; + goto end; + } + + size_string[count] = '\0'; + max_pool_size = simple_strtol(size_string, NULL, 10); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Pool_Size now %d\n", max_pool_size)); + +end: + kfree(size_string); + return_VALUE(count); +} + +static struct file_operations acpi_osl_pool_size_ops = { + .open = acpi_osl_pool_size_open_fs, + .read = seq_read, + .write = acpi_osl_pool_size_write, + .llseek = seq_lseek, + .release = single_release, +}; + /* This is based on the workqueue worker_thread */ static int acpi_os_execute_worker(void *context) { @@ -247,9 +309,14 @@ /* * Enable reaping of unused threads. + * Enable pool size modification by proc filesystem entry. */ acpi_status acpi_os_initialize2(void) { + struct proc_dir_entry *entry; + entry = create_proc_entry("pool_size", S_IRUSR|S_IWUSR, acpi_root_dir); + if (entry) + entry->proc_fops = &acpi_osl_pool_size_ops; INIT_WORK(&acpi_reap_task, acpi_reap_threads, NULL); init_timer(&acpi_reap_timer); return AE_OK;
Attachment:
signature.asc
Description: This is a digitally signed message part