Multi-threaded execution of ACPI control methods (continued)
RFC PATCH 2/2 Multi-threaded execution of ACPI control methods (continued)
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 <[email protected]>
drivers/acpi/osl.c +67 -0
@@ -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_SERVICESACPI_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 ;