Page MenuHomeFreeBSD

D8160.id.diff
No OneTemporary

D8160.id.diff

Index: stable/10/sys/kern/subr_taskqueue.c
===================================================================
--- stable/10/sys/kern/subr_taskqueue.c
+++ stable/10/sys/kern/subr_taskqueue.c
@@ -454,9 +454,26 @@
TQ_LOCK(queue);
task = STAILQ_LAST(&queue->tq_queue, task, ta_link);
- if (task != NULL)
- while (task->ta_pending != 0)
- TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0);
+ while (task != NULL && task->ta_pending != 0) {
+ struct task *oldtask;
+ TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0);
+ /*
+ * While we were asleeep the last entry may have been freed.
+ * We need to check if it's still even in the queue.
+ * Not perfect, but it's better than referencing bad memory.
+ * first guess is the current 'end of queue' but if a new
+ * item has been added we need to take the expensive path
+ * Better fix in 11.
+ */
+ oldtask = task;
+ if (oldtask !=
+ (task = STAILQ_LAST(&queue->tq_queue, task, ta_link))) {
+ STAILQ_FOREACH(task, &queue->tq_queue, ta_link) {
+ if (task == oldtask)
+ break;
+ }
+ }
+ }
taskqueue_drain_running(queue);
KASSERT(STAILQ_EMPTY(&queue->tq_queue),
("taskqueue queue is not empty after draining"));

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 9, 10:38 AM (18 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31105454
Default Alt Text
D8160.id.diff (1 KB)

Event Timeline