Debugging And Fixing The Linux Kernel Prepare_to_wait

0 Comments

You may encounter an error code saying: prepare_to_wait Linux Kernel. Now there are several ways to solve this problem, which we will discuss shortly.

From:

Morton

Andrew
To: Linus Torvalds
Subject: [Patch 1/4] API Prepare_to_wait/Finish_wait Sleep/Wakeup
Date: Wednesday 25 September 2005 9:07:47 -07:00
Copy: lkml

It costs a whopping 2% on spwecweb on the 8th lane. who will be weaksurprising because __wake_up and other parts don’t wait/wake upobviously in the specweb profiles I’ve seen.Typically, the goal is to reduce the CPU’s wait/wake cost.Deal. When the task wakes up again, its queue is removed along with it.waitqueue_head waking up (i.e.: immediately), not waking uptreat.This means that a subsequent awakening is not required to view thisjust awakened task. It also means that the task that just woke up is not needed.to acquire the waitqueue_head lock, which may very well be in anotherProcessor cache.I haven’t been able to change decent different sizes for this – maybe20-30% Off Just __wake_up Trialyu badari from 40 dds to 40 disks (this iswas the most expensive feature), but may not be final. And there is no exam.quantitatively from what I know began to be producedconnect people.The API is extremely easy to use (Linus created this situation):my_func(waitqueue_head_t &wait, *wqh)DEFINE_WAIT(wait);prepare_to_wait(wqh, TASK_UNINTERRUPTIBLE);if (!any_test)Hourly();finish_wait(wqh, &wait);Where:DEFINE_WAIT(wait);during (!some_test_1)prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);if (!any_test_2)Hourly();…finish_wait(wqh, &wait);You need to consider what often happens after you run prepare_to_waitYour task can be removed from the wait_head queue and placed inTASK_RUNNING at any time. You don’t know if you’re still or notwaiting queue_head.Running Prepare_to_Wait() when you are already in the wait queue iswell everything will be fine.Executing finish_wait() when you are not in the wait_head queueGreat.The execution of finish_wait() is the time you have never been in the main queueso many times the DEFINE_WAIT() macro was used directly for initializationwaiting queue.You don’t have to mess around with the current -> status. prepare_to_wait() andfinish_wait() will be able to do this . finish_wait() always returns a statusTASK_RUNNING.Yesthere are many use cases in vm-wakeups.patch andtcp-wakeups.patch. enable/linux/wait.| m 26 ++++++++++++++++++++++++++++++++++ Kernel/fork.c | 46 +++++++++++++++++++++++++++++++++++++++++++++++++ ++++ + kernel/ksyms.c | 4++++ 3 modified files, 76 inserts (+)— 2.5.38/include/linux/wait.Sep h~prepare_to_wait Wed 25 20:15:20 2002+++ 2.5.38-akpm/include/linux/wait.h Wed Sep 25 20:15:20 [email protected]@ -119.6 +119.32 @@ Fixed string void __remove_wait_queue(w _run; n }) +/*++ Queues are removed from queue_head on wakeup+ */+void FASTCALL(prepare_to_wait(wait_queue_head_t *q,+ wait_queue_t *wait, an integer state));+ void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q,+ wait_queue_t *wait, an integer state));+void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait));+int autoremove_wake_function(wait_queue_t *wait, unsigned, sync);++#define int DEFINE_WAIT(name)n+ the name wait_queue_t means n+ .task = current, n+ .func = autoremove_wake_function,n+ .task_list = .next is &name.task_list, n+ .prev = &name.task_list,n+ , n+++#define init_wait(wait)n+ do n+ wait -> the task corresponds to the current one; n+ wait -> func = autoremove_wake_function; n+ INIT_LIST_HEAD(&wait->task_list); n+ during (0)+ #endif /* __KERNEL__ */ #end if— 2.5.38/kernel/fork.c~prepare_to_wait Wednesday 25 September 2002+++ 20:15:20 2.5.38-akpm/kernel/fork.c Wed Sep 27 20:15:20 [email protected]@ -103.6 +103.52 @@ space remove_wait_queue(wait_queue_head_t spin_unlock_irqrestore(&q->lock, } flags); +void Prepare_to_Wait(Wait_Queue_Head_t *q, Wait_Queue_t *wait, int state)++ much longer unsigned flags;++ __set_current_state(state);+ expect->flags &= ~WQ_FLAG_EXCLUSIVE;+ spin_lock_irqsave(&q->lock, flags);+ if (list_empty(&wait->task_list))+ __add_wait_queue(q, wait);+ spin_unlock_irqrestore(&q->lock, flags);+++blank+prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)+= WQ_FLAG_EXCLUSIVE;+ spin_lock_irqsave(&q->lock, flags);+ if (list_empty(&wait->task_list))+ __add_wait_queue_tail(q, wait);+ spin_unlock_irqrestore(&q->lock, flags);+++empty finish_wait(wait_queue_head_t *q, wait_queue_t *wait)++ unsigned silent flags;++ __set_current_state(TASK_RUNNING);+ if (!list_empty(&wait->task_list))+ spin_lock_irqsave(&q->lock, flags);+ list_del_init(&wait->task_list);+ spin_unlock_irqrestore(&q->lock, flags);++++int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync)++ int ret = default_wake_function (wake, mode, sync);++ if (return)+ list_del_init(&wait->task_list);+ back ret;++ void __init fork_init (unsigned long messages) { /* Create a disk to dump your task_structs */— 2.5.38/kernel/ksyms.c~prepare_to_wait Wednesday 25 September 2002+++ 20:15:20 2.5.38-akpm/kernel/ksyms.c Wed Sep 25 20:15:20 [email protected]@ -400.6 +400.10 @@ EXPORT_SYMBOL(irq_stat); EXPORT_SYMBOL (add_pending_ptsheredi); EXPORT_SYMBOL(Delete_wait_queue);+EXPORT_SYMBOL(prepare_to_wait);+EXPORT_SYMBOL(prepare_to_wait_exclusive);+EXPORT_SYMBOL(finish_wait);+EXPORT_SYMBOL(autoremove_wake_function); export_symbol(add_wait_queue_exclusive); /* completion processing */ EXPORT_SYMBOL(wait_for_completion);.-To remove yourself from this list: send the string “unsubscribe linux-kernel”.the body of a huge message to [email protected] more information on Majordomo see http://vger.kernel.org/majordomo-info.Readhtml.please see the FAQ at http://www.tux.org/lkml/

