All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Song Bao Hua (Barry Song)" <song.bao.hua@hisilicon.com>
To: Greg KH <gregkh@linuxfoundation.org>,
	"tiantao (H)" <tiantao6@hisilicon.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>,
	"tiantao (H)" <tiantao6@hisilicon.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Jonathan Cameron <jonathan.cameron@huawei.com>
Subject: RE: [PATCH 1/2] topology: use bin_attribute to avoid buff overflow
Date: Wed, 2 Jun 2021 09:20:45 +0000	[thread overview]
Message-ID: <547f8273faa146699dd50173b33f03e2@hisilicon.com> (raw)
In-Reply-To: <YLdKDXYKm7jqorGa@kroah.com>



> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Wednesday, June 2, 2021 9:06 PM
> To: tiantao (H) <tiantao6@hisilicon.com>
> Cc: Andy Shevchenko <andy.shevchenko@gmail.com>; tiantao (H)
> <tiantao6@hisilicon.com>; Linux Kernel Mailing List
> <linux-kernel@vger.kernel.org>; Andrew Morton <akpm@linux-foundation.org>;
> Song Bao Hua (Barry Song) <song.bao.hua@hisilicon.com>; Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>; Rafael J. Wysocki <rafael@kernel.org>;
> Jonathan Cameron <jonathan.cameron@huawei.com>
> Subject: Re: [PATCH 1/2] topology: use bin_attribute to avoid buff overflow
> 
> On Wed, Jun 02, 2021 at 05:00:16PM +0800, tiantao (H) wrote:
> >
> > 在 2021/6/2 16:48, Andy Shevchenko 写道:
> > > On Wed, Jun 2, 2021 at 9:45 AM tiantao (H) <tiantao6@huawei.com> wrote:
> > > > 在 2021/6/2 14:18, Greg KH 写道:
> > > > > On Wed, Jun 02, 2021 at 02:14:49PM +0800, tiantao (H) wrote:
> > > > > > 在 2021/6/1 12:58, Greg KH 写道:
> > > > > > > On Tue, Jun 01, 2021 at 10:56:49AM +0800, Tian Tao wrote:
> > > ...
> > >
> > > > > > > >     /**
> > > > > > > > + * bitmap_print_to_buf - convert bitmap to list or hex format
> ASCII string
> > > > > > > > + * @list: indicates whether the bitmap must be list
> > > > > > > > + * @buf: page aligned buffer into which string is placed
> > > > > > > > + * @maskp: pointer to bitmap to convert
> > > > > > > > + * @nmaskbits: size of bitmap, in bits
> > > > > > > > + * @off: offset in buf
> > > > > > > > + * @count: count that already output
> > > > > > > > + *
> > > > > > > > + * the role of bitmap_print_to_buf and bitmap_print_to_pagebuf
> is
> > > > > > > > + * the same, the difference is that the second parameter of
> > > > > > > > + * bitmap_print_to_buf can be more than one pagesize.
> > > > > > > > + */
> > > > > > > > +int bitmap_print_to_buf(bool list, char *buf, const unsigned
> long *maskp,
> > > > > > > > +                  int nmaskbits, loff_t off, size_t count)
> > > > > > > > +{
> > > > > > > > +  int len, size;
> > > > > > > > +  void *data;
> > > > > > > > +  char *fmt = list ? "%*pbl\n" : "%*pb\n";
> > > > > > > > +
> > > > > > > > +  len = snprintf(NULL, 0, fmt, nmaskbits, maskp);
> > > > > > > > +
> > > > > > > > +  data = kvmalloc(len+1, GFP_KERNEL);
> > > > > > > > +  if (!data)
> > > > > > > > +          return -ENOMEM;
> > > > > > > > +
> > > > > > > > +  size = scnprintf(data, len+1, fmt, nmaskbits, maskp);
> > > > > > > > +  size = memory_read_from_buffer(buf, count, &off, data, size);
> > > > > > > > +  kvfree(data);
> > > > > > > > +
> > > > > > > > +  return size;
> > > > > > > Why is this so different from bitmap_print_to_pagebuf()?  Can't you
> just
> > > > > > > use this function as the "real" function and then change
> > > > > > > bitmap_print_to_pagebuf() to call it with a size of PAGE_SIZE?
> > > > > > Do you mean do following change, is that correct? :-)
> > > > > Maybe, it is whitespace corrupted, and it still feels like this function
> > > > > is much bigger than it needs to be given the function it is replacing
> is
> > > > > only a simple sprintf() call.
> > > > >
> > > > > > +int bitmap_print_to_buf(bool list, char *buf, const unsigned long
> *maskp,
> > > > > > +                       int nmaskbits, loff_t off, size_t count)
> > > > > > +{
> > > > > > +       int len, size;
> > > > > > +       void *data;
> > > > > > +       const char *fmt = list ? "%*pbl\n" : "%*pb\n";
> > > > > > +
> > > > > > +       if (off == LLONG_MAX && count == PAGE_SIZE - offset_in_page(buf))
> > > > > > +               return scnprintf(buf, count, fmt, nmaskbits, maskp);
> > > > > > +
> > > > > > +       len = snprintf(NULL, 0, fmt, nmaskbits, maskp);
> > > > > > +
> > > > > > +       data = kvmalloc(len+1, GFP_KERNEL);
> > > > > Why do you need to allocate more memory?  And why kvmalloc()?
> > > > Because the memory here will exceed a pagesize and we don't know the
> > > > exact size, we have to call
> > > >
> > > > snprintf first to get the actual size. kvmalloc() is used because when
> > > > physical memory is tight, kmalloc
> > > >
> > > > may fail, but vmalloc will succeed. It is not so bad that the memory is
> > > > not requested here.
> > > To me it sounds like the function is overengineered / lacks thought
> > > through / optimization.
> > > Can you provide a few examples that require the above algorithm?
> >
> > so you think we should use kmalloc instead of kvmalloc ?
> 
> What size bitmap would trigger a vmalloc() call to be forced here?
> 

According to kvmalloc_node(), only if size is larger than PAGE_SIZE,
kvmalloc will move to vmalloc if kmalloc fails to get memory. Otherwise,
it will return error.
void *kvmalloc_node(size_t size, gfp_t flags, int node)
{
	gfp_t kmalloc_flags = flags;
	void *ret;

	...

	ret = kmalloc_node(size, kmalloc_flags, node);

	/*
	 * It doesn't really make sense to fallback to vmalloc for sub page
	 * requests
	 */
	if (ret || size <= PAGE_SIZE)
		return ret;

	return __vmalloc_node(size, 1, flags, node,
			__builtin_return_address(0));
}

For bitmap, it is clear a large NR_CPUS can trigger vmalloc:
Code copy-paste from drivers/base/node.c:
	/* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
	BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1));

But for list, it would be much more tricky. As a list could be as simple
as:
0-2047
It could also be as complex as:
0,1,3,5,7,9,11,13,.....,2045,2047

It totally depends on how the bitmap is like.

That's why tiantao's code is detecting size before malloc.

> thanks,
> 
> greg k-h

Thanks
Barry


  reply	other threads:[~2021-06-02  9:20 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-01  2:56 [PATCH 0/2] use bin_attribute to avoid buff overflow Tian Tao
2021-06-01  2:56 ` [PATCH 1/2] topology: " Tian Tao
2021-06-01  4:58   ` Greg KH
2021-06-01  7:04     ` Song Bao Hua (Barry Song)
2021-06-01  7:13       ` Greg KH
2021-06-02  6:14     ` tiantao (H)
2021-06-02  6:18       ` Greg KH
2021-06-02  6:28         ` tiantao (H)
2021-06-02  8:48           ` Andy Shevchenko
2021-06-02  9:00             ` tiantao (H)
2021-06-02  9:06               ` Greg KH
2021-06-02  9:20                 ` Song Bao Hua (Barry Song) [this message]
2021-06-02  9:35                   ` Greg KH
2021-06-01  2:56 ` [PATCH 2/2] drivers/base/node.c: " Tian Tao
2021-06-01  5:01   ` Greg KH

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=547f8273faa146699dd50173b33f03e2@hisilicon.com \
    --to=song.bao.hua@hisilicon.com \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jonathan.cameron@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=tiantao6@hisilicon.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 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.