Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177568546
D61548.1794761803.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None
D61548.1794761803.diff
View Options
diff --git a/sys/dev/acpica/Osd/OsdSchedule.c b/sys/dev/acpica/Osd/OsdSchedule.c
--- a/sys/dev/acpica/Osd/OsdSchedule.c
+++ b/sys/dev/acpica/Osd/OsdSchedule.c
@@ -83,7 +83,6 @@
int at_flag;
#define ACPI_TASK_FREE 0
#define ACPI_TASK_USED 1
-#define ACPI_TASK_ENQUEUED 2
};
struct taskqueue *acpi_taskq;
@@ -91,11 +90,12 @@
static int acpi_taskq_started;
/*
- * Preallocate some memory for tasks early enough.
- * malloc(9) cannot be used with spin lock held.
+ * Preallocate memory for tasks, as tasks can be posted from interrupt contexts
+ * where malloc(9) cannot be called, and initialize the taskqueue so we can
+ * enqueue tasks on behalf of drivers.
*/
static void
-acpi_task_init(void *arg)
+acpi_taskq_init(void *arg)
{
if (acpi_max_tasks < 0) {
acpi_max_tasks = ACPI_MAX_TASKS;
@@ -105,39 +105,33 @@
acpi_tasks = malloc(sizeof(*acpi_tasks) * acpi_max_tasks, M_ACPITASK,
M_WAITOK | M_ZERO);
-}
-
-SYSINIT(acpi_tasks, SI_SUB_DRIVERS, SI_ORDER_FIRST, acpi_task_init, NULL);
-
-/*
- * Initialize ACPI task queue.
- */
-static void
-acpi_taskq_init(void *arg)
-{
- int boot_tasks_nb, i;
-
acpi_taskq = taskqueue_create_fast("acpi_task", M_WAITOK,
&taskqueue_thread_enqueue, &acpi_taskq);
+}
+
+SYSINIT(acpi_tasks, SI_SUB_DRIVERS, SI_ORDER_FIRST, acpi_taskq_init, NULL);
+
+/*
+ * Start processing of the taskqueue.
+ */
+static void
+acpi_taskq_kick(void *arg)
+{
+ int boot_tasks_nb;
+
+ if (bootverbose && (boot_tasks_nb = atomic_load_int(&acpi_boot_tasks_nb),
+ boot_tasks_nb > 0))
+ printf("ACPI: Unleashing pending %d tasks\n", boot_tasks_nb);
if (acpi_max_threads < 1)
acpi_max_threads = 1;
taskqueue_start_threads(&acpi_taskq, acpi_max_threads, PWAIT, "acpi_task");
- boot_tasks_nb = atomic_load_int(&acpi_boot_tasks_nb);
- if (boot_tasks_nb > 0) {
- if (bootverbose)
- printf("AcpiOsExecute: enqueue %d pending tasks\n", boot_tasks_nb);
- for (i = 0; i < acpi_max_tasks; i++)
- if (atomic_cmpset_int(&acpi_tasks[i].at_flag, ACPI_TASK_USED,
- ACPI_TASK_USED | ACPI_TASK_ENQUEUED))
- taskqueue_enqueue(acpi_taskq, &acpi_tasks[i].at_task);
- }
- acpi_taskq_started = 1;
+ atomic_store_int(&acpi_taskq_started, 1);
}
-SYSINIT(acpi_taskq, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, acpi_taskq_init, NULL);
+SYSINIT(acpi_taskq, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, acpi_taskq_kick, NULL);
/*
* Bounce through this wrapper function since ACPI-CA doesn't understand
@@ -150,12 +144,13 @@
at = (struct acpi_task_ctx *)context;
at->at_function(at->at_context);
- atomic_clear_int(&at->at_flag, ACPI_TASK_USED | ACPI_TASK_ENQUEUED);
+ atomic_store_int(&at->at_flag, ACPI_TASK_FREE);
}
static ACPI_STATUS
acpi_task_enqueue(int priority, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
{
+ const int started = atomic_load_int(&acpi_taskq_started);
struct acpi_task_ctx *at;
int *high_water_p;
int high_water, i;
@@ -169,8 +164,7 @@
}
/* Update the appropriate high water mark. */
- high_water_p = acpi_taskq_started ? &acpi_tasks_high_water :
- &acpi_boot_tasks_nb;
+ high_water_p = started ? &acpi_tasks_high_water : &acpi_boot_tasks_nb;
while (high_water = atomic_load_int(high_water_p), i + 1 > high_water) {
if (atomic_cmpset_int(high_water_p, high_water, i + 1))
break;
@@ -178,25 +172,18 @@
}
if (at == NULL) {
- printf("AcpiOsExecute: failed to enqueue task, consider increasing "
- "the debug.acpi.max_tasks tunable\n");
+ printf("AcpiOsExecute: Failed to enqueue task! Consider increasing "
+ "the 'debug.acpi.max_tasks' tunable.\n");
return (AE_NO_MEMORY);
}
TASK_INIT(&at->at_task, priority, acpi_task_execute, at);
at->at_function = Function;
at->at_context = Context;
+ taskqueue_enqueue(acpi_taskq, &at->at_task);
- /*
- * If the task queue is ready, enqueue it now.
- */
- if (acpi_taskq_started) {
- atomic_set_int(&at->at_flag, ACPI_TASK_ENQUEUED);
- taskqueue_enqueue(acpi_taskq, &at->at_task);
- return (AE_OK);
- }
- if (bootverbose)
- printf("AcpiOsExecute: task queue not started\n");
+ if (bootverbose && !started)
+ printf("AcpiOsExecute: Task enqueued but processing not started yet\n");
return (AE_OK);
}
@@ -248,15 +235,21 @@
void
AcpiOsWaitEventsComplete(void)
{
- int i;
+ static bool warning_printed = false;
- ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
- for (i = 0; i < acpi_max_tasks; i++)
- if ((atomic_load_acq_int(&acpi_tasks[i].at_flag) &
- ACPI_TASK_ENQUEUED) != 0)
- taskqueue_drain(acpi_taskq, &acpi_tasks[i].at_task);
- return_VOID;
+ if (!atomic_load_int(&acpi_taskq_started) &&
+ atomic_load_int(&acpi_boot_tasks_nb) > 0) {
+ if (!warning_printed) {
+ warning_printed = true;
+ printf("%s: Task processing not started, ignoring request\n",
+ __func__);
+ }
+ } else
+ taskqueue_drain_all(acpi_taskq);
+
+ return_VOID;
}
void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 15, 4:56 PM (22 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41745509
Default Alt Text
D61548.1794761803.diff (4 KB)
Attached To
Mode
D61548: acpi: Tasks: Always enqueue in the taskqueue right away
Attached
Detach File
Event Timeline