linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Douglas Gilbert <dgilbert@interlog.com>
To: Bart Van Assche <bvanassche@acm.org>,
	SCSI development list <linux-scsi@vger.kernel.org>,
	"linux-block@vger.kernel.org" <linux-block@vger.kernel.org>
Cc: "Martin K. Petersen" <martin.petersen@ORACLE.COM>,
	USB list <linux-usb@vger.kernel.org>
Subject: Re: lib/scatterlist.c : sgl_alloc_order promises more than it delivers
Date: Fri, 25 Sep 2020 00:55:07 -0400	[thread overview]
Message-ID: <d487005a-ef6c-549f-7006-c7056cf3f36d@interlog.com> (raw)
In-Reply-To: <d9513f73-fa18-4b71-fabf-be0b9e1614fd@acm.org>

On 2020-09-24 10:34 p.m., Bart Van Assche wrote:
> On 2020-09-24 18:46, Douglas Gilbert wrote:
>>          /* Check for integer overflow */
>>          if (length > (nent << (PAGE_SHIFT + order)))
>>                  return NULL;
>>
>> Well _integers_ don't wrap, but that pedantic point aside, 'nent' is an
>> unsigned int which means the rhs expression cannot represent 2^32 or
>> higher. So if length >= 2^32 the function fails (i.e. returns NULL).
>>
>> On 8 GiB and 16 GiB machines I can easily build 6 or 12 GiB sgl_s (with
>> scsi_debug) but only if no single allocation is >= 4 GiB due to the
>> above check.
>>
>> So is the above check intended to do that or is it a bug?
> 
> The above check verifies that nent << (PAGE_SHIFT + order) ==
> (uint64_t)nent << (PAGE_SHIFT + order). So I think it does what the
> comment says it does.

I modified sgl_alloc_order() like this:

         /* Check for integer overflow */
         if (length > (nent << (PAGE_SHIFT + order)))
{
pr_info("%s: (length > (nent << (PAGE_SHIFT + order))\n", __func__);
                 return NULL;
}
	...

Then I tried starting scsi_debug with dev_size_mb=4096

This is what I saw in the log:

scsi_debug:scsi_debug_init: fixing max submit queue depth to host max queue 
depth, 32
sgl_alloc_order: (length > (nent << (PAGE_SHIFT + order))
message repeated 2 times: [sgl_alloc_order: (length > (nent << (PAGE_SHIFT + 
order))]
scsi_debug:sdeb_store_sgat: sdeb_store_sgat: unable to obtain 4096 MiB, last 
element size: 256 kiB
scsi_debug:sdebug_add_store: sgat: user data oom
scsi_debug:sdebug_add_store: sdebug_add_store: failed, errno=12


My code steps down from 1024 KiB elements on failure to 512 KiB and if that
fails it tries 256 KiB. Then it gives up. The log output is consistent with
my analysis. So your stated equality is an inequality when length >= 4 GiB.
There is no promotion of unsigned int nent to uint64_t .

You can write your own test harness if you don't believe me. The test machine
doesn't need much ram. Without the call to sgl_free() corrected, if it really
did try to get that much ram and failed toward the end, then (partially)
freed up what it had obtained, then you would see a huge memory leak ...


Now your intention seems to be that a 4 GiB sgl should be valid. Correct?
Can that check just be dropped?

Doug Gilbert


  reply	other threads:[~2020-09-25  4:55 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-25  1:46 lib/scatterlist.c : sgl_alloc_order promises more than it delivers Douglas Gilbert
2020-09-25  2:34 ` Bart Van Assche
2020-09-25  4:55   ` Douglas Gilbert [this message]
2020-09-26  4:32     ` Bart Van Assche
2020-10-11 21:21       ` Douglas Gilbert
2020-10-11 22:24         ` Bart Van Assche

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=d487005a-ef6c-549f-7006-c7056cf3f36d@interlog.com \
    --to=dgilbert@interlog.com \
    --cc=bvanassche@acm.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=martin.petersen@ORACLE.COM \
    /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).