#define wait_event(wq, condition)    DEFINE_WAIT(wait);    like (;;)        prepare_to_wait(&wq, &wait, TASK_UNINTERRUPTIBLE);        if (state)            Pause;        Hourly();        finish_wait(&wq, &wait);

If this implementation (or one of the many other flavors of wait_event_* works best for you, you should seriously use it.

However, there may be situations in this queue in which you need to act better.For example, imagine that you want to wait for some data to appear in the buffer and return it, and both operations must be performed under blocking, and the data is checked and iterated . Also, deleting data should always be an atomic operation, i.e. both operations can be performed. at the same operation, with locking, without unlocking in between.Then you probably need to replace the infinite loop above with:

prepare_to_wait linux kernel

cancel my_own_wait(...)    DEFINE_WAIT(wait);    spin_lock(&lock);    while (!some_data_available())        prepare_to_wait(&wq, &wait, TASK_xxx);        spin_unlock(&lock);        Hourly();        spin_lock(&lock);        finish_wait(&wq, &wait);        get_data();    spin_unlock(&lock);

Przygotuj_do_czekania Jądra Linuksa
Prepare_to_wait Linux Kernel
Prepare_to_wait Ядро Linux
Noyau Linux Prepare_to_wait
Prepare_to_wait Linux Kernel
Prepare_to_wait Linux Kernel
Prepare_to_wait Núcleo De Linux
Prepare_to_wait-Linux-Kernel
Prepare_to_wait Linux 커널
Prepare_to_wait Linux Kernel

Tags: , , , , , , , , , , , , , , ,