From: Jens Axboe <axboe@kernel.dk>
To: "Lukáš Czerner" <lczerner@redhat.com>
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
jmoyer@redhat.com, akpm@linux-foundation.org
Subject: Re: [PATCH v3] loop: Limit the number of requests in the bio list
Date: Wed, 14 Nov 2012 08:21:41 -0700 [thread overview]
Message-ID: <50A3B705.7050008@kernel.dk> (raw)
In-Reply-To: <alpine.LFD.2.00.1211140951380.3577@localhost>
On 2012-11-14 02:02, Lukáš Czerner wrote:
> On Tue, 13 Nov 2012, Jens Axboe wrote:
>
>> Date: Tue, 13 Nov 2012 09:42:58 -0700
>> From: Jens Axboe <axboe@kernel.dk>
>> To: Lukas Czerner <lczerner@redhat.com>
>> Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
>> jmoyer@redhat.com, akpm@linux-foundation.org
>> Subject: Re: [PATCH v3] loop: Limit the number of requests in the bio list
>>
>>> @@ -489,6 +491,12 @@ static void loop_make_request(struct request_queue *q, struct bio *old_bio)
>>> goto out;
>>> if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
>>> goto out;
>>> + if (lo->lo_bio_count >= q->nr_congestion_on) {
>>> + spin_unlock_irq(&lo->lo_lock);
>>> + wait_event(lo->lo_req_wait, lo->lo_bio_count <
>>> + q->nr_congestion_off);
>>> + spin_lock_irq(&lo->lo_lock);
>>> + }
>>
>> This makes me nervous. You are reading lo_bio_count outside the lock. If
>> you race with the prepare_to_wait() and condition check in
>> __wait_event(), then you will sleep forever.
>
> Hi Jens,
>
> I am sorry for being dense, but I do not see how this would be
> possible. The only place we increase the lo_bio_count is after that
> piece of code (possibly after the wait). Moreover every time we're
> decreasing the lo_bio_count and it is smaller than nr_congestion_off
> we will wake_up().
>
> That's how wait_event/wake_up is supposed to be used, right ?
It is, yes. But you are checking the condition without the lock, so you
could be operating on a stale value. The point is, you have to safely
check the condition _after prepare_to_wait() to be completely safe. And
you do not. Either lo_bio_count needs to be atomic, or you need to use a
variant of wait_event() that holds the appropriate lock before
prepare_to_wait() and condition check, then dropping it for the sleep.
See wait_even_lock_irq() in drivers/md/md.h.
--
Jens Axboe
next prev parent reply other threads:[~2012-11-14 15:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-13 16:27 [PATCH v3] loop: Limit the number of requests in the bio list Lukas Czerner
2012-11-13 16:35 ` Jeff Moyer
2012-11-13 16:42 ` Jens Axboe
2012-11-14 9:02 ` Lukáš Czerner
2012-11-14 15:21 ` Jens Axboe [this message]
2012-11-15 8:20 ` Lukáš Czerner
2012-11-15 14:05 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50A3B705.7050008@kernel.dk \
--to=axboe@kernel.dk \
--cc=akpm@linux-foundation.org \
--cc=jmoyer@redhat.com \
--cc=lczerner@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.