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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'driver-core-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core updatesk from Greg KH:
"Here is the big set of driver core updates for 6.15-rc1. Lots of stuff
happened this development cycle, including:

- kernfs scaling changes to make it even faster thanks to rcu

- bin_attribute constify work in many subsystems

- faux bus minor tweaks for the rust bindings

- rust binding updates for driver core, pci, and platform busses,
making more functionaliy available to rust drivers. These are all
due to people actually trying to use the bindings that were in
6.14.

- make Rafael and Danilo full co-maintainers of the driver core
codebase

- other minor fixes and updates"

* tag 'driver-core-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (52 commits)
rust: platform: require Send for Driver trait implementers
rust: pci: require Send for Driver trait implementers
rust: platform: impl Send + Sync for platform::Device
rust: pci: impl Send + Sync for pci::Device
rust: platform: fix unrestricted &mut platform::Device
rust: pci: fix unrestricted &mut pci::Device
rust: device: implement device context marker
rust: pci: use to_result() in enable_device_mem()
MAINTAINERS: driver core: mark Rafael and Danilo as co-maintainers
rust/kernel/faux: mark Registration methods inline
driver core: faux: only create the device if probe() succeeds
rust/faux: Add missing parent argument to Registration::new()
rust/faux: Drop #[repr(transparent)] from faux::Registration
rust: io: fix devres test with new io accessor functions
rust: io: rename `io::Io` accessors
kernfs: Move dput() outside of the RCU section.
efi: rci2: mark bin_attribute as __ro_after_init
rapidio: constify 'struct bin_attribute'
firmware: qemu_fw_cfg: constify 'struct bin_attribute'
powerpc/perf/hv-24x7: Constify 'struct bin_attribute'
...

