1 // SPDX-License-Identifier: GPL-2.0
3 * System Trace Module (STM) master/channel allocation policy management
4 * Copyright (c) 2014, Intel Corporation.
6 * A master/channel allocation policy allows mapping string identifiers to
7 * master and channel ranges, where allocation can be done.
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/types.h>
13 #include <linux/module.h>
14 #include <linux/device.h>
15 #include <linux/configfs.h>
16 #include <linux/slab.h>
17 #include <linux/stm.h>
21 * STP Master/Channel allocation policy configfs layout.
25 struct config_group group
;
26 struct stm_device
*stm
;
29 struct stp_policy_node
{
30 struct config_group group
;
31 struct stp_policy
*policy
;
32 unsigned int first_master
;
33 unsigned int last_master
;
34 unsigned int first_channel
;
35 unsigned int last_channel
;
38 static struct configfs_subsystem stp_policy_subsys
;
40 void stp_policy_node_get_ranges(struct stp_policy_node
*policy_node
,
41 unsigned int *mstart
, unsigned int *mend
,
42 unsigned int *cstart
, unsigned int *cend
)
44 *mstart
= policy_node
->first_master
;
45 *mend
= policy_node
->last_master
;
46 *cstart
= policy_node
->first_channel
;
47 *cend
= policy_node
->last_channel
;
50 static inline char *stp_policy_node_name(struct stp_policy_node
*policy_node
)
52 return policy_node
->group
.cg_item
.ci_name
? : "<none>";
55 static inline struct stp_policy
*to_stp_policy(struct config_item
*item
)
58 container_of(to_config_group(item
), struct stp_policy
, group
) :
62 static inline struct stp_policy_node
*
63 to_stp_policy_node(struct config_item
*item
)
66 container_of(to_config_group(item
), struct stp_policy_node
,
72 stp_policy_node_masters_show(struct config_item
*item
, char *page
)
74 struct stp_policy_node
*policy_node
= to_stp_policy_node(item
);
77 count
= sprintf(page
, "%u %u\n", policy_node
->first_master
,
78 policy_node
->last_master
);
84 stp_policy_node_masters_store(struct config_item
*item
, const char *page
,
87 struct stp_policy_node
*policy_node
= to_stp_policy_node(item
);
88 unsigned int first
, last
;
89 struct stm_device
*stm
;
90 char *p
= (char *)page
;
91 ssize_t ret
= -ENODEV
;
93 if (sscanf(p
, "%u %u", &first
, &last
) != 2)
96 mutex_lock(&stp_policy_subsys
.su_mutex
);
97 stm
= policy_node
->policy
->stm
;
101 /* must be within [sw_start..sw_end], which is an inclusive range */
102 if (first
> last
|| first
< stm
->data
->sw_start
||
103 last
> stm
->data
->sw_end
) {
109 policy_node
->first_master
= first
;
110 policy_node
->last_master
= last
;
113 mutex_unlock(&stp_policy_subsys
.su_mutex
);
119 stp_policy_node_channels_show(struct config_item
*item
, char *page
)
121 struct stp_policy_node
*policy_node
= to_stp_policy_node(item
);
124 count
= sprintf(page
, "%u %u\n", policy_node
->first_channel
,
125 policy_node
->last_channel
);
131 stp_policy_node_channels_store(struct config_item
*item
, const char *page
,
134 struct stp_policy_node
*policy_node
= to_stp_policy_node(item
);
135 unsigned int first
, last
;
136 struct stm_device
*stm
;
137 char *p
= (char *)page
;
138 ssize_t ret
= -ENODEV
;
140 if (sscanf(p
, "%u %u", &first
, &last
) != 2)
143 mutex_lock(&stp_policy_subsys
.su_mutex
);
144 stm
= policy_node
->policy
->stm
;
148 if (first
> INT_MAX
|| last
> INT_MAX
|| first
> last
||
149 last
>= stm
->data
->sw_nchannels
) {
155 policy_node
->first_channel
= first
;
156 policy_node
->last_channel
= last
;
159 mutex_unlock(&stp_policy_subsys
.su_mutex
);
164 static void stp_policy_node_release(struct config_item
*item
)
166 kfree(to_stp_policy_node(item
));
169 static struct configfs_item_operations stp_policy_node_item_ops
= {
170 .release
= stp_policy_node_release
,
173 CONFIGFS_ATTR(stp_policy_node_
, masters
);
174 CONFIGFS_ATTR(stp_policy_node_
, channels
);
176 static struct configfs_attribute
*stp_policy_node_attrs
[] = {
177 &stp_policy_node_attr_masters
,
178 &stp_policy_node_attr_channels
,
182 static const struct config_item_type stp_policy_type
;
183 static const struct config_item_type stp_policy_node_type
;
185 static struct config_group
*
186 stp_policy_node_make(struct config_group
*group
, const char *name
)
188 struct stp_policy_node
*policy_node
, *parent_node
;
189 struct stp_policy
*policy
;
191 if (group
->cg_item
.ci_type
== &stp_policy_type
) {
192 policy
= container_of(group
, struct stp_policy
, group
);
194 parent_node
= container_of(group
, struct stp_policy_node
,
196 policy
= parent_node
->policy
;
200 return ERR_PTR(-ENODEV
);
202 policy_node
= kzalloc(sizeof(struct stp_policy_node
), GFP_KERNEL
);
204 return ERR_PTR(-ENOMEM
);
206 config_group_init_type_name(&policy_node
->group
, name
,
207 &stp_policy_node_type
);
209 policy_node
->policy
= policy
;
211 /* default values for the attributes */
212 policy_node
->first_master
= policy
->stm
->data
->sw_start
;
213 policy_node
->last_master
= policy
->stm
->data
->sw_end
;
214 policy_node
->first_channel
= 0;
215 policy_node
->last_channel
= policy
->stm
->data
->sw_nchannels
- 1;
217 return &policy_node
->group
;
221 stp_policy_node_drop(struct config_group
*group
, struct config_item
*item
)
223 config_item_put(item
);
226 static struct configfs_group_operations stp_policy_node_group_ops
= {
227 .make_group
= stp_policy_node_make
,
228 .drop_item
= stp_policy_node_drop
,
231 static const struct config_item_type stp_policy_node_type
= {
232 .ct_item_ops
= &stp_policy_node_item_ops
,
233 .ct_group_ops
= &stp_policy_node_group_ops
,
234 .ct_attrs
= stp_policy_node_attrs
,
235 .ct_owner
= THIS_MODULE
,
239 * Root group: policies.
241 static ssize_t
stp_policy_device_show(struct config_item
*item
,
244 struct stp_policy
*policy
= to_stp_policy(item
);
247 count
= sprintf(page
, "%s\n",
248 (policy
&& policy
->stm
) ?
249 policy
->stm
->data
->name
:
255 CONFIGFS_ATTR_RO(stp_policy_
, device
);
257 static struct configfs_attribute
*stp_policy_attrs
[] = {
258 &stp_policy_attr_device
,
262 void stp_policy_unbind(struct stp_policy
*policy
)
264 struct stm_device
*stm
= policy
->stm
;
267 * stp_policy_release() will not call here if the policy is already
268 * unbound; other users should not either, as no link exists between
269 * this policy and anything else in that case
271 if (WARN_ON_ONCE(!policy
->stm
))
274 lockdep_assert_held(&stm
->policy_mutex
);
282 static void stp_policy_release(struct config_item
*item
)
284 struct stp_policy
*policy
= to_stp_policy(item
);
285 struct stm_device
*stm
= policy
->stm
;
287 /* a policy *can* be unbound and still exist in configfs tree */
291 mutex_lock(&stm
->policy_mutex
);
292 stp_policy_unbind(policy
);
293 mutex_unlock(&stm
->policy_mutex
);
298 static struct configfs_item_operations stp_policy_item_ops
= {
299 .release
= stp_policy_release
,
302 static struct configfs_group_operations stp_policy_group_ops
= {
303 .make_group
= stp_policy_node_make
,
306 static const struct config_item_type stp_policy_type
= {
307 .ct_item_ops
= &stp_policy_item_ops
,
308 .ct_group_ops
= &stp_policy_group_ops
,
309 .ct_attrs
= stp_policy_attrs
,
310 .ct_owner
= THIS_MODULE
,
313 static struct config_group
*
314 stp_policies_make(struct config_group
*group
, const char *name
)
316 struct config_group
*ret
;
317 struct stm_device
*stm
;
320 devname
= kasprintf(GFP_KERNEL
, "%s", name
);
322 return ERR_PTR(-ENOMEM
);
325 * node must look like <device_name>.<policy_name>, where
326 * <device_name> is the name of an existing stm device; may
328 * <policy_name> is an arbitrary string; may not contain dots
330 p
= strrchr(devname
, '.');
333 return ERR_PTR(-EINVAL
);
338 stm
= stm_find_device(devname
);
342 return ERR_PTR(-ENODEV
);
344 mutex_lock(&stm
->policy_mutex
);
346 ret
= ERR_PTR(-EBUSY
);
350 stm
->policy
= kzalloc(sizeof(*stm
->policy
), GFP_KERNEL
);
352 ret
= ERR_PTR(-ENOMEM
);
356 config_group_init_type_name(&stm
->policy
->group
, name
,
358 stm
->policy
->stm
= stm
;
360 ret
= &stm
->policy
->group
;
363 mutex_unlock(&stm
->policy_mutex
);
371 static struct configfs_group_operations stp_policies_group_ops
= {
372 .make_group
= stp_policies_make
,
375 static const struct config_item_type stp_policies_type
= {
376 .ct_group_ops
= &stp_policies_group_ops
,
377 .ct_owner
= THIS_MODULE
,
380 static struct configfs_subsystem stp_policy_subsys
= {
383 .ci_namebuf
= "stp-policy",
384 .ci_type
= &stp_policies_type
,
390 * Lock the policy mutex from the outside
392 static struct stp_policy_node
*
393 __stp_policy_node_lookup(struct stp_policy
*policy
, char *s
)
395 struct stp_policy_node
*policy_node
, *ret
;
396 struct list_head
*head
= &policy
->group
.cg_children
;
397 struct config_item
*item
;
398 char *start
, *end
= s
;
400 if (list_empty(head
))
403 /* return the first entry if everything else fails */
404 item
= list_entry(head
->next
, struct config_item
, ci_entry
);
405 ret
= to_stp_policy_node(item
);
409 start
= strsep(&end
, "/");
416 list_for_each_entry(item
, head
, ci_entry
) {
417 policy_node
= to_stp_policy_node(item
);
420 policy_node
->group
.cg_item
.ci_name
)) {
426 head
= &policy_node
->group
.cg_children
;
438 struct stp_policy_node
*
439 stp_policy_node_lookup(struct stm_device
*stm
, char *s
)
441 struct stp_policy_node
*policy_node
= NULL
;
443 mutex_lock(&stp_policy_subsys
.su_mutex
);
445 mutex_lock(&stm
->policy_mutex
);
447 policy_node
= __stp_policy_node_lookup(stm
->policy
, s
);
448 mutex_unlock(&stm
->policy_mutex
);
451 config_item_get(&policy_node
->group
.cg_item
);
452 mutex_unlock(&stp_policy_subsys
.su_mutex
);
457 void stp_policy_node_put(struct stp_policy_node
*policy_node
)
459 config_item_put(&policy_node
->group
.cg_item
);
462 int __init
stp_configfs_init(void)
466 config_group_init(&stp_policy_subsys
.su_group
);
467 mutex_init(&stp_policy_subsys
.su_mutex
);
468 err
= configfs_register_subsystem(&stp_policy_subsys
);
473 void __exit
stp_configfs_exit(void)
475 configfs_unregister_subsystem(&stp_policy_subsys
);