All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@intel.com>
To: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
Cc: Bartosz Golaszewski <brgl@bgdev.pl>,
	linux-gpio@vger.kernel.org,
	Linus Walleij <linus.walleij@linaro.org>,
	linux-kernel@vger.kernel.org,
	Thorsten Leemhuis <regressions@leemhuis.info>
Subject: Re: INFO: REPRODUCED: memory leak in gpio device in 6.2-rc6
Date: Tue, 21 Feb 2023 17:39:23 +0200	[thread overview]
Message-ID: <Y/Tlq9aY3btfoVUN@smile.fi.intel.com> (raw)
In-Reply-To: <d7762f6f-5b58-cf71-3400-557799de43c0@alu.unizg.hr>

On Tue, Feb 21, 2023 at 02:52:38PM +0100, Mirsad Goran Todorovac wrote:
> On 20. 02. 2023. 14:43, Andy Shevchenko wrote:
> > On Mon, Feb 20, 2023 at 02:10:00PM +0100, Mirsad Todorovac wrote:
> > > On 2/16/23 15:16, Bartosz Golaszewski wrote:

...

> > > As Mr. McKenney once said, a bunch of monkeys with keyboard could
> > > have done it in a considerable number of trials and errors ;-)
> > > 
> > > But here I have something that could potentially leak as well. I could not devise a
> > > reproducer due to the leak being lightly triggered only in extreme memory contention.
> > > 
> > > See it for yourself:
> > > 
> > > drivers/gpio/gpio-sim.c:
> > >  301 static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)
> > >  302 {
> > >  303         struct device_attribute *val_dev_attr, *pull_dev_attr;
> > >  304         struct gpio_sim_attribute *val_attr, *pull_attr;
> > >  305         unsigned int num_lines = chip->gc.ngpio;
> > >  306         struct device *dev = chip->gc.parent;
> > >  307         struct attribute_group *attr_group;
> > >  308         struct attribute **attrs;
> > >  309         int i, ret;
> > >  310
> > >  311         chip->attr_groups = devm_kcalloc(dev, sizeof(*chip->attr_groups),
> > >  312                                          num_lines + 1, GFP_KERNEL);
> > >  313         if (!chip->attr_groups)
> > >  314                 return -ENOMEM;
> > >  315
> > >  316         for (i = 0; i < num_lines; i++) {
> > >  317                 attr_group = devm_kzalloc(dev, sizeof(*attr_group), GFP_KERNEL);
> > >  318                 attrs = devm_kcalloc(dev, GPIO_SIM_NUM_ATTRS, sizeof(*attrs),
> > >  319                                      GFP_KERNEL);
> > >  320                 val_attr = devm_kzalloc(dev, sizeof(*val_attr), GFP_KERNEL);
> > >  321                 pull_attr = devm_kzalloc(dev, sizeof(*pull_attr), GFP_KERNEL);
> > >  322                 if (!attr_group || !attrs || !val_attr || !pull_attr)
> > >  323                         return -ENOMEM;
> > >  324
> > >  325                 attr_group->name = devm_kasprintf(dev, GFP_KERNEL,
> > >  326                                                   "sim_gpio%u", i);
> > >  327                 if (!attr_group->name)
> > >  328                         return -ENOMEM;
> > > 
> > > Apparently, if the memory allocation only partially succeeds, in the theoretical case
> > > that the system is close to its kernel memory exhaustion, `return -ENOMEM` would not
> > > free the partially succeeded allocs, would it?
> > > 
> > > To explain it better, I tried a version that is not yet full doing "all or nothing"
> > > memory allocation for the gpio-sim driver, because I am not that familiar with the
> > > driver internals.
> > 
> > devm_*() mean that the resource allocation is made in a managed manner, so when
> > it's done, it will be freed automatically.
> 
> Didn't see that one coming ... :-/ "buzzing though the bush ..."
> 
> > The question is: is the lifetime of the attr_groups should be lesser or the
> > same as chip->gc.parent? Maybe it's incorrect to call devm_*() in the first place?
> 
> Bona fide said, I hope that automatic deallocation does things in the right order.
> I've realised that devm_kzalloc() calls devm_kmalloc() that registers allocations on
> a per driver list. But I am not sure how chip->gc was allocated?
> 
> Here is said it is allocated in drivers/gpio/gpio-sim.c:386 in gpio_sim_add_bank(),
> as a part of
> 
> 	struct gpio_sim_chip *chip;
> 	struct gpio_chip *gc;
> 
> 	gc = &chip->gc;
> 
> and gc->parent is set to
> 
> 	gc->parent = dev;
> 
> in line 420, which appears called before gpio_sim_setup_sysfs() and the lines above.
> 
> If I understood well, automatic deallocation on unloading the driver goes
> in the reverse order, so lifetime of chip appears to be longer than attr_groups,
> but I am really not that good at this ...

So, the device is instantiated by platform_device_register_full().

It should gone with the platform_device_unregister().

In case of CONFIG_DEBUG_KOBJECT_RELEASE=y the ->release() can be called
asynchronously.

So, there are following questions:
- is the put_device() is actually called?
- is the above mentioned option is set to Y?
- if it's in Y, does kmemleak take it into account?
- if no, do you get anything new in `dmesg` when enable it?

> > Or maybe the chip->gc.parent should be changed to something else (actual GPIO
> > device, but then it's unclear how to provide the attributes in non-racy way
> Really, dunno. I have to repeat that my learning curve cannot adapt so quickly.
> 
> I merely gave the report of KMEMLEAK, otherwise I am not a Linux kernel
> device expert nor would be appropriate to try the craft not earned ;-)

-- 
With Best Regards,
Andy Shevchenko



  parent reply	other threads:[~2023-02-21 15:41 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-31  9:36 INFO: memory leak in gpio device in 6.2-rc6 Mirsad Goran Todorovac
2023-02-08 19:55 ` INFO: REPRODUCED: " Mirsad Goran Todorovac
2023-02-12 14:19   ` Andy Shevchenko
2023-02-14 18:19     ` Mirsad Goran Todorovac
2023-02-15 10:53       ` Andy Shevchenko
2023-02-15 14:45         ` Mirsad Goran Todorovac
2023-02-16 14:16           ` Bartosz Golaszewski
2023-02-20 13:10             ` Mirsad Todorovac
2023-02-20 13:43               ` Andy Shevchenko
2023-02-21 13:52                 ` Mirsad Goran Todorovac
2023-02-21 14:20                   ` Mirsad Goran Todorovac
2023-02-21 14:32                   ` Mirsad Goran Todorovac
2023-02-21 15:39                   ` Andy Shevchenko [this message]
2023-02-22 10:53                     ` Bartosz Golaszewski
2023-02-22 21:27                       ` Mirsad Goran Todorovac
2023-02-24 15:12                     ` Mirsad Todorovac
2023-02-24 17:40                       ` Andy Shevchenko
2023-02-27 18:38                         ` Mirsad Todorovac
2023-02-27 23:13                           ` Andy Shevchenko
2023-03-08 13:11                             ` Mirsad Todorovac
2023-03-08 15:20                               ` Andy Shevchenko
2023-03-08 23:17                                 ` Mirsad Goran Todorovac
2023-02-14 20:54     ` INFO: BISECTED: " Mirsad Goran Todorovac

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=Y/Tlq9aY3btfoVUN@smile.fi.intel.com \
    --to=andriy.shevchenko@intel.com \
    --cc=brgl@bgdev.pl \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mirsad.todorovac@alu.unizg.hr \
    --cc=regressions@leemhuis.info \
    /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.