+746 -457
+4 -2
MAINTAINERS
··· 7193 7193 7194 7194 DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS 7195 7195 M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> 7196 - R: "Rafael J. Wysocki" <rafael@kernel.org> 7197 - R: Danilo Krummrich <dakr@kernel.org> 7196 + M: "Rafael J. Wysocki" <rafael@kernel.org> 7197 + M: Danilo Krummrich <dakr@kernel.org> 7198 7198 S: Supported 7199 7199 T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 7200 7200 F: Documentation/core-api/kobject.rst 7201 7201 F: drivers/base/ 7202 7202 F: fs/debugfs/ 7203 7203 F: fs/sysfs/ 7204 + F: include/linux/device/ 7204 7205 F: include/linux/debugfs.h 7206 + F: include/linux/device.h 7205 7207 F: include/linux/fwnode.h 7206 7208 F: include/linux/kobj* 7207 7209 F: include/linux/property.h
+12 -12
arch/powerpc/kernel/secvar-sysfs.c
··· 52 52 } 53 53 54 54 static ssize_t data_read(struct file *filep, struct kobject *kobj, 55 - struct bin_attribute *attr, char *buf, loff_t off, 55 + const struct bin_attribute *attr, char *buf, loff_t off, 56 56 size_t count) 57 57 { 58 58 char *data; ··· 85 85 } 86 86 87 87 static ssize_t update_write(struct file *filep, struct kobject *kobj, 88 - struct bin_attribute *attr, char *buf, loff_t off, 88 + const struct bin_attribute *attr, char *buf, loff_t off, 89 89 size_t count) 90 90 { 91 91 int rc; ··· 104 104 105 105 static struct kobj_attribute size_attr = __ATTR_RO(size); 106 106 107 - static struct bin_attribute data_attr = __BIN_ATTR_RO(data, 0); 107 + static struct bin_attribute data_attr __ro_after_init = __BIN_ATTR_RO(data, 0); 108 108 109 - static struct bin_attribute update_attr = __BIN_ATTR_WO(update, 0); 109 + static struct bin_attribute update_attr __ro_after_init = __BIN_ATTR_WO(update, 0); 110 110 111 - static struct bin_attribute *secvar_bin_attrs[] = { 111 + static const struct bin_attribute *const secvar_bin_attrs[] = { 112 112 &data_attr, 113 113 &update_attr, 114 114 NULL, ··· 121 121 122 122 static const struct attribute_group secvar_attr_group = { 123 123 .attrs = secvar_attrs, 124 - .bin_attrs = secvar_bin_attrs, 124 + .bin_attrs_new = secvar_bin_attrs, 125 125 }; 126 126 __ATTRIBUTE_GROUPS(secvar_attr); 127 127 ··· 130 130 .default_groups = secvar_attr_groups, 131 131 }; 132 132 133 - static int update_kobj_size(void) 133 + static __init int update_kobj_size(void) 134 134 { 135 135 136 136 u64 varsize; ··· 145 145 return 0; 146 146 } 147 147 148 - static int secvar_sysfs_config(struct kobject *kobj) 148 + static __init int secvar_sysfs_config(struct kobject *kobj) 149 149 { 150 150 struct attribute_group config_group = { 151 151 .name = "config", ··· 158 158 return 0; 159 159 } 160 160 161 - static int add_var(const char *name) 161 + static __init int add_var(const char *name) 162 162 { 163 163 struct kobject *kobj; 164 164 int rc; ··· 181 181 return 0; 182 182 } 183 183 184 - static int secvar_sysfs_load(void) 184 + static __init int secvar_sysfs_load(void) 185 185 { 186 186 u64 namesize = 0; 187 187 char *name; ··· 209 209 return rc; 210 210 } 211 211 212 - static int secvar_sysfs_load_static(void) 212 + static __init int secvar_sysfs_load_static(void) 213 213 { 214 214 const char * const *name_ptr = secvar_ops->var_names; 215 215 int rc; ··· 224 224 return 0; 225 225 } 226 226 227 - static int secvar_sysfs_init(void) 227 + static __init int secvar_sysfs_init(void) 228 228 { 229 229 u64 max_size; 230 230 int rc;
+4 -4
arch/powerpc/perf/hv-24x7.c
··· 998 998 } 999 999 1000 1000 static ssize_t catalog_read(struct file *filp, struct kobject *kobj, 1001 - struct bin_attribute *bin_attr, char *buf, 1001 + const struct bin_attribute *bin_attr, char *buf, 1002 1002 loff_t offset, size_t count) 1003 1003 { 1004 1004 long hret; ··· 1108 1108 (unsigned long long)be64_to_cpu(page_0->version)); 1109 1109 PAGE_0_ATTR(catalog_len, "%lld\n", 1110 1110 (unsigned long long)be32_to_cpu(page_0->length) * 4096); 1111 - static BIN_ATTR_RO(catalog, 0/* real length varies */); 1111 + static const BIN_ATTR_RO(catalog, 0/* real length varies */); 1112 1112 static DEVICE_ATTR_RO(domains); 1113 1113 static DEVICE_ATTR_RO(sockets); 1114 1114 static DEVICE_ATTR_RO(chipspersocket); 1115 1115 static DEVICE_ATTR_RO(coresperchip); 1116 1116 static DEVICE_ATTR_RO(cpumask); 1117 1117 1118 - static struct bin_attribute *if_bin_attrs[] = { 1118 + static const struct bin_attribute *const if_bin_attrs[] = { 1119 1119 &bin_attr_catalog, 1120 1120 NULL, 1121 1121 }; ··· 1141 1141 1142 1142 static const struct attribute_group if_group = { 1143 1143 .name = "interface", 1144 - .bin_attrs = if_bin_attrs, 1144 + .bin_attrs_new = if_bin_attrs, 1145 1145 .attrs = if_attrs, 1146 1146 }; 1147 1147
+5 -5
arch/powerpc/platforms/powernv/opal-core.c
··· 159 159 * Returns number of bytes read on success, -errno on failure. 160 160 */ 161 161 static ssize_t read_opalcore(struct file *file, struct kobject *kobj, 162 - struct bin_attribute *bin_attr, char *to, 162 + const struct bin_attribute *bin_attr, char *to, 163 163 loff_t pos, size_t count) 164 164 { 165 165 struct opalcore *m; ··· 206 206 return (tpos - pos); 207 207 } 208 208 209 - static struct bin_attribute opal_core_attr = { 209 + static struct bin_attribute opal_core_attr __ro_after_init = { 210 210 .attr = {.name = "core", .mode = 0400}, 211 - .read = read_opalcore 211 + .read_new = read_opalcore 212 212 }; 213 213 214 214 /* ··· 599 599 NULL, 600 600 }; 601 601 602 - static struct bin_attribute *mpipl_bin_attr[] = { 602 + static const struct bin_attribute *const mpipl_bin_attr[] = { 603 603 &opal_core_attr, 604 604 NULL, 605 605 ··· 607 607 608 608 static const struct attribute_group mpipl_group = { 609 609 .attrs = mpipl_attr, 610 - .bin_attrs = mpipl_bin_attr, 610 + .bin_attrs_new = mpipl_bin_attr, 611 611 }; 612 612 613 613 static int __init opalcore_init(void)
+2 -2
arch/powerpc/platforms/powernv/opal-dump.c
··· 286 286 } 287 287 288 288 static ssize_t dump_attr_read(struct file *filep, struct kobject *kobj, 289 - struct bin_attribute *bin_attr, 289 + const struct bin_attribute *bin_attr, 290 290 char *buffer, loff_t pos, size_t count) 291 291 { 292 292 ssize_t rc; ··· 342 342 dump->dump_attr.attr.name = "dump"; 343 343 dump->dump_attr.attr.mode = 0400; 344 344 dump->dump_attr.size = size; 345 - dump->dump_attr.read = dump_attr_read; 345 + dump->dump_attr.read_new = dump_attr_read; 346 346 347 347 dump->id = id; 348 348 dump->size = size;
+2 -2
arch/powerpc/platforms/powernv/opal-elog.c
··· 156 156 #define OPAL_MAX_ERRLOG_SIZE 16384 157 157 158 158 static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj, 159 - struct bin_attribute *bin_attr, 159 + const struct bin_attribute *bin_attr, 160 160 char *buffer, loff_t pos, size_t count) 161 161 { 162 162 int opal_rc; ··· 203 203 elog->raw_attr.attr.name = "raw"; 204 204 elog->raw_attr.attr.mode = 0400; 205 205 elog->raw_attr.size = size; 206 - elog->raw_attr.read = raw_attr_read; 206 + elog->raw_attr.read_new = raw_attr_read; 207 207 208 208 elog->id = id; 209 209 elog->size = size;
+2 -2
arch/powerpc/platforms/powernv/opal-flash.c
··· 432 432 * and pre-allocate required memory. 433 433 */ 434 434 static ssize_t image_data_write(struct file *filp, struct kobject *kobj, 435 - struct bin_attribute *bin_attr, 435 + const struct bin_attribute *bin_attr, 436 436 char *buffer, loff_t pos, size_t count) 437 437 { 438 438 int rc; ··· 493 493 static const struct bin_attribute image_data_attr = { 494 494 .attr = {.name = "image", .mode = 0200}, 495 495 .size = MAX_IMAGE_SIZE, /* Limit image size */ 496 - .write = image_data_write, 496 + .write_new = image_data_write, 497 497 }; 498 498 499 499 static struct kobj_attribute validate_attribute =
+3 -3
arch/powerpc/platforms/powernv/opal-msglog.c
··· 94 94 } 95 95 96 96 static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, 97 - struct bin_attribute *bin_attr, char *to, 97 + const struct bin_attribute *bin_attr, char *to, 98 98 loff_t pos, size_t count) 99 99 { 100 100 return opal_msglog_copy(to, pos, count); 101 101 } 102 102 103 - static struct bin_attribute opal_msglog_attr = { 103 + static struct bin_attribute opal_msglog_attr __ro_after_init = { 104 104 .attr = {.name = "msglog", .mode = 0400}, 105 - .read = opal_msglog_read 105 + .read_new = opal_msglog_read 106 106 }; 107 107 108 108 struct memcons *__init memcons_init(struct device_node *node, const char *mc_prop_name)
+3 -3
arch/powerpc/platforms/powernv/ultravisor.c
··· 32 32 static struct memcons *uv_memcons; 33 33 34 34 static ssize_t uv_msglog_read(struct file *file, struct kobject *kobj, 35 - struct bin_attribute *bin_attr, char *to, 35 + const struct bin_attribute *bin_attr, char *to, 36 36 loff_t pos, size_t count) 37 37 { 38 38 return memcons_copy(uv_memcons, to, pos, count); 39 39 } 40 40 41 - static struct bin_attribute uv_msglog_attr = { 41 + static struct bin_attribute uv_msglog_attr __ro_after_init = { 42 42 .attr = {.name = "msglog", .mode = 0400}, 43 - .read = uv_msglog_read 43 + .read_new = uv_msglog_read 44 44 }; 45 45 46 46 static int __init uv_init(void)
+5
arch/x86/kernel/cpu/resctrl/internal.h
··· 403 403 404 404 extern struct mutex rdtgroup_mutex; 405 405 406 + static inline const char *rdt_kn_name(const struct kernfs_node *kn) 407 + { 408 + return rcu_dereference_check(kn->name, lockdep_is_held(&rdtgroup_mutex)); 409 + } 410 + 406 411 extern struct rdt_hw_resource rdt_resources_all[]; 407 412 extern struct rdtgroup rdtgroup_default; 408 413 extern struct dentry *debugfs_resctrl;
+10 -4
arch/x86/kernel/cpu/resctrl/pseudo_lock.c
··· 52 52 rdtgrp = dev_get_drvdata(dev); 53 53 if (mode) 54 54 *mode = 0600; 55 - return kasprintf(GFP_KERNEL, "pseudo_lock/%s", rdtgrp->kn->name); 55 + guard(mutex)(&rdtgroup_mutex); 56 + return kasprintf(GFP_KERNEL, "pseudo_lock/%s", rdt_kn_name(rdtgrp->kn)); 56 57 } 57 58 58 59 static const struct class pseudo_lock_class = { ··· 1299 1298 struct task_struct *thread; 1300 1299 unsigned int new_minor; 1301 1300 struct device *dev; 1301 + char *kn_name __free(kfree) = NULL; 1302 1302 int ret; 1303 1303 1304 1304 ret = pseudo_lock_region_alloc(plr); ··· 1310 1308 if (ret < 0) { 1311 1309 ret = -EINVAL; 1312 1310 goto out_region; 1311 + } 1312 + kn_name = kstrdup(rdt_kn_name(rdtgrp->kn), GFP_KERNEL); 1313 + if (!kn_name) { 1314 + ret = -ENOMEM; 1315 + goto out_cstates; 1313 1316 } 1314 1317 1315 1318 plr->thread_done = 0; ··· 1360 1353 mutex_unlock(&rdtgroup_mutex); 1361 1354 1362 1355 if (!IS_ERR_OR_NULL(debugfs_resctrl)) { 1363 - plr->debugfs_dir = debugfs_create_dir(rdtgrp->kn->name, 1364 - debugfs_resctrl); 1356 + plr->debugfs_dir = debugfs_create_dir(kn_name, debugfs_resctrl); 1365 1357 if (!IS_ERR_OR_NULL(plr->debugfs_dir)) 1366 1358 debugfs_create_file("pseudo_lock_measure", 0200, 1367 1359 plr->debugfs_dir, rdtgrp, ··· 1369 1363 1370 1364 dev = device_create(&pseudo_lock_class, NULL, 1371 1365 MKDEV(pseudo_lock_major, new_minor), 1372 - rdtgrp, "%s", rdtgrp->kn->name); 1366 + rdtgrp, "%s", kn_name); 1373 1367 1374 1368 mutex_lock(&rdtgroup_mutex); 1375 1369
+48 -25
arch/x86/kernel/cpu/resctrl/rdtgroup.c
··· 944 944 continue; 945 945 946 946 seq_printf(s, "res:%s%s\n", (rdtg == &rdtgroup_default) ? "/" : "", 947 - rdtg->kn->name); 947 + rdt_kn_name(rdtg->kn)); 948 948 seq_puts(s, "mon:"); 949 949 list_for_each_entry(crg, &rdtg->mon.crdtgrp_list, 950 950 mon.crdtgrp_list) { 951 951 if (!resctrl_arch_match_rmid(tsk, crg->mon.parent->closid, 952 952 crg->mon.rmid)) 953 953 continue; 954 - seq_printf(s, "%s", crg->kn->name); 954 + seq_printf(s, "%s", rdt_kn_name(crg->kn)); 955 955 break; 956 956 } 957 957 seq_putc(s, '\n'); ··· 984 984 return 0; 985 985 } 986 986 987 + static void *rdt_kn_parent_priv(struct kernfs_node *kn) 988 + { 989 + /* 990 + * The parent pointer is only valid within RCU section since it can be 991 + * replaced. 992 + */ 993 + guard(rcu)(); 994 + return rcu_dereference(kn->__parent)->priv; 995 + } 996 + 987 997 static int rdt_num_closids_show(struct kernfs_open_file *of, 988 998 struct seq_file *seq, void *v) 989 999 { 990 - struct resctrl_schema *s = of->kn->parent->priv; 1000 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 991 1001 992 1002 seq_printf(seq, "%u\n", s->num_closid); 993 1003 return 0; ··· 1006 996 static int rdt_default_ctrl_show(struct kernfs_open_file *of, 1007 997 struct seq_file *seq, void *v) 1008 998 { 1009 - struct resctrl_schema *s = of->kn->parent->priv; 999 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1010 1000 struct rdt_resource *r = s->res; 1011 1001 1012 1002 seq_printf(seq, "%x\n", resctrl_get_default_ctrl(r)); ··· 1016 1006 static int rdt_min_cbm_bits_show(struct kernfs_open_file *of, 1017 1007 struct seq_file *seq, void *v) 1018 1008 { 1019 - struct resctrl_schema *s = of->kn->parent->priv; 1009 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1020 1010 struct rdt_resource *r = s->res; 1021 1011 1022 1012 seq_printf(seq, "%u\n", r->cache.min_cbm_bits); ··· 1026 1016 static int rdt_shareable_bits_show(struct kernfs_open_file *of, 1027 1017 struct seq_file *seq, void *v) 1028 1018 { 1029 - struct resctrl_schema *s = of->kn->parent->priv; 1019 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1030 1020 struct rdt_resource *r = s->res; 1031 1021 1032 1022 seq_printf(seq, "%x\n", r->cache.shareable_bits); ··· 1050 1040 static int rdt_bit_usage_show(struct kernfs_open_file *of, 1051 1041 struct seq_file *seq, void *v) 1052 1042 { 1053 - struct resctrl_schema *s = of->kn->parent->priv; 1043 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1054 1044 /* 1055 1045 * Use unsigned long even though only 32 bits are used to ensure 1056 1046 * test_bit() is used safely. ··· 1132 1122 static int rdt_min_bw_show(struct kernfs_open_file *of, 1133 1123 struct seq_file *seq, void *v) 1134 1124 { 1135 - struct resctrl_schema *s = of->kn->parent->priv; 1125 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1136 1126 struct rdt_resource *r = s->res; 1137 1127 1138 1128 seq_printf(seq, "%u\n", r->membw.min_bw); ··· 1142 1132 static int rdt_num_rmids_show(struct kernfs_open_file *of, 1143 1133 struct seq_file *seq, void *v) 1144 1134 { 1145 - struct rdt_resource *r = of->kn->parent->priv; 1135 + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); 1146 1136 1147 1137 seq_printf(seq, "%d\n", r->num_rmid); 1148 1138 ··· 1152 1142 static int rdt_mon_features_show(struct kernfs_open_file *of, 1153 1143 struct seq_file *seq, void *v) 1154 1144 { 1155 - struct rdt_resource *r = of->kn->parent->priv; 1145 + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); 1156 1146 struct mon_evt *mevt; 1157 1147 1158 1148 list_for_each_entry(mevt, &r->evt_list, list) { ··· 1167 1157 static int rdt_bw_gran_show(struct kernfs_open_file *of, 1168 1158 struct seq_file *seq, void *v) 1169 1159 { 1170 - struct resctrl_schema *s = of->kn->parent->priv; 1160 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1171 1161 struct rdt_resource *r = s->res; 1172 1162 1173 1163 seq_printf(seq, "%u\n", r->membw.bw_gran); ··· 1177 1167 static int rdt_delay_linear_show(struct kernfs_open_file *of, 1178 1168 struct seq_file *seq, void *v) 1179 1169 { 1180 - struct resctrl_schema *s = of->kn->parent->priv; 1170 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1181 1171 struct rdt_resource *r = s->res; 1182 1172 1183 1173 seq_printf(seq, "%u\n", r->membw.delay_linear); ··· 1195 1185 static int rdt_thread_throttle_mode_show(struct kernfs_open_file *of, 1196 1186 struct seq_file *seq, void *v) 1197 1187 { 1198 - struct resctrl_schema *s = of->kn->parent->priv; 1188 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1199 1189 struct rdt_resource *r = s->res; 1200 1190 1201 1191 switch (r->membw.throttle_mode) { ··· 1269 1259 static int rdt_has_sparse_bitmasks_show(struct kernfs_open_file *of, 1270 1260 struct seq_file *seq, void *v) 1271 1261 { 1272 - struct resctrl_schema *s = of->kn->parent->priv; 1262 + struct resctrl_schema *s = rdt_kn_parent_priv(of->kn); 1273 1263 struct rdt_resource *r = s->res; 1274 1264 1275 1265 seq_printf(seq, "%u\n", r->cache.arch_has_sparse_bitmasks); ··· 1680 1670 static int mbm_total_bytes_config_show(struct kernfs_open_file *of, 1681 1671 struct seq_file *seq, void *v) 1682 1672 { 1683 - struct rdt_resource *r = of->kn->parent->priv; 1673 + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); 1684 1674 1685 1675 mbm_config_show(seq, r, QOS_L3_MBM_TOTAL_EVENT_ID); 1686 1676 ··· 1690 1680 static int mbm_local_bytes_config_show(struct kernfs_open_file *of, 1691 1681 struct seq_file *seq, void *v) 1692 1682 { 1693 - struct rdt_resource *r = of->kn->parent->priv; 1683 + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); 1694 1684 1695 1685 mbm_config_show(seq, r, QOS_L3_MBM_LOCAL_EVENT_ID); 1696 1686 ··· 1797 1787 char *buf, size_t nbytes, 1798 1788 loff_t off) 1799 1789 { 1800 - struct rdt_resource *r = of->kn->parent->priv; 1790 + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); 1801 1791 int ret; 1802 1792 1803 1793 /* Valid input requires a trailing newline */ ··· 1823 1813 char *buf, size_t nbytes, 1824 1814 loff_t off) 1825 1815 { 1826 - struct rdt_resource *r = of->kn->parent->priv; 1816 + struct rdt_resource *r = rdt_kn_parent_priv(of->kn); 1827 1817 int ret; 1828 1818 1829 1819 /* Valid input requires a trailing newline */ ··· 2523 2513 * resource. "info" and its subdirectories don't 2524 2514 * have rdtgroup structures, so return NULL here. 2525 2515 */ 2526 - if (kn == kn_info || kn->parent == kn_info) 2516 + if (kn == kn_info || 2517 + rcu_access_pointer(kn->__parent) == kn_info) 2527 2518 return NULL; 2528 2519 else 2529 2520 return kn->priv; 2530 2521 } else { 2531 - return kn->parent->priv; 2522 + return rdt_kn_parent_priv(kn); 2532 2523 } 2533 2524 } 2534 2525 ··· 3763 3752 */ 3764 3753 static bool is_mon_groups(struct kernfs_node *kn, const char *name) 3765 3754 { 3766 - return (!strcmp(kn->name, "mon_groups") && 3755 + return (!strcmp(rdt_kn_name(kn), "mon_groups") && 3767 3756 strcmp(name, "mon_groups")); 3768 3757 } 3769 3758 ··· 3878 3867 return 0; 3879 3868 } 3880 3869 3870 + static struct kernfs_node *rdt_kn_parent(struct kernfs_node *kn) 3871 + { 3872 + /* 3873 + * Valid within the RCU section it was obtained or while rdtgroup_mutex 3874 + * is held. 3875 + */ 3876 + return rcu_dereference_check(kn->__parent, lockdep_is_held(&rdtgroup_mutex)); 3877 + } 3878 + 3881 3879 static int rdtgroup_rmdir(struct kernfs_node *kn) 3882 3880 { 3883 - struct kernfs_node *parent_kn = kn->parent; 3881 + struct kernfs_node *parent_kn; 3884 3882 struct rdtgroup *rdtgrp; 3885 3883 cpumask_var_t tmpmask; 3886 3884 int ret = 0; ··· 3902 3882 ret = -EPERM; 3903 3883 goto out; 3904 3884 } 3885 + parent_kn = rdt_kn_parent(kn); 3905 3886 3906 3887 /* 3907 3888 * If the rdtgroup is a ctrl_mon group and parent directory ··· 3920 3899 ret = rdtgroup_rmdir_ctrl(rdtgrp, tmpmask); 3921 3900 } 3922 3901 } else if (rdtgrp->type == RDTMON_GROUP && 3923 - is_mon_groups(parent_kn, kn->name)) { 3902 + is_mon_groups(parent_kn, rdt_kn_name(kn))) { 3924 3903 ret = rdtgroup_rmdir_mon(rdtgrp, tmpmask); 3925 3904 } else { 3926 3905 ret = -EPERM; ··· 3971 3950 static int rdtgroup_rename(struct kernfs_node *kn, 3972 3951 struct kernfs_node *new_parent, const char *new_name) 3973 3952 { 3953 + struct kernfs_node *kn_parent; 3974 3954 struct rdtgroup *new_prdtgrp; 3975 3955 struct rdtgroup *rdtgrp; 3976 3956 cpumask_var_t tmpmask; ··· 4006 3984 goto out; 4007 3985 } 4008 3986 4009 - if (rdtgrp->type != RDTMON_GROUP || !kn->parent || 4010 - !is_mon_groups(kn->parent, kn->name)) { 3987 + kn_parent = rdt_kn_parent(kn); 3988 + if (rdtgrp->type != RDTMON_GROUP || !kn_parent || 3989 + !is_mon_groups(kn_parent, rdt_kn_name(kn))) { 4011 3990 rdt_last_cmd_puts("Source must be a MON group\n"); 4012 3991 ret = -EPERM; 4013 3992 goto out;
+5 -5
drivers/accel/habanalabs/common/sysfs.c
··· 368 368 } 369 369 370 370 static ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj, 371 - struct bin_attribute *attr, char *buf, loff_t offset, 371 + const struct bin_attribute *attr, char *buf, loff_t offset, 372 372 size_t max_size) 373 373 { 374 374 struct device *dev = kobj_to_dev(kobj); ··· 443 443 static DEVICE_ATTR_RO(module_id); 444 444 static DEVICE_ATTR_RO(parent_device); 445 445 446 - static struct bin_attribute bin_attr_eeprom = { 446 + static const struct bin_attribute bin_attr_eeprom = { 447 447 .attr = {.name = "eeprom", .mode = (0444)}, 448 448 .size = PAGE_SIZE, 449 - .read = eeprom_read_handler 449 + .read_new = eeprom_read_handler 450 450 }; 451 451 452 452 static struct attribute *hl_dev_attrs[] = { ··· 472 472 NULL, 473 473 }; 474 474 475 - static struct bin_attribute *hl_dev_bin_attrs[] = { 475 + static const struct bin_attribute *const hl_dev_bin_attrs[] = { 476 476 &bin_attr_eeprom, 477 477 NULL 478 478 }; 479 479 480 480 static struct attribute_group hl_dev_attr_group = { 481 481 .attrs = hl_dev_attrs, 482 - .bin_attrs = hl_dev_bin_attrs, 482 + .bin_attrs_new = hl_dev_bin_attrs, 483 483 }; 484 484 485 485 static struct attribute_group hl_dev_clks_attr_group;
+1 -1
drivers/base/bus.c
··· 1291 1291 * @groups: default attributes for the root device 1292 1292 * 1293 1293 * All 'virtual' subsystems have a /sys/devices/system/<name> root device 1294 - * with the name of the subystem. The root device can carry subsystem-wide 1294 + * with the name of the subsystem. The root device can carry subsystem-wide 1295 1295 * attributes. All registered devices are below this single root device. 1296 1296 * There's no restriction on device naming. This is for kernel software 1297 1297 * constructs which need sysfs interface.
+6 -6
drivers/base/component.c
··· 87 87 size_t i; 88 88 89 89 mutex_lock(&component_mutex); 90 - seq_printf(s, "%-40s %20s\n", "aggregate_device name", "status"); 91 - seq_puts(s, "-------------------------------------------------------------\n"); 92 - seq_printf(s, "%-40s %20s\n\n", 90 + seq_printf(s, "%-50s %20s\n", "aggregate_device name", "status"); 91 + seq_puts(s, "-----------------------------------------------------------------------\n"); 92 + seq_printf(s, "%-50s %20s\n\n", 93 93 dev_name(m->parent), m->bound ? "bound" : "not bound"); 94 94 95 - seq_printf(s, "%-40s %20s\n", "device name", "status"); 96 - seq_puts(s, "-------------------------------------------------------------\n"); 95 + seq_printf(s, "%-50s %20s\n", "device name", "status"); 96 + seq_puts(s, "-----------------------------------------------------------------------\n"); 97 97 for (i = 0; i < match->num; i++) { 98 98 struct component *component = match->compare[i].component; 99 99 100 - seq_printf(s, "%-40s %20s\n", 100 + seq_printf(s, "%-50s %20s\n", 101 101 component ? dev_name(component->dev) : "(unknown)", 102 102 component ? (component->bound ? "bound" : "not bound") : "not registered"); 103 103 }
+14 -1
drivers/base/faux.c
··· 102 102 * 103 103 * Note, when this function is called, the functions specified in struct 104 104 * faux_ops can be called before the function returns, so be prepared for 105 - * everything to be properly initialized before that point in time. 105 + * everything to be properly initialized before that point in time. If the 106 + * probe callback (if one is present) does NOT succeed, the creation of the 107 + * device will fail and NULL will be returned. 106 108 * 107 109 * Return: 108 110 * * NULL if an error happened with creating the device ··· 147 145 __func__, name, ret); 148 146 put_device(dev); 149 147 return NULL; 148 + } 149 + 150 + /* 151 + * Verify that we did bind the driver to the device (i.e. probe worked), 152 + * if not, let's fail the creation as trying to guess if probe was 153 + * successful is almost impossible to determine by the caller. 154 + */ 155 + if (!dev->driver) { 156 + dev_err(dev, "probe did not succeed, tearing down the device\n"); 157 + faux_device_destroy(faux_dev); 158 + faux_dev = NULL; 150 159 } 151 160 152 161 return faux_dev;
+3 -2
drivers/base/physical_location.c
··· 7 7 8 8 #include <linux/acpi.h> 9 9 #include <linux/sysfs.h> 10 + #include <linux/string_choices.h> 10 11 11 12 #include "physical_location.h" 12 13 ··· 117 116 char *buf) 118 117 { 119 118 return sysfs_emit(buf, "%s\n", 120 - dev->physical_location->dock ? "yes" : "no"); 119 + str_yes_no(dev->physical_location->dock)); 121 120 } 122 121 static DEVICE_ATTR_RO(dock); 123 122 ··· 125 124 char *buf) 126 125 { 127 126 return sysfs_emit(buf, "%s\n", 128 - dev->physical_location->lid ? "yes" : "no"); 127 + str_yes_no(dev->physical_location->lid)); 129 128 } 130 129 static DEVICE_ATTR_RO(lid); 131 130
+5 -5
drivers/cxl/port.c
··· 153 153 } 154 154 155 155 static ssize_t CDAT_read(struct file *filp, struct kobject *kobj, 156 - struct bin_attribute *bin_attr, char *buf, 156 + const struct bin_attribute *bin_attr, char *buf, 157 157 loff_t offset, size_t count) 158 158 { 159 159 struct device *dev = kobj_to_dev(kobj); ··· 170 170 port->cdat.length); 171 171 } 172 172 173 - static BIN_ATTR_ADMIN_RO(CDAT, 0); 173 + static const BIN_ATTR_ADMIN_RO(CDAT, 0); 174 174 175 175 static umode_t cxl_port_bin_attr_is_visible(struct kobject *kobj, 176 176 const struct bin_attribute *attr, int i) ··· 184 184 return 0; 185 185 } 186 186 187 - static struct bin_attribute *cxl_cdat_bin_attributes[] = { 187 + static const struct bin_attribute *const cxl_cdat_bin_attributes[] = { 188 188 &bin_attr_CDAT, 189 189 NULL, 190 190 }; 191 191 192 - static struct attribute_group cxl_cdat_attribute_group = { 193 - .bin_attrs = cxl_cdat_bin_attributes, 192 + static const struct attribute_group cxl_cdat_attribute_group = { 193 + .bin_attrs_new = cxl_cdat_bin_attributes, 194 194 .is_bin_visible = cxl_port_bin_attr_is_visible, 195 195 }; 196 196
+11 -17
drivers/firmware/dmi-sysfs.c
··· 431 431 } 432 432 } 433 433 434 - static ssize_t dmi_sel_raw_read(struct file *filp, struct kobject *kobj, 435 - struct bin_attribute *bin_attr, 436 - char *buf, loff_t pos, size_t count) 434 + static ssize_t raw_event_log_read(struct file *filp, struct kobject *kobj, 435 + const struct bin_attribute *bin_attr, 436 + char *buf, loff_t pos, size_t count) 437 437 { 438 438 struct dmi_sysfs_entry *entry = to_entry(kobj->parent); 439 439 struct dmi_read_state state = { ··· 445 445 return find_dmi_entry(entry, dmi_sel_raw_read_helper, &state); 446 446 } 447 447 448 - static struct bin_attribute dmi_sel_raw_attr = { 449 - .attr = {.name = "raw_event_log", .mode = 0400}, 450 - .read = dmi_sel_raw_read, 451 - }; 448 + static const BIN_ATTR_ADMIN_RO(raw_event_log, 0); 452 449 453 450 static int dmi_system_event_log(struct dmi_sysfs_entry *entry) 454 451 { ··· 461 464 if (ret) 462 465 goto out_free; 463 466 464 - ret = sysfs_create_bin_file(entry->child, &dmi_sel_raw_attr); 467 + ret = sysfs_create_bin_file(entry->child, &bin_attr_raw_event_log); 465 468 if (ret) 466 469 goto out_del; 467 470 ··· 534 537 &state->pos, dh, entry_length); 535 538 } 536 539 537 - static ssize_t dmi_entry_raw_read(struct file *filp, 538 - struct kobject *kobj, 539 - struct bin_attribute *bin_attr, 540 - char *buf, loff_t pos, size_t count) 540 + static ssize_t raw_read(struct file *filp, 541 + struct kobject *kobj, 542 + const struct bin_attribute *bin_attr, 543 + char *buf, loff_t pos, size_t count) 541 544 { 542 545 struct dmi_sysfs_entry *entry = to_entry(kobj); 543 546 struct dmi_read_state state = { ··· 549 552 return find_dmi_entry(entry, dmi_entry_raw_read_helper, &state); 550 553 } 551 554 552 - static const struct bin_attribute dmi_entry_raw_attr = { 553 - .attr = {.name = "raw", .mode = 0400}, 554 - .read = dmi_entry_raw_read, 555 - }; 555 + static const BIN_ATTR_ADMIN_RO(raw, 0); 556 556 557 557 static void dmi_sysfs_entry_release(struct kobject *kobj) 558 558 { ··· 624 630 goto out_err; 625 631 626 632 /* Create the raw binary file to access the entry */ 627 - *ret = sysfs_create_bin_file(&entry->kobj, &dmi_entry_raw_attr); 633 + *ret = sysfs_create_bin_file(&entry->kobj, &bin_attr_raw); 628 634 if (*ret) 629 635 goto out_err; 630 636
+2 -2
drivers/firmware/dmi_scan.c
··· 761 761 pr_info("DMI not present or invalid.\n"); 762 762 } 763 763 764 - static BIN_ATTR_SIMPLE_ADMIN_RO(smbios_entry_point); 765 - static BIN_ATTR_SIMPLE_ADMIN_RO(DMI); 764 + static __ro_after_init BIN_ATTR_SIMPLE_ADMIN_RO(smbios_entry_point); 765 + static __ro_after_init BIN_ATTR_SIMPLE_ADMIN_RO(DMI); 766 766 767 767 static int __init dmi_init(void) 768 768 {
+2 -2
drivers/firmware/efi/mokvar-table.c
··· 263 263 * amount of data in this mokvar config table entry. 264 264 */ 265 265 static ssize_t efi_mokvar_sysfs_read(struct file *file, struct kobject *kobj, 266 - struct bin_attribute *bin_attr, char *buf, 266 + const struct bin_attribute *bin_attr, char *buf, 267 267 loff_t off, size_t count) 268 268 { 269 269 struct efi_mokvar_table_entry *mokvar_entry = bin_attr->private; ··· 340 340 mokvar_sysfs->bin_attr.attr.name = mokvar_entry->name; 341 341 mokvar_sysfs->bin_attr.attr.mode = 0400; 342 342 mokvar_sysfs->bin_attr.size = mokvar_entry->data_size; 343 - mokvar_sysfs->bin_attr.read = efi_mokvar_sysfs_read; 343 + mokvar_sysfs->bin_attr.read_new = efi_mokvar_sysfs_read; 344 344 345 345 err = sysfs_create_bin_file(mokvar_kobj, 346 346 &mokvar_sysfs->bin_attr);
+1 -1
drivers/firmware/efi/rci2-table.c
··· 40 40 static u32 rci2_table_len; 41 41 unsigned long rci2_table_phys __ro_after_init = EFI_INVALID_TABLE_ADDR; 42 42 43 - static BIN_ATTR_SIMPLE_ADMIN_RO(rci2); 43 + static __ro_after_init BIN_ATTR_SIMPLE_ADMIN_RO(rci2); 44 44 45 45 static u16 checksum(void) 46 46 {
+3 -3
drivers/firmware/qemu_fw_cfg.c
··· 460 460 461 461 /* raw-read method and attribute */ 462 462 static ssize_t fw_cfg_sysfs_read_raw(struct file *filp, struct kobject *kobj, 463 - struct bin_attribute *bin_attr, 463 + const struct bin_attribute *bin_attr, 464 464 char *buf, loff_t pos, size_t count) 465 465 { 466 466 struct fw_cfg_sysfs_entry *entry = to_entry(kobj); ··· 474 474 return fw_cfg_read_blob(entry->select, buf, pos, count); 475 475 } 476 476 477 - static struct bin_attribute fw_cfg_sysfs_attr_raw = { 477 + static const struct bin_attribute fw_cfg_sysfs_attr_raw = { 478 478 .attr = { .name = "raw", .mode = S_IRUSR }, 479 - .read = fw_cfg_sysfs_read_raw, 479 + .read_new = fw_cfg_sysfs_read_raw, 480 480 }; 481 481 482 482 /*
+4 -4
drivers/fsi/fsi-core.c
··· 554 554 } 555 555 556 556 static ssize_t fsi_slave_sysfs_raw_read(struct file *file, 557 - struct kobject *kobj, struct bin_attribute *attr, char *buf, 557 + struct kobject *kobj, const struct bin_attribute *attr, char *buf, 558 558 loff_t off, size_t count) 559 559 { 560 560 struct fsi_slave *slave = to_fsi_slave(kobj_to_dev(kobj)); ··· 581 581 } 582 582 583 583 static ssize_t fsi_slave_sysfs_raw_write(struct file *file, 584 - struct kobject *kobj, struct bin_attribute *attr, 584 + struct kobject *kobj, const struct bin_attribute *attr, 585 585 char *buf, loff_t off, size_t count) 586 586 { 587 587 struct fsi_slave *slave = to_fsi_slave(kobj_to_dev(kobj)); ··· 613 613 .mode = 0600, 614 614 }, 615 615 .size = 0, 616 - .read = fsi_slave_sysfs_raw_read, 617 - .write = fsi_slave_sysfs_raw_write, 616 + .read_new = fsi_slave_sysfs_raw_read, 617 + .write_new = fsi_slave_sysfs_raw_write, 618 618 }; 619 619 620 620 static void fsi_slave_release(struct device *dev)
+3 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 246 246 } 247 247 248 248 static ssize_t amdgpu_sysfs_reg_state_get(struct file *f, struct kobject *kobj, 249 - struct bin_attribute *attr, char *buf, 249 + const struct bin_attribute *attr, char *buf, 250 250 loff_t ppos, size_t count) 251 251 { 252 252 struct device *dev = kobj_to_dev(kobj); ··· 282 282 return bytes_read; 283 283 } 284 284 285 - BIN_ATTR(reg_state, 0444, amdgpu_sysfs_reg_state_get, NULL, 286 - AMDGPU_SYS_REG_STATE_END); 285 + static const BIN_ATTR(reg_state, 0444, amdgpu_sysfs_reg_state_get, NULL, 286 + AMDGPU_SYS_REG_STATE_END); 287 287 288 288 int amdgpu_reg_state_sysfs_init(struct amdgpu_device *adev) 289 289 {
+7 -7
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
··· 4025 4025 } 4026 4026 4027 4027 static ssize_t amdgpu_psp_vbflash_write(struct file *filp, struct kobject *kobj, 4028 - struct bin_attribute *bin_attr, 4028 + const struct bin_attribute *bin_attr, 4029 4029 char *buffer, loff_t pos, size_t count) 4030 4030 { 4031 4031 struct device *dev = kobj_to_dev(kobj); ··· 4061 4061 } 4062 4062 4063 4063 static ssize_t amdgpu_psp_vbflash_read(struct file *filp, struct kobject *kobj, 4064 - struct bin_attribute *bin_attr, char *buffer, 4064 + const struct bin_attribute *bin_attr, char *buffer, 4065 4065 loff_t pos, size_t count) 4066 4066 { 4067 4067 struct device *dev = kobj_to_dev(kobj); ··· 4113 4113 * Writing to this file will stage an IFWI for update. Reading from this file 4114 4114 * will trigger the update process. 4115 4115 */ 4116 - static struct bin_attribute psp_vbflash_bin_attr = { 4116 + static const struct bin_attribute psp_vbflash_bin_attr = { 4117 4117 .attr = {.name = "psp_vbflash", .mode = 0660}, 4118 4118 .size = 0, 4119 - .write = amdgpu_psp_vbflash_write, 4120 - .read = amdgpu_psp_vbflash_read, 4119 + .write_new = amdgpu_psp_vbflash_write, 4120 + .read_new = amdgpu_psp_vbflash_read, 4121 4121 }; 4122 4122 4123 4123 /** ··· 4144 4144 } 4145 4145 static DEVICE_ATTR(psp_vbflash_status, 0440, amdgpu_psp_vbflash_status, NULL); 4146 4146 4147 - static struct bin_attribute *bin_flash_attrs[] = { 4147 + static const struct bin_attribute *const bin_flash_attrs[] = { 4148 4148 &psp_vbflash_bin_attr, 4149 4149 NULL 4150 4150 }; ··· 4180 4180 4181 4181 const struct attribute_group amdgpu_flash_attr_group = { 4182 4182 .attrs = flash_attrs, 4183 - .bin_attrs = bin_flash_attrs, 4183 + .bin_attrs_new = bin_flash_attrs, 4184 4184 .is_bin_visible = amdgpu_bin_flash_attr_is_visible, 4185 4185 .is_visible = amdgpu_flash_attr_is_visible, 4186 4186 };
+6 -7
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
··· 1733 1733 */ 1734 1734 1735 1735 static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f, 1736 - struct kobject *kobj, struct bin_attribute *attr, 1736 + struct kobject *kobj, const struct bin_attribute *attr, 1737 1737 char *buf, loff_t ppos, size_t count) 1738 1738 { 1739 1739 struct amdgpu_ras *con = ··· 2068 2068 /* debugfs end */ 2069 2069 2070 2070 /* ras fs */ 2071 - static BIN_ATTR(gpu_vram_bad_pages, S_IRUGO, 2072 - amdgpu_ras_sysfs_badpages_read, NULL, 0); 2071 + static const BIN_ATTR(gpu_vram_bad_pages, S_IRUGO, 2072 + amdgpu_ras_sysfs_badpages_read, NULL, 0); 2073 2073 static DEVICE_ATTR(features, S_IRUGO, 2074 2074 amdgpu_ras_sysfs_features_read, NULL); 2075 2075 static DEVICE_ATTR(version, 0444, ··· 2091 2091 &con->event_state_attr.attr, 2092 2092 NULL 2093 2093 }; 2094 - struct bin_attribute *bin_attrs[] = { 2094 + const struct bin_attribute *bin_attrs[] = { 2095 2095 NULL, 2096 2096 NULL, 2097 2097 }; ··· 2117 2117 2118 2118 if (amdgpu_bad_page_threshold != 0) { 2119 2119 /* add bad_page_features entry */ 2120 - bin_attr_gpu_vram_bad_pages.private = NULL; 2121 2120 con->badpages_attr = bin_attr_gpu_vram_bad_pages; 2121 + sysfs_bin_attr_init(&con->badpages_attr); 2122 2122 bin_attrs[0] = &con->badpages_attr; 2123 - group.bin_attrs = bin_attrs; 2124 - sysfs_bin_attr_init(bin_attrs[0]); 2123 + group.bin_attrs_new = bin_attrs; 2125 2124 } 2126 2125 2127 2126 r = sysfs_create_group(&adev->dev->kobj, &group);
+4 -4
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
··· 597 597 * incorrect/corrupted and we should correct our SRM by getting it from PSP 598 598 */ 599 599 static ssize_t srm_data_write(struct file *filp, struct kobject *kobj, 600 - struct bin_attribute *bin_attr, char *buffer, 600 + const struct bin_attribute *bin_attr, char *buffer, 601 601 loff_t pos, size_t count) 602 602 { 603 603 struct hdcp_workqueue *work; ··· 621 621 } 622 622 623 623 static ssize_t srm_data_read(struct file *filp, struct kobject *kobj, 624 - struct bin_attribute *bin_attr, char *buffer, 624 + const struct bin_attribute *bin_attr, char *buffer, 625 625 loff_t pos, size_t count) 626 626 { 627 627 struct hdcp_workqueue *work; ··· 681 681 static const struct bin_attribute data_attr = { 682 682 .attr = {.name = "hdcp_srm", .mode = 0664}, 683 683 .size = PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE, /* Limit SRM size */ 684 - .write = srm_data_write, 685 - .read = srm_data_read, 684 + .write_new = srm_data_write, 685 + .read_new = srm_data_read, 686 686 }; 687 687 688 688 struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev,
+5 -5
drivers/gpu/drm/drm_sysfs.c
··· 261 261 } 262 262 263 263 static ssize_t edid_show(struct file *filp, struct kobject *kobj, 264 - struct bin_attribute *attr, char *buf, loff_t off, 264 + const struct bin_attribute *attr, char *buf, loff_t off, 265 265 size_t count) 266 266 { 267 267 struct device *connector_dev = kobj_to_dev(kobj); ··· 315 315 NULL 316 316 }; 317 317 318 - static struct bin_attribute edid_attr = { 318 + static const struct bin_attribute edid_attr = { 319 319 .attr.name = "edid", 320 320 .attr.mode = 0444, 321 321 .size = 0, 322 - .read = edid_show, 322 + .read_new = edid_show, 323 323 }; 324 324 325 - static struct bin_attribute *connector_bin_attrs[] = { 325 + static const struct bin_attribute *const connector_bin_attrs[] = { 326 326 &edid_attr, 327 327 NULL 328 328 }; 329 329 330 330 static const struct attribute_group connector_dev_group = { 331 331 .attrs = connector_dev_attrs, 332 - .bin_attrs = connector_bin_attrs, 332 + .bin_attrs_new = connector_bin_attrs, 333 333 }; 334 334 335 335 static const struct attribute_group *connector_dev_groups[] = {
+4 -4
drivers/gpu/drm/i915/i915_gpu_error.c
··· 2490 2490 } 2491 2491 2492 2492 static ssize_t error_state_read(struct file *filp, struct kobject *kobj, 2493 - struct bin_attribute *attr, char *buf, 2493 + const struct bin_attribute *attr, char *buf, 2494 2494 loff_t off, size_t count) 2495 2495 { 2496 2496 ··· 2526 2526 } 2527 2527 2528 2528 static ssize_t error_state_write(struct file *file, struct kobject *kobj, 2529 - struct bin_attribute *attr, char *buf, 2529 + const struct bin_attribute *attr, char *buf, 2530 2530 loff_t off, size_t count) 2531 2531 { 2532 2532 struct device *kdev = kobj_to_dev(kobj); ··· 2542 2542 .attr.name = "error", 2543 2543 .attr.mode = S_IRUSR | S_IWUSR, 2544 2544 .size = 0, 2545 - .read = error_state_read, 2546 - .write = error_state_write, 2545 + .read_new = error_state_read, 2546 + .write_new = error_state_write, 2547 2547 }; 2548 2548 2549 2549 void i915_gpu_error_sysfs_setup(struct drm_i915_private *i915)
+6 -6
drivers/gpu/drm/i915/i915_sysfs.c
··· 60 60 61 61 static ssize_t 62 62 i915_l3_read(struct file *filp, struct kobject *kobj, 63 - struct bin_attribute *attr, char *buf, 63 + const struct bin_attribute *attr, char *buf, 64 64 loff_t offset, size_t count) 65 65 { 66 66 struct device *kdev = kobj_to_dev(kobj); ··· 88 88 89 89 static ssize_t 90 90 i915_l3_write(struct file *filp, struct kobject *kobj, 91 - struct bin_attribute *attr, char *buf, 91 + const struct bin_attribute *attr, char *buf, 92 92 loff_t offset, size_t count) 93 93 { 94 94 struct device *kdev = kobj_to_dev(kobj); ··· 140 140 static const struct bin_attribute dpf_attrs = { 141 141 .attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)}, 142 142 .size = GEN7_L3LOG_SIZE, 143 - .read = i915_l3_read, 144 - .write = i915_l3_write, 143 + .read_new = i915_l3_read, 144 + .write_new = i915_l3_write, 145 145 .mmap = NULL, 146 146 .private = (void *)0 147 147 }; ··· 149 149 static const struct bin_attribute dpf_attrs_1 = { 150 150 .attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)}, 151 151 .size = GEN7_L3LOG_SIZE, 152 - .read = i915_l3_read, 153 - .write = i915_l3_write, 152 + .read_new = i915_l3_read, 153 + .write_new = i915_l3_write, 154 154 .mmap = NULL, 155 155 .private = (void *)1 156 156 };
+4 -4
drivers/gpu/drm/lima/lima_drv.c
··· 310 310 } 311 311 312 312 static ssize_t lima_error_state_read(struct file *filp, struct kobject *kobj, 313 - struct bin_attribute *attr, char *buf, 313 + const struct bin_attribute *attr, char *buf, 314 314 loff_t off, size_t count) 315 315 { 316 316 struct device *dev = kobj_to_dev(kobj); ··· 336 336 } 337 337 338 338 static ssize_t lima_error_state_write(struct file *file, struct kobject *kobj, 339 - struct bin_attribute *attr, char *buf, 339 + const struct bin_attribute *attr, char *buf, 340 340 loff_t off, size_t count) 341 341 { 342 342 struct device *dev = kobj_to_dev(kobj); ··· 362 362 .attr.name = "error", 363 363 .attr.mode = 0600, 364 364 .size = 0, 365 - .read = lima_error_state_read, 366 - .write = lima_error_state_write, 365 + .read_new = lima_error_state_read, 366 + .write_new = lima_error_state_write, 367 367 }; 368 368 369 369 static int lima_pdev_probe(struct platform_device *pdev)
+2 -2
drivers/gpu/nova-core/driver.rs
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 - use kernel::{bindings, c_str, pci, prelude::*}; 3 + use kernel::{bindings, c_str, device::Core, pci, prelude::*}; 4 4 5 5 use crate::gpu::Gpu; 6 6 ··· 27 27 type IdInfo = (); 28 28 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; 29 29 30 - fn probe(pdev: &mut pci::Device, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { 30 + fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { 31 31 dev_dbg!(pdev.as_ref(), "Probe Nova Core GPU driver.\n"); 32 32 33 33 pdev.enable_device_mem()?;
+1 -1
drivers/gpu/nova-core/regs.rs
··· 35 35 impl Boot0 { 36 36 #[inline] 37 37 pub(crate) fn read(bar: &Bar0) -> Self { 38 - Self(bar.readl(BOOT0_OFFSET)) 38 + Self(bar.read32(BOOT0_OFFSET)) 39 39 } 40 40 41 41 #[inline]
+5 -5
drivers/input/touchscreen/goodix_berlin_core.c
··· 673 673 } 674 674 675 675 static ssize_t registers_read(struct file *filp, struct kobject *kobj, 676 - struct bin_attribute *bin_attr, 676 + const struct bin_attribute *bin_attr, 677 677 char *buf, loff_t off, size_t count) 678 678 { 679 679 struct device *dev = kobj_to_dev(kobj); ··· 686 686 } 687 687 688 688 static ssize_t registers_write(struct file *filp, struct kobject *kobj, 689 - struct bin_attribute *bin_attr, 689 + const struct bin_attribute *bin_attr, 690 690 char *buf, loff_t off, size_t count) 691 691 { 692 692 struct device *dev = kobj_to_dev(kobj); ··· 698 698 return error ? error : count; 699 699 } 700 700 701 - static BIN_ATTR_ADMIN_RW(registers, 0); 701 + static const BIN_ATTR_ADMIN_RW(registers, 0); 702 702 703 - static struct bin_attribute *goodix_berlin_bin_attrs[] = { 703 + static const struct bin_attribute *const goodix_berlin_bin_attrs[] = { 704 704 &bin_attr_registers, 705 705 NULL, 706 706 }; 707 707 708 708 static const struct attribute_group goodix_berlin_attr_group = { 709 - .bin_attrs = goodix_berlin_bin_attrs, 709 + .bin_attrs_new = goodix_berlin_bin_attrs, 710 710 }; 711 711 712 712 const struct attribute_group *goodix_berlin_groups[] = {
+4 -4
drivers/pcmcia/cistpl.c
··· 1540 1540 1541 1541 1542 1542 static ssize_t pccard_show_cis(struct file *filp, struct kobject *kobj, 1543 - struct bin_attribute *bin_attr, 1543 + const struct bin_attribute *bin_attr, 1544 1544 char *buf, loff_t off, size_t count) 1545 1545 { 1546 1546 unsigned int size = 0x200; ··· 1571 1571 1572 1572 1573 1573 static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj, 1574 - struct bin_attribute *bin_attr, 1574 + const struct bin_attribute *bin_attr, 1575 1575 char *buf, loff_t off, size_t count) 1576 1576 { 1577 1577 struct pcmcia_socket *s; ··· 1605 1605 const struct bin_attribute pccard_cis_attr = { 1606 1606 .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR }, 1607 1607 .size = 0x200, 1608 - .read = pccard_show_cis, 1609 - .write = pccard_store_cis, 1608 + .read_new = pccard_show_cis, 1609 + .write_new = pccard_store_cis, 1610 1610 };
+7 -7
drivers/rapidio/rio-sysfs.c
··· 114 114 115 115 static ssize_t 116 116 rio_read_config(struct file *filp, struct kobject *kobj, 117 - struct bin_attribute *bin_attr, 117 + const struct bin_attribute *bin_attr, 118 118 char *buf, loff_t off, size_t count) 119 119 { 120 120 struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj)); ··· 185 185 186 186 static ssize_t 187 187 rio_write_config(struct file *filp, struct kobject *kobj, 188 - struct bin_attribute *bin_attr, 188 + const struct bin_attribute *bin_attr, 189 189 char *buf, loff_t off, size_t count) 190 190 { 191 191 struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj)); ··· 241 241 return count; 242 242 } 243 243 244 - static struct bin_attribute rio_config_attr = { 244 + static const struct bin_attribute rio_config_attr = { 245 245 .attr = { 246 246 .name = "config", 247 247 .mode = S_IRUGO | S_IWUSR, 248 248 }, 249 249 .size = RIO_MAINT_SPACE_SZ, 250 - .read = rio_read_config, 251 - .write = rio_write_config, 250 + .read_new = rio_read_config, 251 + .write_new = rio_write_config, 252 252 }; 253 253 254 - static struct bin_attribute *rio_dev_bin_attrs[] = { 254 + static const struct bin_attribute *const rio_dev_bin_attrs[] = { 255 255 &rio_config_attr, 256 256 NULL, 257 257 }; ··· 278 278 static const struct attribute_group rio_dev_group = { 279 279 .attrs = rio_dev_attrs, 280 280 .is_visible = rio_dev_is_attr_visible, 281 - .bin_attrs = rio_dev_bin_attrs, 281 + .bin_attrs_new = rio_dev_bin_attrs, 282 282 }; 283 283 284 284 const struct attribute_group *rio_dev_groups[] = {
+123 -88
fs/kernfs/dir.c
··· 17 17 18 18 #include "kernfs-internal.h" 19 19 20 - static DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */ 20 + DEFINE_RWLOCK(kernfs_rename_lock); /* kn->parent and ->name */ 21 21 /* 22 22 * Don't use rename_lock to piggy back on pr_cont_buf. We don't want to 23 23 * call pr_cont() while holding rename_lock. Because sometimes pr_cont() ··· 51 51 #endif 52 52 } 53 53 54 - static int kernfs_name_locked(struct kernfs_node *kn, char *buf, size_t buflen) 55 - { 56 - if (!kn) 57 - return strscpy(buf, "(null)", buflen); 58 - 59 - return strscpy(buf, kn->parent ? kn->name : "/", buflen); 60 - } 61 - 62 54 /* kernfs_node_depth - compute depth from @from to @to */ 63 55 static size_t kernfs_depth(struct kernfs_node *from, struct kernfs_node *to) 64 56 { 65 57 size_t depth = 0; 66 58 67 - while (to->parent && to != from) { 59 + while (rcu_dereference(to->__parent) && to != from) { 68 60 depth++; 69 - to = to->parent; 61 + to = rcu_dereference(to->__parent); 70 62 } 71 63 return depth; 72 64 } ··· 76 84 db = kernfs_depth(rb->kn, b); 77 85 78 86 while (da > db) { 79 - a = a->parent; 87 + a = rcu_dereference(a->__parent); 80 88 da--; 81 89 } 82 90 while (db > da) { 83 - b = b->parent; 91 + b = rcu_dereference(b->__parent); 84 92 db--; 85 93 } 86 94 87 95 /* worst case b and a will be the same at root */ 88 96 while (b != a) { 89 - b = b->parent; 90 - a = a->parent; 97 + b = rcu_dereference(b->__parent); 98 + a = rcu_dereference(a->__parent); 91 99 } 92 100 93 101 return a; ··· 160 168 161 169 /* Calculate how many bytes we need for the rest */ 162 170 for (i = depth_to - 1; i >= 0; i--) { 163 - for (kn = kn_to, j = 0; j < i; j++) 164 - kn = kn->parent; 171 + const char *name; 165 172 166 - len += scnprintf(buf + len, buflen - len, "/%s", kn->name); 173 + for (kn = kn_to, j = 0; j < i; j++) 174 + kn = rcu_dereference(kn->__parent); 175 + 176 + name = rcu_dereference(kn->name); 177 + len += scnprintf(buf + len, buflen - len, "/%s", name); 167 178 } 168 179 169 180 return len; ··· 190 195 */ 191 196 int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen) 192 197 { 193 - unsigned long flags; 194 - int ret; 198 + struct kernfs_node *kn_parent; 195 199 196 - read_lock_irqsave(&kernfs_rename_lock, flags); 197 - ret = kernfs_name_locked(kn, buf, buflen); 198 - read_unlock_irqrestore(&kernfs_rename_lock, flags); 199 - return ret; 200 + if (!kn) 201 + return strscpy(buf, "(null)", buflen); 202 + 203 + guard(rcu)(); 204 + /* 205 + * KERNFS_ROOT_INVARIANT_PARENT is ignored here. The name is RCU freed and 206 + * the parent is either existing or not. 207 + */ 208 + kn_parent = rcu_dereference(kn->__parent); 209 + return strscpy(buf, kn_parent ? rcu_dereference(kn->name) : "/", buflen); 200 210 } 201 211 202 212 /** ··· 223 223 int kernfs_path_from_node(struct kernfs_node *to, struct kernfs_node *from, 224 224 char *buf, size_t buflen) 225 225 { 226 - unsigned long flags; 227 - int ret; 226 + struct kernfs_root *root; 228 227 229 - read_lock_irqsave(&kernfs_rename_lock, flags); 230 - ret = kernfs_path_from_node_locked(to, from, buf, buflen); 231 - read_unlock_irqrestore(&kernfs_rename_lock, flags); 232 - return ret; 228 + guard(rcu)(); 229 + if (to) { 230 + root = kernfs_root(to); 231 + if (!(root->flags & KERNFS_ROOT_INVARIANT_PARENT)) { 232 + guard(read_lock_irqsave)(&kernfs_rename_lock); 233 + return kernfs_path_from_node_locked(to, from, buf, buflen); 234 + } 235 + } 236 + return kernfs_path_from_node_locked(to, from, buf, buflen); 233 237 } 234 238 EXPORT_SYMBOL_GPL(kernfs_path_from_node); 235 239 ··· 299 295 unsigned long flags; 300 296 301 297 read_lock_irqsave(&kernfs_rename_lock, flags); 302 - parent = kn->parent; 298 + parent = kernfs_parent(kn); 303 299 kernfs_get(parent); 304 300 read_unlock_irqrestore(&kernfs_rename_lock, flags); 305 301 ··· 340 336 return -1; 341 337 if (ns > kn->ns) 342 338 return 1; 343 - return strcmp(name, kn->name); 339 + return strcmp(name, kernfs_rcu_name(kn)); 344 340 } 345 341 346 342 static int kernfs_sd_compare(const struct kernfs_node *left, 347 343 const struct kernfs_node *right) 348 344 { 349 - return kernfs_name_compare(left->hash, left->name, left->ns, right); 345 + return kernfs_name_compare(left->hash, kernfs_rcu_name(left), left->ns, right); 350 346 } 351 347 352 348 /** ··· 364 360 */ 365 361 static int kernfs_link_sibling(struct kernfs_node *kn) 366 362 { 367 - struct rb_node **node = &kn->parent->dir.children.rb_node; 368 363 struct rb_node *parent = NULL; 364 + struct kernfs_node *kn_parent; 365 + struct rb_node **node; 366 + 367 + kn_parent = kernfs_parent(kn); 368 + node = &kn_parent->dir.children.rb_node; 369 369 370 370 while (*node) { 371 371 struct kernfs_node *pos; ··· 388 380 389 381 /* add new node and rebalance the tree */ 390 382 rb_link_node(&kn->rb, parent, node); 391 - rb_insert_color(&kn->rb, &kn->parent->dir.children); 383 + rb_insert_color(&kn->rb, &kn_parent->dir.children); 392 384 393 385 /* successfully added, account subdir number */ 394 386 down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); 395 387 if (kernfs_type(kn) == KERNFS_DIR) 396 - kn->parent->dir.subdirs++; 397 - kernfs_inc_rev(kn->parent); 388 + kn_parent->dir.subdirs++; 389 + kernfs_inc_rev(kn_parent); 398 390 up_write(&kernfs_root(kn)->kernfs_iattr_rwsem); 399 391 400 392 return 0; ··· 415 407 */ 416 408 static bool kernfs_unlink_sibling(struct kernfs_node *kn) 417 409 { 410 + struct kernfs_node *kn_parent; 411 + 418 412 if (RB_EMPTY_NODE(&kn->rb)) 419 413 return false; 420 414 415 + kn_parent = kernfs_parent(kn); 421 416 down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); 422 417 if (kernfs_type(kn) == KERNFS_DIR) 423 - kn->parent->dir.subdirs--; 424 - kernfs_inc_rev(kn->parent); 418 + kn_parent->dir.subdirs--; 419 + kernfs_inc_rev(kn_parent); 425 420 up_write(&kernfs_root(kn)->kernfs_iattr_rwsem); 426 421 427 - rb_erase(&kn->rb, &kn->parent->dir.children); 422 + rb_erase(&kn->rb, &kn_parent->dir.children); 428 423 RB_CLEAR_NODE(&kn->rb); 429 424 return true; 430 425 } ··· 544 533 { 545 534 struct kernfs_node *kn = container_of(rcu, struct kernfs_node, rcu); 546 535 547 - kfree_const(kn->name); 536 + /* If the whole node goes away, then name can't be used outside */ 537 + kfree_const(rcu_access_pointer(kn->name)); 548 538 549 539 if (kn->iattr) { 550 540 simple_xattrs_free(&kn->iattr->xattrs, NULL); ··· 574 562 * Moving/renaming is always done while holding reference. 575 563 * kn->parent won't change beneath us. 576 564 */ 577 - parent = kn->parent; 565 + parent = kernfs_parent(kn); 578 566 579 567 WARN_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS, 580 568 "kernfs_put: %s/%s: released with incorrect active_ref %d\n", 581 - parent ? parent->name : "", kn->name, atomic_read(&kn->active)); 569 + parent ? rcu_dereference(parent->name) : "", 570 + rcu_dereference(kn->name), atomic_read(&kn->active)); 582 571 583 572 if (kernfs_type(kn) == KERNFS_LINK) 584 573 kernfs_put(kn->symlink.target_kn); ··· 656 643 atomic_set(&kn->active, KN_DEACTIVATED_BIAS); 657 644 RB_CLEAR_NODE(&kn->rb); 658 645 659 - kn->name = name; 646 + rcu_assign_pointer(kn->name, name); 660 647 kn->mode = mode; 661 648 kn->flags = flags; 662 649 ··· 714 701 name, mode, uid, gid, flags); 715 702 if (kn) { 716 703 kernfs_get(parent); 717 - kn->parent = parent; 704 + rcu_assign_pointer(kn->__parent, parent); 718 705 } 719 706 return kn; 720 707 } ··· 782 769 */ 783 770 int kernfs_add_one(struct kernfs_node *kn) 784 771 { 785 - struct kernfs_node *parent = kn->parent; 786 - struct kernfs_root *root = kernfs_root(parent); 772 + struct kernfs_root *root = kernfs_root(kn); 787 773 struct kernfs_iattrs *ps_iattr; 774 + struct kernfs_node *parent; 788 775 bool has_ns; 789 776 int ret; 790 777 791 778 down_write(&root->kernfs_rwsem); 779 + parent = kernfs_parent(kn); 792 780 793 781 ret = -EINVAL; 794 782 has_ns = kernfs_ns_enabled(parent); 795 783 if (WARN(has_ns != (bool)kn->ns, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", 796 - has_ns ? "required" : "invalid", parent->name, kn->name)) 784 + has_ns ? "required" : "invalid", 785 + kernfs_rcu_name(parent), kernfs_rcu_name(kn))) 797 786 goto out_unlock; 798 787 799 788 if (kernfs_type(parent) != KERNFS_DIR) ··· 805 790 if (parent->flags & (KERNFS_REMOVING | KERNFS_EMPTY_DIR)) 806 791 goto out_unlock; 807 792 808 - kn->hash = kernfs_name_hash(kn->name, kn->ns); 793 + kn->hash = kernfs_name_hash(kernfs_rcu_name(kn), kn->ns); 809 794 810 795 ret = kernfs_link_sibling(kn); 811 796 if (ret) ··· 861 846 862 847 if (has_ns != (bool)ns) { 863 848 WARN(1, KERN_WARNING "kernfs: ns %s in '%s' for '%s'\n", 864 - has_ns ? "required" : "invalid", parent->name, name); 849 + has_ns ? "required" : "invalid", kernfs_rcu_name(parent), name); 865 850 return NULL; 866 851 } 867 852 ··· 962 947 up_read(&root->kernfs_rwsem); 963 948 964 949 return kn; 950 + } 951 + 952 + unsigned int kernfs_root_flags(struct kernfs_node *kn) 953 + { 954 + return kernfs_root(kn)->flags; 965 955 } 966 956 967 957 /** ··· 1132 1112 static int kernfs_dop_revalidate(struct inode *dir, const struct qstr *name, 1133 1113 struct dentry *dentry, unsigned int flags) 1134 1114 { 1135 - struct kernfs_node *kn; 1115 + struct kernfs_node *kn, *parent; 1136 1116 struct kernfs_root *root; 1137 1117 1138 1118 if (flags & LOOKUP_RCU) ··· 1140 1120 1141 1121 /* Negative hashed dentry? */ 1142 1122 if (d_really_is_negative(dentry)) { 1143 - struct kernfs_node *parent; 1144 - 1145 1123 /* If the kernfs parent node has changed discard and 1146 1124 * proceed to ->lookup. 1147 1125 * ··· 1181 1163 if (!kernfs_active(kn)) 1182 1164 goto out_bad; 1183 1165 1166 + parent = kernfs_parent(kn); 1184 1167 /* The kernfs node has been moved? */ 1185 - if (kernfs_dentry_node(dentry->d_parent) != kn->parent) 1168 + if (kernfs_dentry_node(dentry->d_parent) != parent) 1186 1169 goto out_bad; 1187 1170 1188 1171 /* The kernfs node has been renamed */ 1189 - if (strcmp(dentry->d_name.name, kn->name) != 0) 1172 + if (strcmp(dentry->d_name.name, kernfs_rcu_name(kn)) != 0) 1190 1173 goto out_bad; 1191 1174 1192 1175 /* The kernfs node has been moved to a different namespace */ 1193 - if (kn->parent && kernfs_ns_enabled(kn->parent) && 1176 + if (parent && kernfs_ns_enabled(parent) && 1194 1177 kernfs_info(dentry->d_sb)->ns != kn->ns) 1195 1178 goto out_bad; 1196 1179 ··· 1384 1365 return kernfs_leftmost_descendant(rb_to_kn(rbn)); 1385 1366 1386 1367 /* no sibling left, visit parent */ 1387 - return pos->parent; 1368 + return kernfs_parent(pos); 1388 1369 } 1389 1370 1390 1371 static void kernfs_activate_one(struct kernfs_node *kn) ··· 1396 1377 if (kernfs_active(kn) || (kn->flags & (KERNFS_HIDDEN | KERNFS_REMOVING))) 1397 1378 return; 1398 1379 1399 - WARN_ON_ONCE(kn->parent && RB_EMPTY_NODE(&kn->rb)); 1380 + WARN_ON_ONCE(rcu_access_pointer(kn->__parent) && RB_EMPTY_NODE(&kn->rb)); 1400 1381 WARN_ON_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS); 1401 1382 1402 1383 atomic_sub(KN_DEACTIVATED_BIAS, &kn->active); ··· 1466 1447 1467 1448 static void __kernfs_remove(struct kernfs_node *kn) 1468 1449 { 1469 - struct kernfs_node *pos; 1450 + struct kernfs_node *pos, *parent; 1470 1451 1471 1452 /* Short-circuit if non-root @kn has already finished removal. */ 1472 1453 if (!kn) ··· 1478 1459 * This is for kernfs_remove_self() which plays with active ref 1479 1460 * after removal. 1480 1461 */ 1481 - if (kn->parent && RB_EMPTY_NODE(&kn->rb)) 1462 + if (kernfs_parent(kn) && RB_EMPTY_NODE(&kn->rb)) 1482 1463 return; 1483 1464 1484 - pr_debug("kernfs %s: removing\n", kn->name); 1465 + pr_debug("kernfs %s: removing\n", kernfs_rcu_name(kn)); 1485 1466 1486 1467 /* prevent new usage by marking all nodes removing and deactivating */ 1487 1468 pos = NULL; ··· 1504 1485 kernfs_get(pos); 1505 1486 1506 1487 kernfs_drain(pos); 1507 - 1488 + parent = kernfs_parent(pos); 1508 1489 /* 1509 1490 * kernfs_unlink_sibling() succeeds once per node. Use it 1510 1491 * to decide who's responsible for cleanups. 1511 1492 */ 1512 - if (!pos->parent || kernfs_unlink_sibling(pos)) { 1493 + if (!parent || kernfs_unlink_sibling(pos)) { 1513 1494 struct kernfs_iattrs *ps_iattr = 1514 - pos->parent ? pos->parent->iattr : NULL; 1495 + parent ? parent->iattr : NULL; 1515 1496 1516 1497 /* update timestamps on the parent */ 1517 1498 down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); ··· 1737 1718 { 1738 1719 struct kernfs_node *old_parent; 1739 1720 struct kernfs_root *root; 1740 - const char *old_name = NULL; 1721 + const char *old_name; 1741 1722 int error; 1742 1723 1743 1724 /* can't move or rename root */ 1744 - if (!kn->parent) 1725 + if (!rcu_access_pointer(kn->__parent)) 1745 1726 return -EINVAL; 1746 1727 1747 1728 root = kernfs_root(kn); ··· 1752 1733 (new_parent->flags & KERNFS_EMPTY_DIR)) 1753 1734 goto out; 1754 1735 1736 + old_parent = kernfs_parent(kn); 1737 + if (root->flags & KERNFS_ROOT_INVARIANT_PARENT) { 1738 + error = -EINVAL; 1739 + if (WARN_ON_ONCE(old_parent != new_parent)) 1740 + goto out; 1741 + } 1742 + 1755 1743 error = 0; 1756 - if ((kn->parent == new_parent) && (kn->ns == new_ns) && 1757 - (strcmp(kn->name, new_name) == 0)) 1744 + old_name = kernfs_rcu_name(kn); 1745 + if (!new_name) 1746 + new_name = old_name; 1747 + if ((old_parent == new_parent) && (kn->ns == new_ns) && 1748 + (strcmp(old_name, new_name) == 0)) 1758 1749 goto out; /* nothing to rename */ 1759 1750 1760 1751 error = -EEXIST; ··· 1772 1743 goto out; 1773 1744 1774 1745 /* rename kernfs_node */ 1775 - if (strcmp(kn->name, new_name) != 0) { 1746 + if (strcmp(old_name, new_name) != 0) { 1776 1747 error = -ENOMEM; 1777 1748 new_name = kstrdup_const(new_name, GFP_KERNEL); 1778 1749 if (!new_name) ··· 1785 1756 * Move to the appropriate place in the appropriate directories rbtree. 1786 1757 */ 1787 1758 kernfs_unlink_sibling(kn); 1788 - kernfs_get(new_parent); 1789 1759 1790 - /* rename_lock protects ->parent and ->name accessors */ 1791 - write_lock_irq(&kernfs_rename_lock); 1760 + /* rename_lock protects ->parent accessors */ 1761 + if (old_parent != new_parent) { 1762 + kernfs_get(new_parent); 1763 + write_lock_irq(&kernfs_rename_lock); 1792 1764 1793 - old_parent = kn->parent; 1794 - kn->parent = new_parent; 1765 + rcu_assign_pointer(kn->__parent, new_parent); 1795 1766 1796 - kn->ns = new_ns; 1797 - if (new_name) { 1798 - old_name = kn->name; 1799 - kn->name = new_name; 1767 + kn->ns = new_ns; 1768 + if (new_name) 1769 + rcu_assign_pointer(kn->name, new_name); 1770 + 1771 + write_unlock_irq(&kernfs_rename_lock); 1772 + kernfs_put(old_parent); 1773 + } else { 1774 + /* name assignment is RCU protected, parent is the same */ 1775 + kn->ns = new_ns; 1776 + if (new_name) 1777 + rcu_assign_pointer(kn->name, new_name); 1800 1778 } 1801 1779 1802 - write_unlock_irq(&kernfs_rename_lock); 1803 - 1804 - kn->hash = kernfs_name_hash(kn->name, kn->ns); 1780 + kn->hash = kernfs_name_hash(new_name ?: old_name, kn->ns); 1805 1781 kernfs_link_sibling(kn); 1806 1782 1807 - kernfs_put(old_parent); 1808 - kfree_const(old_name); 1783 + if (new_name && !is_kernel_rodata((unsigned long)old_name)) 1784 + kfree_rcu_mightsleep(old_name); 1809 1785 1810 1786 error = 0; 1811 1787 out: ··· 1829 1795 { 1830 1796 if (pos) { 1831 1797 int valid = kernfs_active(pos) && 1832 - pos->parent == parent && hash == pos->hash; 1798 + rcu_access_pointer(pos->__parent) == parent && 1799 + hash == pos->hash; 1833 1800 kernfs_put(pos); 1834 1801 if (!valid) 1835 1802 pos = NULL; ··· 1895 1860 for (pos = kernfs_dir_pos(ns, parent, ctx->pos, pos); 1896 1861 pos; 1897 1862 pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos)) { 1898 - const char *name = pos->name; 1863 + const char *name = kernfs_rcu_name(pos); 1899 1864 unsigned int type = fs_umode_to_dtype(pos->mode); 1900 1865 int len = strlen(name); 1901 1866 ino_t ino = kernfs_ino(pos); ··· 1904 1869 file->private_data = pos; 1905 1870 kernfs_get(pos); 1906 1871 1907 - up_read(&root->kernfs_rwsem); 1908 - if (!dir_emit(ctx, name, len, ino, type)) 1872 + if (!dir_emit(ctx, name, len, ino, type)) { 1873 + up_read(&root->kernfs_rwsem); 1909 1874 return 0; 1910 - down_read(&root->kernfs_rwsem); 1875 + } 1911 1876 } 1912 1877 up_read(&root->kernfs_rwsem); 1913 1878 file->private_data = NULL;
+5 -1
fs/kernfs/file.c
··· 911 911 /* kick fsnotify */ 912 912 913 913 down_read(&root->kernfs_supers_rwsem); 914 + down_read(&root->kernfs_rwsem); 914 915 list_for_each_entry(info, &kernfs_root(kn)->supers, node) { 915 916 struct kernfs_node *parent; 916 917 struct inode *p_inode = NULL; 918 + const char *kn_name; 917 919 struct inode *inode; 918 920 struct qstr name; 919 921 ··· 929 927 if (!inode) 930 928 continue; 931 929 932 - name = QSTR(kn->name); 930 + kn_name = kernfs_rcu_name(kn); 931 + name = QSTR(kn_name); 933 932 parent = kernfs_get_parent(kn); 934 933 if (parent) { 935 934 p_inode = ilookup(info->sb, kernfs_ino(parent)); ··· 950 947 iput(inode); 951 948 } 952 949 950 + up_read(&root->kernfs_rwsem); 953 951 up_read(&root->kernfs_supers_rwsem); 954 952 kernfs_put(kn); 955 953 goto repeat;
+34 -3
fs/kernfs/kernfs-internal.h
··· 19 19 #include <linux/kernfs.h> 20 20 #include <linux/fs_context.h> 21 21 22 + extern rwlock_t kernfs_rename_lock; 23 + 22 24 struct kernfs_iattrs { 23 25 kuid_t ia_uid; 24 26 kgid_t ia_gid; ··· 66 64 * 67 65 * Return: the kernfs_root @kn belongs to. 68 66 */ 69 - static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) 67 + static inline struct kernfs_root *kernfs_root(const struct kernfs_node *kn) 70 68 { 69 + const struct kernfs_node *knp; 71 70 /* if parent exists, it's always a dir; otherwise, @sd is a dir */ 72 - if (kn->parent) 73 - kn = kn->parent; 71 + guard(rcu)(); 72 + knp = rcu_dereference(kn->__parent); 73 + if (knp) 74 + kn = knp; 74 75 return kn->dir.root; 75 76 } 76 77 ··· 101 96 struct list_head node; 102 97 }; 103 98 #define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) 99 + 100 + static inline bool kernfs_root_is_locked(const struct kernfs_node *kn) 101 + { 102 + return lockdep_is_held(&kernfs_root(kn)->kernfs_rwsem); 103 + } 104 + 105 + static inline const char *kernfs_rcu_name(const struct kernfs_node *kn) 106 + { 107 + return rcu_dereference_check(kn->name, kernfs_root_is_locked(kn)); 108 + } 109 + 110 + static inline struct kernfs_node *kernfs_parent(const struct kernfs_node *kn) 111 + { 112 + /* 113 + * The kernfs_node::__parent remains valid within a RCU section. The kn 114 + * can be reparented (and renamed) which changes the entry. This can be 115 + * avoided by locking kernfs_root::kernfs_rwsem or kernfs_rename_lock. 116 + * Both locks can be used to obtain a reference on __parent. Once the 117 + * reference count reaches 0 then the node is about to be freed 118 + * and can not be renamed (or become a different parent) anymore. 119 + */ 120 + return rcu_dereference_check(kn->__parent, 121 + kernfs_root_is_locked(kn) || 122 + lockdep_is_held(&kernfs_rename_lock) || 123 + !atomic_read(&kn->count)); 124 + } 104 125 105 126 static inline struct kernfs_node *kernfs_dentry_node(struct dentry *dentry) 106 127 {
+34 -12
fs/kernfs/mount.c
··· 145 145 static struct dentry *kernfs_get_parent_dentry(struct dentry *child) 146 146 { 147 147 struct kernfs_node *kn = kernfs_dentry_node(child); 148 + struct kernfs_root *root = kernfs_root(kn); 148 149 149 - return d_obtain_alias(kernfs_get_inode(child->d_sb, kn->parent)); 150 + guard(rwsem_read)(&root->kernfs_rwsem); 151 + return d_obtain_alias(kernfs_get_inode(child->d_sb, kernfs_parent(kn))); 150 152 } 151 153 152 154 static const struct export_operations kernfs_export_ops = { ··· 188 186 return NULL; 189 187 } 190 188 191 - while (child->parent != parent) { 192 - if (!child->parent) 189 + while (kernfs_parent(child) != parent) { 190 + child = kernfs_parent(child); 191 + if (!child) 193 192 return NULL; 194 - child = child->parent; 195 193 } 196 194 197 195 return child; ··· 209 207 { 210 208 struct dentry *dentry; 211 209 struct kernfs_node *knparent; 210 + struct kernfs_root *root; 212 211 213 212 BUG_ON(sb->s_op != &kernfs_sops); 214 213 215 214 dentry = dget(sb->s_root); 216 215 217 216 /* Check if this is the root kernfs_node */ 218 - if (!kn->parent) 217 + if (!rcu_access_pointer(kn->__parent)) 219 218 return dentry; 220 219 221 - knparent = find_next_ancestor(kn, NULL); 220 + root = kernfs_root(kn); 221 + /* 222 + * As long as kn is valid, its parent can not vanish. This is cgroup's 223 + * kn so it can't have its parent replaced. Therefore it is safe to use 224 + * the ancestor node outside of the RCU or locked section. 225 + */ 226 + if (WARN_ON_ONCE(!(root->flags & KERNFS_ROOT_INVARIANT_PARENT))) 227 + return ERR_PTR(-EINVAL); 228 + scoped_guard(rcu) { 229 + knparent = find_next_ancestor(kn, NULL); 230 + } 222 231 if (WARN_ON(!knparent)) { 223 232 dput(dentry); 224 233 return ERR_PTR(-EINVAL); ··· 238 225 do { 239 226 struct dentry *dtmp; 240 227 struct kernfs_node *kntmp; 228 + const char *name; 241 229 242 230 if (kn == knparent) 243 231 return dentry; 244 - kntmp = find_next_ancestor(kn, knparent); 245 - if (WARN_ON(!kntmp)) { 246 - dput(dentry); 247 - return ERR_PTR(-EINVAL); 232 + 233 + scoped_guard(rwsem_read, &root->kernfs_rwsem) { 234 + kntmp = find_next_ancestor(kn, knparent); 235 + if (WARN_ON(!kntmp)) { 236 + dput(dentry); 237 + return ERR_PTR(-EINVAL); 238 + } 239 + name = kstrdup(kernfs_rcu_name(kntmp), GFP_KERNEL); 248 240 } 249 - dtmp = lookup_positive_unlocked(kntmp->name, dentry, 250 - strlen(kntmp->name)); 241 + if (!name) { 242 + dput(dentry); 243 + return ERR_PTR(-ENOMEM); 244 + } 245 + dtmp = lookup_positive_unlocked(name, dentry, strlen(name)); 251 246 dput(dentry); 247 + kfree(name); 252 248 if (IS_ERR(dtmp)) 253 249 return dtmp; 254 250 knparent = kntmp;
+16 -14
fs/kernfs/symlink.c
··· 62 62 63 63 /* go up to the root, stop at the base */ 64 64 base = parent; 65 - while (base->parent) { 66 - kn = target->parent; 67 - while (kn->parent && base != kn) 68 - kn = kn->parent; 65 + while (kernfs_parent(base)) { 66 + kn = kernfs_parent(target); 67 + while (kernfs_parent(kn) && base != kn) 68 + kn = kernfs_parent(kn); 69 69 70 70 if (base == kn) 71 71 break; ··· 75 75 76 76 strcpy(s, "../"); 77 77 s += 3; 78 - base = base->parent; 78 + base = kernfs_parent(base); 79 79 } 80 80 81 81 /* determine end of target string for reverse fillup */ 82 82 kn = target; 83 - while (kn->parent && kn != base) { 84 - len += strlen(kn->name) + 1; 85 - kn = kn->parent; 83 + while (kernfs_parent(kn) && kn != base) { 84 + len += strlen(kernfs_rcu_name(kn)) + 1; 85 + kn = kernfs_parent(kn); 86 86 } 87 87 88 88 /* check limits */ ··· 94 94 95 95 /* reverse fillup of target string from target to base */ 96 96 kn = target; 97 - while (kn->parent && kn != base) { 98 - int slen = strlen(kn->name); 97 + while (kernfs_parent(kn) && kn != base) { 98 + const char *name = kernfs_rcu_name(kn); 99 + int slen = strlen(name); 99 100 100 101 len -= slen; 101 - memcpy(s + len, kn->name, slen); 102 + memcpy(s + len, name, slen); 102 103 if (len) 103 104 s[--len] = '/'; 104 105 105 - kn = kn->parent; 106 + kn = kernfs_parent(kn); 106 107 } 107 108 108 109 return 0; ··· 112 111 static int kernfs_getlink(struct inode *inode, char *path) 113 112 { 114 113 struct kernfs_node *kn = inode->i_private; 115 - struct kernfs_node *parent = kn->parent; 114 + struct kernfs_node *parent; 116 115 struct kernfs_node *target = kn->symlink.target_kn; 117 - struct kernfs_root *root = kernfs_root(parent); 116 + struct kernfs_root *root = kernfs_root(kn); 118 117 int error; 119 118 120 119 down_read(&root->kernfs_rwsem); 120 + parent = kernfs_parent(kn); 121 121 error = kernfs_get_target_path(parent, target, path); 122 122 up_read(&root->kernfs_rwsem); 123 123
+1 -1
fs/sysfs/dir.c
··· 123 123 new_parent = new_parent_kobj && new_parent_kobj->sd ? 124 124 new_parent_kobj->sd : sysfs_root_kn; 125 125 126 - return kernfs_rename_ns(kn, new_parent, kn->name, new_ns); 126 + return kernfs_rename_ns(kn, new_parent, NULL, new_ns); 127 127 } 128 128 129 129 /**
+15 -9
fs/sysfs/file.c
··· 19 19 20 20 #include "sysfs.h" 21 21 22 + static struct kobject *sysfs_file_kobj(struct kernfs_node *kn) 23 + { 24 + guard(rcu)(); 25 + return rcu_dereference(kn->__parent)->priv; 26 + } 27 + 22 28 /* 23 29 * Determine ktype->sysfs_ops for the given kernfs_node. This function 24 30 * must be called while holding an active reference. 25 31 */ 26 32 static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) 27 33 { 28 - struct kobject *kobj = kn->parent->priv; 34 + struct kobject *kobj = sysfs_file_kobj(kn); 29 35 30 36 if (kn->flags & KERNFS_LOCKDEP) 31 37 lockdep_assert_held(kn); ··· 46 40 static int sysfs_kf_seq_show(struct seq_file *sf, void *v) 47 41 { 48 42 struct kernfs_open_file *of = sf->private; 49 - struct kobject *kobj = of->kn->parent->priv; 43 + struct kobject *kobj = sysfs_file_kobj(of->kn); 50 44 const struct sysfs_ops *ops = sysfs_file_ops(of->kn); 51 45 ssize_t count; 52 46 char *buf; ··· 84 78 size_t count, loff_t pos) 85 79 { 86 80 struct bin_attribute *battr = of->kn->priv; 87 - struct kobject *kobj = of->kn->parent->priv; 81 + struct kobject *kobj = sysfs_file_kobj(of->kn); 88 82 loff_t size = file_inode(of->file)->i_size; 89 83 90 84 if (!count) ··· 111 105 size_t count, loff_t pos) 112 106 { 113 107 const struct sysfs_ops *ops = sysfs_file_ops(of->kn); 114 - struct kobject *kobj = of->kn->parent->priv; 108 + struct kobject *kobj = sysfs_file_kobj(of->kn); 115 109 ssize_t len; 116 110 117 111 /* ··· 137 131 size_t count, loff_t pos) 138 132 { 139 133 const struct sysfs_ops *ops = sysfs_file_ops(of->kn); 140 - struct kobject *kobj = of->kn->parent->priv; 134 + struct kobject *kobj = sysfs_file_kobj(of->kn); 141 135 142 136 if (!count) 143 137 return 0; ··· 150 144 size_t count, loff_t pos) 151 145 { 152 146 struct bin_attribute *battr = of->kn->priv; 153 - struct kobject *kobj = of->kn->parent->priv; 147 + struct kobject *kobj = sysfs_file_kobj(of->kn); 154 148 loff_t size = file_inode(of->file)->i_size; 155 149 156 150 if (size) { ··· 174 168 struct vm_area_struct *vma) 175 169 { 176 170 struct bin_attribute *battr = of->kn->priv; 177 - struct kobject *kobj = of->kn->parent->priv; 171 + struct kobject *kobj = sysfs_file_kobj(of->kn); 178 172 179 173 return battr->mmap(of->file, kobj, battr, vma); 180 174 } ··· 183 177 int whence) 184 178 { 185 179 struct bin_attribute *battr = of->kn->priv; 186 - struct kobject *kobj = of->kn->parent->priv; 180 + struct kobject *kobj = sysfs_file_kobj(of->kn); 187 181 188 182 if (battr->llseek) 189 183 return battr->llseek(of->file, kobj, battr, offset, whence); ··· 500 494 */ 501 495 void sysfs_unbreak_active_protection(struct kernfs_node *kn) 502 496 { 503 - struct kobject *kobj = kn->parent->priv; 497 + struct kobject *kobj = sysfs_file_kobj(kn); 504 498 505 499 kernfs_unbreak_active_protection(kn); 506 500 kernfs_put(kn);
+1 -1
include/linux/device.h
··· 1162 1162 { 1163 1163 const struct attribute_group *groups[] = { grp, NULL }; 1164 1164 1165 - return device_remove_groups(dev, groups); 1165 + device_remove_groups(dev, groups); 1166 1166 } 1167 1167 1168 1168 int __must_check devm_device_add_group(struct device *dev,
+1 -1
include/linux/device/class.h
··· 193 193 static inline void class_remove_file(const struct class *class, 194 194 const struct class_attribute *attr) 195 195 { 196 - return class_remove_file_ns(class, attr, NULL); 196 + class_remove_file_ns(class, attr, NULL); 197 197 } 198 198 199 199 /* Simple class attribute that is just a static string */
+11 -3
include/linux/kernfs.h
··· 147 147 * Support user xattrs to be written to nodes rooted at this root. 148 148 */ 149 149 KERNFS_ROOT_SUPPORT_USER_XATTR = 0x0008, 150 + 151 + /* 152 + * Renames must not change the parent node. 153 + */ 154 + KERNFS_ROOT_INVARIANT_PARENT = 0x0010, 150 155 }; 151 156 152 157 /* type-specific structures for kernfs_node union members */ ··· 204 199 * never moved to a different parent, it is safe to access the 205 200 * parent directly. 206 201 */ 207 - struct kernfs_node *parent; 208 - const char *name; 202 + struct kernfs_node __rcu *__parent; 203 + const char __rcu *name; 209 204 210 205 struct rb_node rb; 211 206 ··· 400 395 } 401 396 402 397 int kernfs_name(struct kernfs_node *kn, char *buf, size_t buflen); 403 - int kernfs_path_from_node(struct kernfs_node *root_kn, struct kernfs_node *kn, 398 + int kernfs_path_from_node(struct kernfs_node *kn_to, struct kernfs_node *kn_from, 404 399 char *buf, size_t buflen); 405 400 void pr_cont_kernfs_name(struct kernfs_node *kn); 406 401 void pr_cont_kernfs_path(struct kernfs_node *kn); ··· 421 416 struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, 422 417 unsigned int flags, void *priv); 423 418 void kernfs_destroy_root(struct kernfs_root *root); 419 + unsigned int kernfs_root_flags(struct kernfs_node *kn); 424 420 425 421 struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, 426 422 const char *name, umode_t mode, ··· 520 514 { return ERR_PTR(-ENOSYS); } 521 515 522 516 static inline void kernfs_destroy_root(struct kernfs_root *root) { } 517 + static inline unsigned int kernfs_root_flags(struct kernfs_node *kn) 518 + { return 0; } 523 519 524 520 static inline struct kernfs_node * 525 521 kernfs_create_dir_ns(struct kernfs_node *parent, const char *name,
+1 -1
kernel/Kconfig.hz
··· 30 30 250 Hz is a good compromise choice allowing server performance 31 31 while also showing good interactive responsiveness even 32 32 on SMP and NUMA systems. If you are going to be using NTSC video 33 - or multimedia, selected 300Hz instead. 33 + or multimedia, select 300Hz instead. 34 34 35 35 config HZ_300 36 36 bool "300 HZ"
+1 -1
kernel/cgroup/cgroup-v1.c
··· 851 851 852 852 if (kernfs_type(kn) != KERNFS_DIR) 853 853 return -ENOTDIR; 854 - if (kn->parent != new_parent) 854 + if (rcu_access_pointer(kn->__parent) != new_parent) 855 855 return -EIO; 856 856 857 857 /*
+19 -5
kernel/cgroup/cgroup.c
··· 633 633 return count; 634 634 } 635 635 636 + static struct cgroup *kn_priv(struct kernfs_node *kn) 637 + { 638 + struct kernfs_node *parent; 639 + /* 640 + * The parent can not be replaced due to KERNFS_ROOT_INVARIANT_PARENT. 641 + * Therefore it is always safe to dereference this pointer outside of a 642 + * RCU section. 643 + */ 644 + parent = rcu_dereference_check(kn->__parent, 645 + kernfs_root_flags(kn) & KERNFS_ROOT_INVARIANT_PARENT); 646 + return parent->priv; 647 + } 648 + 636 649 struct cgroup_subsys_state *of_css(struct kernfs_open_file *of) 637 650 { 638 - struct cgroup *cgrp = of->kn->parent->priv; 651 + struct cgroup *cgrp = kn_priv(of->kn); 639 652 struct cftype *cft = of_cft(of); 640 653 641 654 /* ··· 1625 1612 if (kernfs_type(kn) == KERNFS_DIR) 1626 1613 cgrp = kn->priv; 1627 1614 else 1628 - cgrp = kn->parent->priv; 1615 + cgrp = kn_priv(kn); 1629 1616 1630 1617 cgroup_unlock(); 1631 1618 ··· 1657 1644 if (kernfs_type(kn) == KERNFS_DIR) 1658 1645 cgrp = kn->priv; 1659 1646 else 1660 - cgrp = kn->parent->priv; 1647 + cgrp = kn_priv(kn); 1661 1648 1662 1649 /* 1663 1650 * We're gonna grab cgroup_mutex which nests outside kernfs ··· 2131 2118 root->kf_root = kernfs_create_root(kf_sops, 2132 2119 KERNFS_ROOT_CREATE_DEACTIVATED | 2133 2120 KERNFS_ROOT_SUPPORT_EXPORTOP | 2134 - KERNFS_ROOT_SUPPORT_USER_XATTR, 2121 + KERNFS_ROOT_SUPPORT_USER_XATTR | 2122 + KERNFS_ROOT_INVARIANT_PARENT, 2135 2123 root_cgrp); 2136 2124 if (IS_ERR(root->kf_root)) { 2137 2125 ret = PTR_ERR(root->kf_root); ··· 4129 4115 size_t nbytes, loff_t off) 4130 4116 { 4131 4117 struct cgroup_file_ctx *ctx = of->priv; 4132 - struct cgroup *cgrp = of->kn->parent->priv; 4118 + struct cgroup *cgrp = kn_priv(of->kn); 4133 4119 struct cftype *cft = of_cft(of); 4134 4120 struct cgroup_subsys_state *css; 4135 4121 int ret;
+26
rust/kernel/device.rs
··· 209 209 // synchronization in `struct device`. 210 210 unsafe impl Sync for Device {} 211 211 212 + /// Marker trait for the context of a bus specific device. 213 + /// 214 + /// Some functions of a bus specific device should only be called from a certain context, i.e. bus 215 + /// callbacks, such as `probe()`. 216 + /// 217 + /// This is the marker trait for structures representing the context of a bus specific device. 218 + pub trait DeviceContext: private::Sealed {} 219 + 220 + /// The [`Normal`] context is the context of a bus specific device when it is not an argument of 221 + /// any bus callback. 222 + pub struct Normal; 223 + 224 + /// The [`Core`] context is the context of a bus specific device when it is supplied as argument of 225 + /// any of the bus callbacks, such as `probe()`. 226 + pub struct Core; 227 + 228 + mod private { 229 + pub trait Sealed {} 230 + 231 + impl Sealed for super::Core {} 232 + impl Sealed for super::Normal {} 233 + } 234 + 235 + impl DeviceContext for Core {} 236 + impl DeviceContext for Normal {} 237 + 212 238 #[doc(hidden)] 213 239 #[macro_export] 214 240 macro_rules! dev_printk {
+1 -1
rust/kernel/devres.rs
··· 92 92 /// let devres = Devres::new(&dev, iomem, GFP_KERNEL)?; 93 93 /// 94 94 /// let res = devres.try_access().ok_or(ENXIO)?; 95 - /// res.writel(0x42, 0x0); 95 + /// res.write8(0x42, 0x0); 96 96 /// # Ok(()) 97 97 /// # } 98 98 /// ```
+13 -3
rust/kernel/faux.rs
··· 19 19 /// `self.0` always holds a valid pointer to an initialized and registered [`struct faux_device`]. 20 20 /// 21 21 /// [`struct faux_device`]: srctree/include/linux/device/faux.h 22 - #[repr(transparent)] 23 22 pub struct Registration(NonNull<bindings::faux_device>); 24 23 25 24 impl Registration { 26 25 /// Create and register a new faux device with the given name. 27 - pub fn new(name: &CStr) -> Result<Self> { 26 + #[inline] 27 + pub fn new(name: &CStr, parent: Option<&device::Device>) -> Result<Self> { 28 28 // SAFETY: 29 29 // - `name` is copied by this function into its own storage 30 30 // - `faux_ops` is safe to leave NULL according to the C API 31 - let dev = unsafe { bindings::faux_device_create(name.as_char_ptr(), null_mut(), null()) }; 31 + // - `parent` can be either NULL or a pointer to a `struct device`, and `faux_device_create` 32 + // will take a reference to `parent` using `device_add` - ensuring that it remains valid 33 + // for the lifetime of the faux device. 34 + let dev = unsafe { 35 + bindings::faux_device_create( 36 + name.as_char_ptr(), 37 + parent.map_or(null_mut(), |p| p.as_raw()), 38 + null(), 39 + ) 40 + }; 32 41 33 42 // The above function will return either a valid device, or NULL on failure 34 43 // INVARIANT: The device will remain registered until faux_device_destroy() is called, which ··· 59 50 } 60 51 61 52 impl Drop for Registration { 53 + #[inline] 62 54 fn drop(&mut self) { 63 55 // SAFETY: `self.0` is a valid registered faux_device via our type invariants. 64 56 unsafe { bindings::faux_device_destroy(self.as_raw()) }
+33 -33
rust/kernel/io.rs
··· 98 98 ///# fn no_run() -> Result<(), Error> { 99 99 /// // SAFETY: Invalid usage for example purposes. 100 100 /// let iomem = unsafe { IoMem::<{ core::mem::size_of::<u32>() }>::new(0xBAAAAAAD)? }; 101 - /// iomem.writel(0x42, 0x0); 102 - /// assert!(iomem.try_writel(0x42, 0x0).is_ok()); 103 - /// assert!(iomem.try_writel(0x42, 0x4).is_err()); 101 + /// iomem.write32(0x42, 0x0); 102 + /// assert!(iomem.try_write32(0x42, 0x0).is_ok()); 103 + /// assert!(iomem.try_write32(0x42, 0x4).is_err()); 104 104 /// # Ok(()) 105 105 /// # } 106 106 /// ``` ··· 108 108 pub struct Io<const SIZE: usize = 0>(IoRaw<SIZE>); 109 109 110 110 macro_rules! define_read { 111 - ($(#[$attr:meta])* $name:ident, $try_name:ident, $type_name:ty) => { 111 + ($(#[$attr:meta])* $name:ident, $try_name:ident, $c_fn:ident -> $type_name:ty) => { 112 112 /// Read IO data from a given offset known at compile time. 113 113 /// 114 114 /// Bound checks are performed on compile time, hence if the offset is not known at compile ··· 119 119 let addr = self.io_addr_assert::<$type_name>(offset); 120 120 121 121 // SAFETY: By the type invariant `addr` is a valid address for MMIO operations. 122 - unsafe { bindings::$name(addr as _) } 122 + unsafe { bindings::$c_fn(addr as _) } 123 123 } 124 124 125 125 /// Read IO data from a given offset. ··· 131 131 let addr = self.io_addr::<$type_name>(offset)?; 132 132 133 133 // SAFETY: By the type invariant `addr` is a valid address for MMIO operations. 134 - Ok(unsafe { bindings::$name(addr as _) }) 134 + Ok(unsafe { bindings::$c_fn(addr as _) }) 135 135 } 136 136 }; 137 137 } 138 138 139 139 macro_rules! define_write { 140 - ($(#[$attr:meta])* $name:ident, $try_name:ident, $type_name:ty) => { 140 + ($(#[$attr:meta])* $name:ident, $try_name:ident, $c_fn:ident <- $type_name:ty) => { 141 141 /// Write IO data from a given offset known at compile time. 142 142 /// 143 143 /// Bound checks are performed on compile time, hence if the offset is not known at compile ··· 148 148 let addr = self.io_addr_assert::<$type_name>(offset); 149 149 150 150 // SAFETY: By the type invariant `addr` is a valid address for MMIO operations. 151 - unsafe { bindings::$name(value, addr as _, ) } 151 + unsafe { bindings::$c_fn(value, addr as _, ) } 152 152 } 153 153 154 154 /// Write IO data from a given offset. ··· 160 160 let addr = self.io_addr::<$type_name>(offset)?; 161 161 162 162 // SAFETY: By the type invariant `addr` is a valid address for MMIO operations. 163 - unsafe { bindings::$name(value, addr as _) } 163 + unsafe { bindings::$c_fn(value, addr as _) } 164 164 Ok(()) 165 165 } 166 166 }; ··· 218 218 self.addr() + offset 219 219 } 220 220 221 - define_read!(readb, try_readb, u8); 222 - define_read!(readw, try_readw, u16); 223 - define_read!(readl, try_readl, u32); 221 + define_read!(read8, try_read8, readb -> u8); 222 + define_read!(read16, try_read16, readw -> u16); 223 + define_read!(read32, try_read32, readl -> u32); 224 224 define_read!( 225 225 #[cfg(CONFIG_64BIT)] 226 - readq, 227 - try_readq, 228 - u64 226 + read64, 227 + try_read64, 228 + readq -> u64 229 229 ); 230 230 231 - define_read!(readb_relaxed, try_readb_relaxed, u8); 232 - define_read!(readw_relaxed, try_readw_relaxed, u16); 233 - define_read!(readl_relaxed, try_readl_relaxed, u32); 231 + define_read!(read8_relaxed, try_read8_relaxed, readb_relaxed -> u8); 232 + define_read!(read16_relaxed, try_read16_relaxed, readw_relaxed -> u16); 233 + define_read!(read32_relaxed, try_read32_relaxed, readl_relaxed -> u32); 234 234 define_read!( 235 235 #[cfg(CONFIG_64BIT)] 236 - readq_relaxed, 237 - try_readq_relaxed, 238 - u64 236 + read64_relaxed, 237 + try_read64_relaxed, 238 + readq_relaxed -> u64 239 239 ); 240 240 241 - define_write!(writeb, try_writeb, u8); 242 - define_write!(writew, try_writew, u16); 243 - define_write!(writel, try_writel, u32); 241 + define_write!(write8, try_write8, writeb <- u8); 242 + define_write!(write16, try_write16, writew <- u16); 243 + define_write!(write32, try_write32, writel <- u32); 244 244 define_write!( 245 245 #[cfg(CONFIG_64BIT)] 246 - writeq, 247 - try_writeq, 248 - u64 246 + write64, 247 + try_write64, 248 + writeq <- u64 249 249 ); 250 250 251 - define_write!(writeb_relaxed, try_writeb_relaxed, u8); 252 - define_write!(writew_relaxed, try_writew_relaxed, u16); 253 - define_write!(writel_relaxed, try_writel_relaxed, u32); 251 + define_write!(write8_relaxed, try_write8_relaxed, writeb_relaxed <- u8); 252 + define_write!(write16_relaxed, try_write16_relaxed, writew_relaxed <- u16); 253 + define_write!(write32_relaxed, try_write32_relaxed, writel_relaxed <- u32); 254 254 define_write!( 255 255 #[cfg(CONFIG_64BIT)] 256 - writeq_relaxed, 257 - try_writeq_relaxed, 258 - u64 256 + write64_relaxed, 257 + try_write64_relaxed, 258 + writeq_relaxed <- u64 259 259 ); 260 260 }
+95 -55
rust/kernel/pci.rs
··· 6 6 7 7 use crate::{ 8 8 alloc::flags::*, 9 - bindings, container_of, device, 9 + bindings, device, 10 10 device_id::RawDeviceId, 11 11 devres::Devres, 12 12 driver, ··· 17 17 types::{ARef, ForeignOwnable, Opaque}, 18 18 ThisModule, 19 19 }; 20 - use core::{ops::Deref, ptr::addr_of_mut}; 20 + use core::{ 21 + marker::PhantomData, 22 + ops::Deref, 23 + ptr::{addr_of_mut, NonNull}, 24 + }; 21 25 use kernel::prelude::*; 22 26 23 27 /// An adapter for the registration of PCI drivers. ··· 64 60 ) -> kernel::ffi::c_int { 65 61 // SAFETY: The PCI bus only ever calls the probe callback with a valid pointer to a 66 62 // `struct pci_dev`. 67 - let dev = unsafe { device::Device::get_device(addr_of_mut!((*pdev).dev)) }; 68 - // SAFETY: `dev` is guaranteed to be embedded in a valid `struct pci_dev` by the call 69 - // above. 70 - let mut pdev = unsafe { Device::from_dev(dev) }; 63 + // 64 + // INVARIANT: `pdev` is valid for the duration of `probe_callback()`. 65 + let pdev = unsafe { &*pdev.cast::<Device<device::Core>>() }; 71 66 72 67 // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct pci_device_id` and 73 68 // does not add additional invariants, so it's safe to transmute. 74 69 let id = unsafe { &*id.cast::<DeviceId>() }; 75 70 let info = T::ID_TABLE.info(id.index()); 76 71 77 - match T::probe(&mut pdev, info) { 72 + match T::probe(pdev, info) { 78 73 Ok(data) => { 79 74 // Let the `struct pci_dev` own a reference of the driver's private data. 80 75 // SAFETY: By the type invariant `pdev.as_raw` returns a valid pointer to a ··· 195 192 /// # Example 196 193 /// 197 194 ///``` 198 - /// # use kernel::{bindings, pci}; 195 + /// # use kernel::{bindings, device::Core, pci}; 199 196 /// 200 197 /// struct MyDriver; 201 198 /// ··· 213 210 /// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; 214 211 /// 215 212 /// fn probe( 216 - /// _pdev: &mut pci::Device, 213 + /// _pdev: &pci::Device<Core>, 217 214 /// _id_info: &Self::IdInfo, 218 215 /// ) -> Result<Pin<KBox<Self>>> { 219 216 /// Err(ENODEV) ··· 222 219 ///``` 223 220 /// Drivers must implement this trait in order to get a PCI driver registered. Please refer to the 224 221 /// `Adapter` documentation for an example. 225 - pub trait Driver { 222 + pub trait Driver: Send { 226 223 /// The type holding information about each device id supported by the driver. 227 224 /// 228 225 /// TODO: Use associated_type_defaults once stabilized: ··· 237 234 /// 238 235 /// Called when a new platform device is added or discovered. 239 236 /// Implementers should attempt to initialize the device here. 240 - fn probe(dev: &mut Device, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>; 237 + fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>; 241 238 } 242 239 243 240 /// The PCI device representation. 244 241 /// 245 - /// A PCI device is based on an always reference counted `device:Device` instance. Cloning a PCI 246 - /// device, hence, also increments the base device' reference count. 242 + /// This structure represents the Rust abstraction for a C `struct pci_dev`. The implementation 243 + /// abstracts the usage of an already existing C `struct pci_dev` within Rust code that we get 244 + /// passed from the C side. 247 245 /// 248 246 /// # Invariants 249 247 /// 250 - /// `Device` hold a valid reference of `ARef<device::Device>` whose underlying `struct device` is a 251 - /// member of a `struct pci_dev`. 252 - #[derive(Clone)] 253 - pub struct Device(ARef<device::Device>); 248 + /// A [`Device`] instance represents a valid `struct device` created by the C portion of the kernel. 249 + #[repr(transparent)] 250 + pub struct Device<Ctx: device::DeviceContext = device::Normal>( 251 + Opaque<bindings::pci_dev>, 252 + PhantomData<Ctx>, 253 + ); 254 254 255 255 /// A PCI BAR to perform I/O-Operations on. 256 256 /// ··· 262 256 /// `Bar` always holds an `IoRaw` inststance that holds a valid pointer to the start of the I/O 263 257 /// memory mapped PCI bar and its size. 264 258 pub struct Bar<const SIZE: usize = 0> { 265 - pdev: Device, 259 + pdev: ARef<Device>, 266 260 io: IoRaw<SIZE>, 267 261 num: i32, 268 262 } 269 263 270 264 impl<const SIZE: usize> Bar<SIZE> { 271 - fn new(pdev: Device, num: u32, name: &CStr) -> Result<Self> { 265 + fn new(pdev: &Device, num: u32, name: &CStr) -> Result<Self> { 272 266 let len = pdev.resource_len(num)?; 273 267 if len == 0 { 274 268 return Err(ENOMEM); ··· 306 300 // `pdev` is valid by the invariants of `Device`. 307 301 // `ioptr` is guaranteed to be the start of a valid I/O mapped memory region. 308 302 // `num` is checked for validity by a previous call to `Device::resource_len`. 309 - unsafe { Self::do_release(&pdev, ioptr, num) }; 303 + unsafe { Self::do_release(pdev, ioptr, num) }; 310 304 return Err(err); 311 305 } 312 306 }; 313 307 314 - Ok(Bar { pdev, io, num }) 308 + Ok(Bar { 309 + pdev: pdev.into(), 310 + io, 311 + num, 312 + }) 315 313 } 316 314 317 315 /// # Safety ··· 361 351 } 362 352 363 353 impl Device { 364 - /// Create a PCI Device instance from an existing `device::Device`. 365 - /// 366 - /// # Safety 367 - /// 368 - /// `dev` must be an `ARef<device::Device>` whose underlying `bindings::device` is a member of 369 - /// a `bindings::pci_dev`. 370 - pub unsafe fn from_dev(dev: ARef<device::Device>) -> Self { 371 - Self(dev) 372 - } 373 - 374 354 fn as_raw(&self) -> *mut bindings::pci_dev { 375 - // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` 376 - // embedded in `struct pci_dev`. 377 - unsafe { container_of!(self.0.as_raw(), bindings::pci_dev, dev) as _ } 355 + self.0.get() 378 356 } 379 357 380 358 /// Returns the PCI vendor ID. ··· 375 377 pub fn device_id(&self) -> u16 { 376 378 // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`. 377 379 unsafe { (*self.as_raw()).device } 378 - } 379 - 380 - /// Enable memory resources for this device. 381 - pub fn enable_device_mem(&self) -> Result { 382 - // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. 383 - let ret = unsafe { bindings::pci_enable_device_mem(self.as_raw()) }; 384 - if ret != 0 { 385 - Err(Error::from_errno(ret)) 386 - } else { 387 - Ok(()) 388 - } 389 - } 390 - 391 - /// Enable bus-mastering for this device. 392 - pub fn set_master(&self) { 393 - // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. 394 - unsafe { bindings::pci_set_master(self.as_raw()) }; 395 380 } 396 381 397 382 /// Returns the size of the given PCI bar resource. ··· 396 415 bar: u32, 397 416 name: &CStr, 398 417 ) -> Result<Devres<Bar<SIZE>>> { 399 - let bar = Bar::<SIZE>::new(self.clone(), bar, name)?; 418 + let bar = Bar::<SIZE>::new(self, bar, name)?; 400 419 let devres = Devres::new(self.as_ref(), bar, GFP_KERNEL)?; 401 420 402 421 Ok(devres) ··· 408 427 } 409 428 } 410 429 411 - impl AsRef<device::Device> for Device { 412 - fn as_ref(&self) -> &device::Device { 413 - &self.0 430 + impl Device<device::Core> { 431 + /// Enable memory resources for this device. 432 + pub fn enable_device_mem(&self) -> Result { 433 + // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. 434 + to_result(unsafe { bindings::pci_enable_device_mem(self.as_raw()) }) 435 + } 436 + 437 + /// Enable bus-mastering for this device. 438 + pub fn set_master(&self) { 439 + // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. 440 + unsafe { bindings::pci_set_master(self.as_raw()) }; 414 441 } 415 442 } 443 + 444 + impl Deref for Device<device::Core> { 445 + type Target = Device; 446 + 447 + fn deref(&self) -> &Self::Target { 448 + let ptr: *const Self = self; 449 + 450 + // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::pci_dev>`. 451 + let ptr = ptr.cast::<Device>(); 452 + 453 + // SAFETY: `ptr` was derived from `&self`. 454 + unsafe { &*ptr } 455 + } 456 + } 457 + 458 + impl From<&Device<device::Core>> for ARef<Device> { 459 + fn from(dev: &Device<device::Core>) -> Self { 460 + (&**dev).into() 461 + } 462 + } 463 + 464 + // SAFETY: Instances of `Device` are always reference-counted. 465 + unsafe impl crate::types::AlwaysRefCounted for Device { 466 + fn inc_ref(&self) { 467 + // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. 468 + unsafe { bindings::pci_dev_get(self.as_raw()) }; 469 + } 470 + 471 + unsafe fn dec_ref(obj: NonNull<Self>) { 472 + // SAFETY: The safety requirements guarantee that the refcount is non-zero. 473 + unsafe { bindings::pci_dev_put(obj.cast().as_ptr()) } 474 + } 475 + } 476 + 477 + impl AsRef<device::Device> for Device { 478 + fn as_ref(&self) -> &device::Device { 479 + // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid 480 + // `struct pci_dev`. 481 + let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) }; 482 + 483 + // SAFETY: `dev` points to a valid `struct device`. 484 + unsafe { device::Device::as_ref(dev) } 485 + } 486 + } 487 + 488 + // SAFETY: A `Device` is always reference-counted and can be released from any thread. 489 + unsafe impl Send for Device {} 490 + 491 + // SAFETY: `Device` can be shared among threads because all methods of `Device` 492 + // (i.e. `Device<Normal>) are thread safe. 493 + unsafe impl Sync for Device {}
+73 -31
rust/kernel/platform.rs
··· 5 5 //! C header: [`include/linux/platform_device.h`](srctree/include/linux/platform_device.h) 6 6 7 7 use crate::{ 8 - bindings, container_of, device, driver, 8 + bindings, device, driver, 9 9 error::{to_result, Result}, 10 10 of, 11 11 prelude::*, ··· 14 14 ThisModule, 15 15 }; 16 16 17 - use core::ptr::addr_of_mut; 17 + use core::{ 18 + marker::PhantomData, 19 + ops::Deref, 20 + ptr::{addr_of_mut, NonNull}, 21 + }; 18 22 19 23 /// An adapter for the registration of platform drivers. 20 24 pub struct Adapter<T: Driver>(T); ··· 58 54 59 55 impl<T: Driver + 'static> Adapter<T> { 60 56 extern "C" fn probe_callback(pdev: *mut bindings::platform_device) -> kernel::ffi::c_int { 61 - // SAFETY: The platform bus only ever calls the probe callback with a valid `pdev`. 62 - let dev = unsafe { device::Device::get_device(addr_of_mut!((*pdev).dev)) }; 63 - // SAFETY: `dev` is guaranteed to be embedded in a valid `struct platform_device` by the 64 - // call above. 65 - let mut pdev = unsafe { Device::from_dev(dev) }; 57 + // SAFETY: The platform bus only ever calls the probe callback with a valid pointer to a 58 + // `struct platform_device`. 59 + // 60 + // INVARIANT: `pdev` is valid for the duration of `probe_callback()`. 61 + let pdev = unsafe { &*pdev.cast::<Device<device::Core>>() }; 66 62 67 63 let info = <Self as driver::Adapter>::id_info(pdev.as_ref()); 68 - match T::probe(&mut pdev, info) { 64 + match T::probe(pdev, info) { 69 65 Ok(data) => { 70 66 // Let the `struct platform_device` own a reference of the driver's private data. 71 67 // SAFETY: By the type invariant `pdev.as_raw` returns a valid pointer to a ··· 124 120 /// # Example 125 121 /// 126 122 ///``` 127 - /// # use kernel::{bindings, c_str, of, platform}; 123 + /// # use kernel::{bindings, c_str, device::Core, of, platform}; 128 124 /// 129 125 /// struct MyDriver; 130 126 /// ··· 142 138 /// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); 143 139 /// 144 140 /// fn probe( 145 - /// _pdev: &mut platform::Device, 141 + /// _pdev: &platform::Device<Core>, 146 142 /// _id_info: Option<&Self::IdInfo>, 147 143 /// ) -> Result<Pin<KBox<Self>>> { 148 144 /// Err(ENODEV) 149 145 /// } 150 146 /// } 151 147 ///``` 152 - pub trait Driver { 148 + pub trait Driver: Send { 153 149 /// The type holding driver private data about each device id supported by the driver. 154 150 /// 155 151 /// TODO: Use associated_type_defaults once stabilized: ··· 164 160 /// 165 161 /// Called when a new platform device is added or discovered. 166 162 /// Implementers should attempt to initialize the device here. 167 - fn probe(dev: &mut Device, id_info: Option<&Self::IdInfo>) -> Result<Pin<KBox<Self>>>; 163 + fn probe(dev: &Device<device::Core>, id_info: Option<&Self::IdInfo>) 164 + -> Result<Pin<KBox<Self>>>; 168 165 } 169 166 170 167 /// The platform device representation. 171 168 /// 172 - /// A platform device is based on an always reference counted `device:Device` instance. Cloning a 173 - /// platform device, hence, also increments the base device' reference count. 169 + /// This structure represents the Rust abstraction for a C `struct platform_device`. The 170 + /// implementation abstracts the usage of an already existing C `struct platform_device` within Rust 171 + /// code that we get passed from the C side. 174 172 /// 175 173 /// # Invariants 176 174 /// 177 - /// `Device` holds a valid reference of `ARef<device::Device>` whose underlying `struct device` is a 178 - /// member of a `struct platform_device`. 179 - #[derive(Clone)] 180 - pub struct Device(ARef<device::Device>); 175 + /// A [`Device`] instance represents a valid `struct platform_device` created by the C portion of 176 + /// the kernel. 177 + #[repr(transparent)] 178 + pub struct Device<Ctx: device::DeviceContext = device::Normal>( 179 + Opaque<bindings::platform_device>, 180 + PhantomData<Ctx>, 181 + ); 181 182 182 183 impl Device { 183 - /// Convert a raw kernel device into a `Device` 184 - /// 185 - /// # Safety 186 - /// 187 - /// `dev` must be an `Aref<device::Device>` whose underlying `bindings::device` is a member of a 188 - /// `bindings::platform_device`. 189 - unsafe fn from_dev(dev: ARef<device::Device>) -> Self { 190 - Self(dev) 184 + fn as_raw(&self) -> *mut bindings::platform_device { 185 + self.0.get() 186 + } 187 + } 188 + 189 + impl Deref for Device<device::Core> { 190 + type Target = Device; 191 + 192 + fn deref(&self) -> &Self::Target { 193 + let ptr: *const Self = self; 194 + 195 + // CAST: `Device<Ctx>` is a transparent wrapper of `Opaque<bindings::platform_device>`. 196 + let ptr = ptr.cast::<Device>(); 197 + 198 + // SAFETY: `ptr` was derived from `&self`. 199 + unsafe { &*ptr } 200 + } 201 + } 202 + 203 + impl From<&Device<device::Core>> for ARef<Device> { 204 + fn from(dev: &Device<device::Core>) -> Self { 205 + (&**dev).into() 206 + } 207 + } 208 + 209 + // SAFETY: Instances of `Device` are always reference-counted. 210 + unsafe impl crate::types::AlwaysRefCounted for Device { 211 + fn inc_ref(&self) { 212 + // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. 213 + unsafe { bindings::get_device(self.as_ref().as_raw()) }; 191 214 } 192 215 193 - fn as_raw(&self) -> *mut bindings::platform_device { 194 - // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` 195 - // embedded in `struct platform_device`. 196 - unsafe { container_of!(self.0.as_raw(), bindings::platform_device, dev) }.cast_mut() 216 + unsafe fn dec_ref(obj: NonNull<Self>) { 217 + // SAFETY: The safety requirements guarantee that the refcount is non-zero. 218 + unsafe { bindings::platform_device_put(obj.cast().as_ptr()) } 197 219 } 198 220 } 199 221 200 222 impl AsRef<device::Device> for Device { 201 223 fn as_ref(&self) -> &device::Device { 202 - &self.0 224 + // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid 225 + // `struct platform_device`. 226 + let dev = unsafe { addr_of_mut!((*self.as_raw()).dev) }; 227 + 228 + // SAFETY: `dev` points to a valid `struct device`. 229 + unsafe { device::Device::as_ref(dev) } 203 230 } 204 231 } 232 + 233 + // SAFETY: A `Device` is always reference-counted and can be released from any thread. 234 + unsafe impl Send for Device {} 235 + 236 + // SAFETY: `Device` can be shared among threads because all methods of `Device` 237 + // (i.e. `Device<Normal>) are thread safe. 238 + unsafe impl Sync for Device {}
+4 -4
samples/rust/rust_dma.rs
··· 4 4 //! 5 5 //! To make this driver probe, QEMU must be run with `-device pci-testdev`. 6 6 7 - use kernel::{bindings, dma::CoherentAllocation, pci, prelude::*}; 7 + use kernel::{bindings, device::Core, dma::CoherentAllocation, pci, prelude::*, types::ARef}; 8 8 9 9 struct DmaSampleDriver { 10 - pdev: pci::Device, 10 + pdev: ARef<pci::Device>, 11 11 ca: CoherentAllocation<MyStruct>, 12 12 } 13 13 ··· 48 48 type IdInfo = (); 49 49 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; 50 50 51 - fn probe(pdev: &mut pci::Device, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { 51 + fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { 52 52 dev_info!(pdev.as_ref(), "Probe DMA test driver.\n"); 53 53 54 54 let ca: CoherentAllocation<MyStruct> = ··· 64 64 65 65 let drvdata = KBox::new( 66 66 Self { 67 - pdev: pdev.clone(), 67 + pdev: pdev.into(), 68 68 ca, 69 69 }, 70 70 GFP_KERNEL,
+1 -1
samples/rust/rust_driver_faux.rs
··· 20 20 fn init(_module: &'static ThisModule) -> Result<Self> { 21 21 pr_info!("Initialising Rust Faux Device Sample\n"); 22 22 23 - let reg = faux::Registration::new(c_str!("rust-faux-sample-device"))?; 23 + let reg = faux::Registration::new(c_str!("rust-faux-sample-device"), None)?; 24 24 25 25 dev_info!(reg.as_ref(), "Hello from faux device!\n"); 26 26
+10 -10
samples/rust/rust_driver_pci.rs
··· 4 4 //! 5 5 //! To make this driver probe, QEMU must be run with `-device pci-testdev`. 6 6 7 - use kernel::{bindings, c_str, devres::Devres, pci, prelude::*}; 7 + use kernel::{bindings, c_str, device::Core, devres::Devres, pci, prelude::*, types::ARef}; 8 8 9 9 struct Regs; 10 10 ··· 26 26 } 27 27 28 28 struct SampleDriver { 29 - pdev: pci::Device, 29 + pdev: ARef<pci::Device>, 30 30 bar: Devres<Bar0>, 31 31 } 32 32 ··· 43 43 impl SampleDriver { 44 44 fn testdev(index: &TestIndex, bar: &Bar0) -> Result<u32> { 45 45 // Select the test. 46 - bar.writeb(index.0, Regs::TEST); 46 + bar.write8(index.0, Regs::TEST); 47 47 48 - let offset = u32::from_le(bar.readl(Regs::OFFSET)) as usize; 49 - let data = bar.readb(Regs::DATA); 48 + let offset = u32::from_le(bar.read32(Regs::OFFSET)) as usize; 49 + let data = bar.read8(Regs::DATA); 50 50 51 51 // Write `data` to `offset` to increase `count` by one. 52 52 // 53 - // Note that we need `try_writeb`, since `offset` can't be checked at compile-time. 54 - bar.try_writeb(data, offset)?; 53 + // Note that we need `try_write8`, since `offset` can't be checked at compile-time. 54 + bar.try_write8(data, offset)?; 55 55 56 - Ok(bar.readl(Regs::COUNT)) 56 + Ok(bar.read32(Regs::COUNT)) 57 57 } 58 58 } 59 59 ··· 62 62 63 63 const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; 64 64 65 - fn probe(pdev: &mut pci::Device, info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { 65 + fn probe(pdev: &pci::Device<Core>, info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> { 66 66 dev_dbg!( 67 67 pdev.as_ref(), 68 68 "Probe Rust PCI driver sample (PCI ID: 0x{:x}, 0x{:x}).\n", ··· 77 77 78 78 let drvdata = KBox::new( 79 79 Self { 80 - pdev: pdev.clone(), 80 + pdev: pdev.into(), 81 81 bar, 82 82 }, 83 83 GFP_KERNEL,
+7 -4
samples/rust/rust_driver_platform.rs
··· 2 2 3 3 //! Rust Platform driver sample. 4 4 5 - use kernel::{c_str, of, platform, prelude::*}; 5 + use kernel::{c_str, device::Core, of, platform, prelude::*, types::ARef}; 6 6 7 7 struct SampleDriver { 8 - pdev: platform::Device, 8 + pdev: ARef<platform::Device>, 9 9 } 10 10 11 11 struct Info(u32); ··· 21 21 type IdInfo = Info; 22 22 const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); 23 23 24 - fn probe(pdev: &mut platform::Device, info: Option<&Self::IdInfo>) -> Result<Pin<KBox<Self>>> { 24 + fn probe( 25 + pdev: &platform::Device<Core>, 26 + info: Option<&Self::IdInfo>, 27 + ) -> Result<Pin<KBox<Self>>> { 25 28 dev_dbg!(pdev.as_ref(), "Probe Rust Platform driver sample.\n"); 26 29 27 30 if let Some(info) = info { 28 31 dev_info!(pdev.as_ref(), "Probed with info: '{}'.\n", info.0); 29 32 } 30 33 31 - let drvdata = KBox::new(Self { pdev: pdev.clone() }, GFP_KERNEL)?; 34 + let drvdata = KBox::new(Self { pdev: pdev.into() }, GFP_KERNEL)?; 32 35 33 36 Ok(drvdata.into()) 34 37 }
+5 -2
security/selinux/hooks.c
··· 3587 3587 newsid = tsec->create_sid; 3588 3588 } else { 3589 3589 u16 secclass = inode_mode_to_security_class(kn->mode); 3590 + const char *kn_name; 3590 3591 struct qstr q; 3591 3592 3592 - q.name = kn->name; 3593 - q.hash_len = hashlen_string(kn_dir, kn->name); 3593 + /* kn is fresh, can't be renamed, name goes not away */ 3594 + kn_name = rcu_dereference_check(kn->name, true); 3595 + q.name = kn_name; 3596 + q.hash_len = hashlen_string(kn_dir, kn_name); 3594 3597 3595 3598 rc = security_transition_sid(tsec->sid, 3596 3599 parent_sid, secclass, &q,
+1 -1
tools/testing/selftests/bpf/progs/profiler.inc.h
··· 223 223 if (bpf_cmp_likely(filepart_length, <=, MAX_PATH)) { 224 224 payload += filepart_length; 225 225 } 226 - cgroup_node = BPF_CORE_READ(cgroup_node, parent); 226 + cgroup_node = BPF_CORE_READ(cgroup_node, __parent); 227 227 } 228 228 return payload; 229 229 }