Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers/base/power: add dpm_sysfs_change_owner()

Add a helper to change the owner of a device's power entries. This
needs to happen when the ownership of a device is changed, e.g. when
moving network devices between network namespaces.
This function will be used to correctly account for ownership changes,
e.g. when moving network devices between network namespaces.

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Christian Brauner and committed by
David S. Miller
3b52fc5d b8f33e5d

+61 -1
+4
drivers/base/core.c
··· 3552 3552 if (error) 3553 3553 goto out; 3554 3554 3555 + error = dpm_sysfs_change_owner(dev, kuid, kgid); 3556 + if (error) 3557 + goto out; 3558 + 3555 3559 #ifdef CONFIG_BLOCK 3556 3560 if (sysfs_deprecated && dev->class == &block_class) 3557 3561 goto out;
+3
drivers/base/power/power.h
··· 74 74 extern void pm_qos_sysfs_remove_flags(struct device *dev); 75 75 extern int pm_qos_sysfs_add_latency_tolerance(struct device *dev); 76 76 extern void pm_qos_sysfs_remove_latency_tolerance(struct device *dev); 77 + extern int dpm_sysfs_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid); 77 78 78 79 #else /* CONFIG_PM */ 79 80 ··· 89 88 90 89 static inline int dpm_sysfs_add(struct device *dev) { return 0; } 91 90 static inline void dpm_sysfs_remove(struct device *dev) {} 91 + static inline int dpm_sysfs_change_owner(struct device *dev, kuid_t kuid, 92 + kgid_t kgid) { return 0; } 92 93 93 94 #endif 94 95
+54 -1
drivers/base/power/sysfs.c
··· 480 480 return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); 481 481 } 482 482 483 + static inline int dpm_sysfs_wakeup_change_owner(struct device *dev, kuid_t kuid, 484 + kgid_t kgid) 485 + { 486 + if (dev->power.wakeup && dev->power.wakeup->dev) 487 + return device_change_owner(dev->power.wakeup->dev, kuid, kgid); 488 + return 0; 489 + } 490 + 483 491 static DEVICE_ATTR_RO(wakeup_last_time_ms); 484 492 485 493 #ifdef CONFIG_PM_AUTOSLEEP ··· 509 501 510 502 static DEVICE_ATTR_RO(wakeup_prevent_sleep_time_ms); 511 503 #endif /* CONFIG_PM_AUTOSLEEP */ 512 - #endif /* CONFIG_PM_SLEEP */ 504 + #else /* CONFIG_PM_SLEEP */ 505 + static inline int dpm_sysfs_wakeup_change_owner(struct device *dev, kuid_t kuid, 506 + kgid_t kgid) 507 + { 508 + return 0; 509 + } 510 + #endif 513 511 514 512 #ifdef CONFIG_PM_ADVANCED_DEBUG 515 513 static ssize_t runtime_usage_show(struct device *dev, ··· 696 682 err_out: 697 683 sysfs_remove_group(&dev->kobj, &pm_attr_group); 698 684 return rc; 685 + } 686 + 687 + int dpm_sysfs_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) 688 + { 689 + int rc; 690 + 691 + if (device_pm_not_required(dev)) 692 + return 0; 693 + 694 + rc = sysfs_group_change_owner(&dev->kobj, &pm_attr_group, kuid, kgid); 695 + if (rc) 696 + return rc; 697 + 698 + if (pm_runtime_callbacks_present(dev)) { 699 + rc = sysfs_group_change_owner( 700 + &dev->kobj, &pm_runtime_attr_group, kuid, kgid); 701 + if (rc) 702 + return rc; 703 + } 704 + 705 + if (device_can_wakeup(dev)) { 706 + rc = sysfs_group_change_owner(&dev->kobj, &pm_wakeup_attr_group, 707 + kuid, kgid); 708 + if (rc) 709 + return rc; 710 + 711 + rc = dpm_sysfs_wakeup_change_owner(dev, kuid, kgid); 712 + if (rc) 713 + return rc; 714 + } 715 + 716 + if (dev->power.set_latency_tolerance) { 717 + rc = sysfs_group_change_owner( 718 + &dev->kobj, &pm_qos_latency_tolerance_attr_group, kuid, 719 + kgid); 720 + if (rc) 721 + return rc; 722 + } 723 + return 0; 699 724 } 700 725 701 726 int wakeup_sysfs_add(struct device *dev)