linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Begunkov <asml.silence@gmail.com>
To: Kanchan Joshi <joshi.k@samsung.com>
Cc: axboe@kernel.dk, linux-block@vger.kernel.org
Subject: Re: [PATCH] block: fix bio-allocation from per-cpu cache
Date: Thu, 27 Oct 2022 12:46:03 +0100	[thread overview]
Message-ID: <7f2a2ecd-7fe1-d30a-a29c-8025b33156ce@gmail.com> (raw)
In-Reply-To: <20221027104910.GA22546@test-zns>

On 10/27/22 11:49, Kanchan Joshi wrote:
> On Thu, Oct 27, 2022 at 11:38:50AM +0100, Pavel Begunkov wrote:
>> On 10/27/22 11:04, Kanchan Joshi wrote:
>>> If cache does not have any entry, make sure to detect that and return
>>> failure. Otherwise this leads to null pointer dereference.
>>
>> Damn, it was done right in v2
>>
>> https://lore.kernel.org/all/9fd04486d972c1f3ef273fa26b4b6bf51a5e4270.1666122465.git.asml.silence@gmail.com/
>>
>> Perhaps I based v3 on a wrong version. Thanks
>>
>>
>>> Fixes: 13a184e26965 ("block/bio: add pcpu caching for non-polling bio_put")
>>> Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
>>> ---
>>> Can be reproduced by:
>>> fio -direct=1 -iodepth=1 -rw=randread -ioengine=io_uring -bs=4k -numjobs=1 -size=4k -filename=/dev/nvme0n1 -hipri=1 -name=block
>>>
>>> BUG: KASAN: null-ptr-deref in bio_alloc_bioset.cold+0x2a/0x16a
>>> Read of size 8 at addr 0000000000000000 by task fio/1835
>>>
>>> CPU: 5 PID: 1835 Comm: fio Not tainted 6.1.0-rc2+ #226
>>> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g
>>> Call Trace:
>>>  <TASK>
>>>  dump_stack_lvl+0x34/0x48
>>>  print_report+0x490/0x4a1
>>>  ? __virt_addr_valid+0x28/0x140
>>>  ? bio_alloc_bioset.cold+0x2a/0x16a
>>>  kasan_report+0xb3/0x130
>>>  ? bio_alloc_bioset.cold+0x2a/0x16a
>>>  bio_alloc_bioset.cold+0x2a/0x16a
>>>  ? bvec_alloc+0xf0/0xf0
>>>  ? iov_iter_is_aligned+0x130/0x2c0
>>>  blkdev_direct_IO.part.0+0x16a/0x8d0
>>>
>>>  block/bio.c | 11 ++++++-----
>>>  1 file changed, 6 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/block/bio.c b/block/bio.c
>>> index 8f624ffaf3d0..66f088bb3736 100644
>>> --- a/block/bio.c
>>> +++ b/block/bio.c
>>> @@ -439,13 +439,14 @@ static struct bio *bio_alloc_percpu_cache(struct block_device *bdev,
>>>      cache = per_cpu_ptr(bs->cache, get_cpu());
>>>      if (!cache->free_list &&
>>> -        READ_ONCE(cache->nr_irq) >= ALLOC_CACHE_THRESHOLD) {
>>> +        READ_ONCE(cache->nr_irq) >= ALLOC_CACHE_THRESHOLD)
>>>          bio_alloc_irq_cache_splice(cache);
>>> -        if (!cache->free_list) {
>>> -            put_cpu();
>>> -            return NULL;
>>> -        }
>>> +
>>> +    if (!cache->free_list) {
>>
>> Let's nest it under the other "if (!cache->free_list)"
> 
> Not sure if I got you. It was under that if condition earlier, and that
> part causes trouble.

Under the free_list check specifically, the threshold would also
go in a separate if,

> What you wrote in v2 is another way, but there also we have two checks
> on cache->free_list.

Your version:

if (cache_empty())
	if (check_threshold())
		try_replenish_cache(); // splice
if (cache_empty()) // still empty
	return NULL;


vs v2:

if (cache_empty()) {
	if (check_threshold())
		try_replenish_cache(); // splice
	if (cache_empty()) // still empty
		return NULL;
}

But on the other hand compilers should be smart enough to
optimise repeated checks when the cache already have requests,
so there should be no real difference.

-- 
Pavel Begunkov

  reply	other threads:[~2022-10-27 11:47 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20221027101534epcas5p3b8335c05a1003531f1a4488dc27f27ee@epcas5p3.samsung.com>
2022-10-27 10:04 ` [PATCH] block: fix bio-allocation from per-cpu cache Kanchan Joshi
2022-10-27 10:38   ` Pavel Begunkov
2022-10-27 10:49     ` Kanchan Joshi
2022-10-27 11:46       ` Pavel Begunkov [this message]
2022-10-27 20:44   ` Jens Axboe
2022-10-27 20:45     ` Pavel Begunkov
2022-10-27 20:50       ` Pavel Begunkov
2022-10-27 20:52       ` Jens Axboe
2022-10-27 21:35         ` Pavel Begunkov

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=7f2a2ecd-7fe1-d30a-a29c-8025b33156ce@gmail.com \
    --to=asml.silence@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=joshi.k@samsung.com \
    --cc=linux-block@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).