Skip to content

Commit e1a9e3d

Browse files
committed
Merge tag 'driver-core-5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core fixes from Greg KH: "Here are three small driver core / debugfs fixes for 5.13-rc4: - debugfs fix for incorrect "lockdown" mode for selinux accesses - two device link changes, one bugfix and one cleanup All of these have been in linux-next for over a week with no reported problems" * tag 'driver-core-5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: drivers: base: Reduce device link removal code duplication drivers: base: Fix device link removal debugfs: fix security_locked_down() call for SELinux
2 parents 494b99f + 0c87131 commit e1a9e3d

File tree

3 files changed

+44
-39
lines changed

3 files changed

+44
-39
lines changed

drivers/base/core.c

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,17 @@ int device_links_read_lock_held(void)
194194
{
195195
return srcu_read_lock_held(&device_links_srcu);
196196
}
197+
198+
static void device_link_synchronize_removal(void)
199+
{
200+
synchronize_srcu(&device_links_srcu);
201+
}
202+
203+
static void device_link_remove_from_lists(struct device_link *link)
204+
{
205+
list_del_rcu(&link->s_node);
206+
list_del_rcu(&link->c_node);
207+
}
197208
#else /* !CONFIG_SRCU */
198209
static DECLARE_RWSEM(device_links_lock);
199210

@@ -224,6 +235,16 @@ int device_links_read_lock_held(void)
224235
return lockdep_is_held(&device_links_lock);
225236
}
226237
#endif
238+
239+
static inline void device_link_synchronize_removal(void)
240+
{
241+
}
242+
243+
static void device_link_remove_from_lists(struct device_link *link)
244+
{
245+
list_del(&link->s_node);
246+
list_del(&link->c_node);
247+
}
227248
#endif /* !CONFIG_SRCU */
228249

229250
static bool device_is_ancestor(struct device *dev, struct device *target)
@@ -445,8 +466,13 @@ static struct attribute *devlink_attrs[] = {
445466
};
446467
ATTRIBUTE_GROUPS(devlink);
447468

448-
static void device_link_free(struct device_link *link)
469+
static void device_link_release_fn(struct work_struct *work)
449470
{
471+
struct device_link *link = container_of(work, struct device_link, rm_work);
472+
473+
/* Ensure that all references to the link object have been dropped. */
474+
device_link_synchronize_removal();
475+
450476
while (refcount_dec_not_one(&link->rpm_active))
451477
pm_runtime_put(link->supplier);
452478

@@ -455,24 +481,19 @@ static void device_link_free(struct device_link *link)
455481
kfree(link);
456482
}
457483

458-
#ifdef CONFIG_SRCU
459-
static void __device_link_free_srcu(struct rcu_head *rhead)
460-
{
461-
device_link_free(container_of(rhead, struct device_link, rcu_head));
462-
}
463-
464484
static void devlink_dev_release(struct device *dev)
465485
{
466486
struct device_link *link = to_devlink(dev);
467487

468-
call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu);
469-
}
470-
#else
471-
static void devlink_dev_release(struct device *dev)
472-
{
473-
device_link_free(to_devlink(dev));
488+
INIT_WORK(&link->rm_work, device_link_release_fn);
489+
/*
490+
* It may take a while to complete this work because of the SRCU
491+
* synchronization in device_link_release_fn() and if the consumer or
492+
* supplier devices get deleted when it runs, so put it into the "long"
493+
* workqueue.
494+
*/
495+
queue_work(system_long_wq, &link->rm_work);
474496
}
475-
#endif
476497

477498
static struct class devlink_class = {
478499
.name = "devlink",
@@ -846,7 +867,6 @@ struct device_link *device_link_add(struct device *consumer,
846867
}
847868
EXPORT_SYMBOL_GPL(device_link_add);
848869

849-
#ifdef CONFIG_SRCU
850870
static void __device_link_del(struct kref *kref)
851871
{
852872
struct device_link *link = container_of(kref, struct device_link, kref);
@@ -856,25 +876,9 @@ static void __device_link_del(struct kref *kref)
856876

857877
pm_runtime_drop_link(link);
858878

859-
list_del_rcu(&link->s_node);
860-
list_del_rcu(&link->c_node);
861-
device_unregister(&link->link_dev);
862-
}
863-
#else /* !CONFIG_SRCU */
864-
static void __device_link_del(struct kref *kref)
865-
{
866-
struct device_link *link = container_of(kref, struct device_link, kref);
867-
868-
dev_info(link->consumer, "Dropping the link to %s\n",
869-
dev_name(link->supplier));
870-
871-
pm_runtime_drop_link(link);
872-
873-
list_del(&link->s_node);
874-
list_del(&link->c_node);
879+
device_link_remove_from_lists(link);
875880
device_unregister(&link->link_dev);
876881
}
877-
#endif /* !CONFIG_SRCU */
878882

879883
static void device_link_put_kref(struct device_link *link)
880884
{

fs/debugfs/inode.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,13 @@ static unsigned int debugfs_allow __ro_after_init = DEFAULT_DEBUGFS_ALLOW_BITS;
4545
static int debugfs_setattr(struct user_namespace *mnt_userns,
4646
struct dentry *dentry, struct iattr *ia)
4747
{
48-
int ret = security_locked_down(LOCKDOWN_DEBUGFS);
48+
int ret;
4949

50-
if (ret && (ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
51-
return ret;
50+
if (ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) {
51+
ret = security_locked_down(LOCKDOWN_DEBUGFS);
52+
if (ret)
53+
return ret;
54+
}
5255
return simple_setattr(&init_user_ns, dentry, ia);
5356
}
5457

include/linux/device.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ struct device {
570570
* @flags: Link flags.
571571
* @rpm_active: Whether or not the consumer device is runtime-PM-active.
572572
* @kref: Count repeated addition of the same link.
573-
* @rcu_head: An RCU head to use for deferred execution of SRCU callbacks.
573+
* @rm_work: Work structure used for removing the link.
574574
* @supplier_preactivated: Supplier has been made active before consumer probe.
575575
*/
576576
struct device_link {
@@ -583,9 +583,7 @@ struct device_link {
583583
u32 flags;
584584
refcount_t rpm_active;
585585
struct kref kref;
586-
#ifdef CONFIG_SRCU
587-
struct rcu_head rcu_head;
588-
#endif
586+
struct work_struct rm_work;
589587
bool supplier_preactivated; /* Owned by consumer probe. */
590588
};
591589

0 commit comments

Comments
 (0)