Hello, On Tue, Apr 18, 2017 at 10:12:16AM +0100, Andre Przywara wrote: > Yeah, so I stack-dumped on the zero allocations and indeed they are > called from cleanup functions: > drivers/pinctrl/pinmux.c:pinmux_generic_free_functions(): > devm_kzalloc(sizeof(*indices) * pctldev->num_functions, ...) > (and another one I don't know from the top of the my head, logs at home) > > So my hunch was that once EPROBE_DEFER triggers the devres cleanup, it > uses some reverse list traversal to release all allocated resources > (backwards!), so missing those which get (appended) during the process. > But I don't think that would not work with the locking. > So I have to dig deeper tonight in my logs.
If this is a valid use case, we can change devm to repeat till empty but it's a weird thing to do to allocate from a release function. So, something like this. Only compile tested. Thanks. diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 71d5770..d2a9f34 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -509,13 +509,21 @@ static int release_nodes(struct device *dev, struct list_head *first, int devres_release_all(struct device *dev) { unsigned long flags; + int cnt = 0, ret; /* Looks like an uninitialized device structure */ if (WARN_ON(dev->devres_head.next == NULL)) return -ENODEV; - spin_lock_irqsave(&dev->devres_lock, flags); - return release_nodes(dev, dev->devres_head.next, &dev->devres_head, - flags); + + /* Release callbacks may create new nodes, repeat till empty */ + do { + spin_lock_irqsave(&dev->devres_lock, flags); + ret = release_nodes(dev, dev->devres_head.next, + &dev->devres_head, flags); + cnt += ret; + } while (ret); + + return cnt; } /**