On 06/17, Alpár Török  wrote:
>
> The producer is a utrace monitored task. At any time there is an
> arbitrary number of producers. On sys_entry and sys_exit the producers
> do  :
>
> slot = book_message_in_buffer(buf);
> if (slot < 0) {
>   /* no slot can be alocated, producer must sleep  */
>   enque_producer_on_wait_list(list, producer);
>   return UTRACE_STOP;
> }

I think Roland is right. Let's forget about utrace for the moment,
this code looks like

        if (!CONDITION) {
                set_task_state(TASK_XXX);
                schedule();
        }

and it can obviously race with

        CONDITION = true;
        wake_up_xxx();



I am wondering if there is another way to handle such a race...
Suppose we

        - add UTRACE_STOP_XXX

        - modify utrace_control(UTRACE_STOP_XXX) to do
          mark_engine_wants_stop() and nothing more.

        - finish_callback_report(UTRACE_STOP_XXX) does

                spin_lock(&utrace->lock);
                if (engine_wants_stop(engine))
                        action = UTRACE_STOP;
                else
                        action = UTRACE_REUME;
                spin_unlock(&utrace->lock);

Then, probably producer could do

        utrace_control(current, UTRACE_STOP_XXX);

        slot = book_message_in_buffer(buf);
        if (slot < 0)
                return UTRACE_STOP_XXX;

        ...
        return UTRACE_RESUME;

Even better, UTRACE_STOP_XXX can live outside of UTRACE_RESUME_MASK.

Unlikely this makes sense, just a random thought.

Oleg.

Reply via email to