On Mon, 22 Oct 2012, Ming Lei wrote: > +void pm_runtime_set_memalloc_noio(struct device *dev, bool enable) > +{ > + dev->power.memalloc_noio_resume = enable; > + > + if (!dev->parent) > + return; > + > + if (enable) { > + pm_runtime_set_memalloc_noio(dev->parent, 1); > + } else { > + /* only clear the flag for one device if all > + * children of the device don't set the flag. > + */ > + if (device_for_each_child(dev->parent, NULL, > + dev_memalloc_noio)) > + return; > + > + pm_runtime_set_memalloc_noio(dev->parent, 0); > + } > +} > +EXPORT_SYMBOL_GPL(pm_runtime_set_memalloc_noio); Tail recursion should be implemented as a loop, not as an explicit recursion. That is, the function should be: void pm_runtime_set_memalloc_noio(struct device *dev, bool enable) { do { dev->power.memalloc_noio_resume = enable; if (!enable) { /* * Don't clear the parent's flag if any of the * parent's children have their flag set. */ if (device_for_each_child(dev->parent, NULL, dev_memalloc_noio)) return; } dev = dev->parent; } while (dev); } except that you need to add locking, for two reasons: There's a race. What happens if another child sets the flag between the time device_for_each_child() runs and the next loop iteration? Even without a race, access to bitfields is not SMP-safe without locking. Alan Stern -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>