* what should be a simple question about sysfs attributes ...
@ 2015-01-30 11:55 Robert P. J. Day
2015-01-30 12:06 ` Robert P. J. Day
2015-01-30 12:30 ` Robert P. J. Day
0 siblings, 2 replies; 4+ messages in thread
From: Robert P. J. Day @ 2015-01-30 11:55 UTC (permalink / raw)
To: kernelnewbies
... but will take a while to set up. i want to write a short tutorial
on kobjects, sysfs and attributes so i want to make absolutely sure i
understand them (which is something i should understand anyway. :-)
from sysfs.h and kobject.h, we have the definition of the generic
kernel-wide "attribute" and "kobj_attribute" structures:
struct attribute {
const char *name;
umode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
bool ignore_lockdep:1;
struct lock_class_key *key;
struct lock_class_key skey;
#endif
};
and
struct kobj_attribute {
struct attribute attr;
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
char *buf);
ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count);
};
so what the above shows is that a "kobj_attribute" contains an
"attribute" and has, as its internal callback routines, functions that
deal only with completely generic kobject and kobj_attribute pointers.
so if i'm creating a number of attributes for some kobject i've
created, and i'm associating show and store routines with each one,
those show and store routines must have that prototype.
for example, look at mm/ksm.c and how the attributes and callback
routines are defined -- here's one:
////////
static ssize_t full_scans_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", ksm_scan.seqnr);
}
KSM_ATTR_RO(full_scans);
static struct attribute *ksm_attrs[] = {
&sleep_millisecs_attr.attr,
&pages_to_scan_attr.attr,
&run_attr.attr,
&pages_shared_attr.attr,
&pages_sharing_attr.attr,
&pages_unshared_attr.attr,
&pages_volatile_attr.attr,
&full_scans_attr.attr,
#ifdef CONFIG_NUMA
&merge_across_nodes_attr.attr,
#endif
NULL,
};
static struct attribute_group ksm_attr_group = {
.attrs = ksm_attrs,
.name = "ksm",
};
////////
so the way i've always interpreted the above is that, when i finally
register the attributes with the kernel, i am registering really just
the underlying generic "attribute" structure and, when i try to access
that attribute file, it automatically dereferences to the enclosing
kobj_attribute structure to pick up the corresponding show() and
store() routines associated with that attribute.
so the first question is, is my understanding correct? if, in the
above case, whenever i try to access one of the ksm attributes in
/sys/kernel/mm/ksm, does the kernel take the reference to that
*generic* attribute and automatically dereference/container_of() on it
to get the enclosing kobj_attribute structure to pick up the
corresponding show() and store() routines? asked a shorter way, is it
assumed that a kobject attribute is *always* contained inside a
kobj_attribute structure? and that the code in mm/ksm.c is an example
of how to add individual show() and store() routines to such
attributes?
now here's part 2, and it's just a followup from the above. the
second variation for attributes is what you see in cpufreq.c. rather
than each attribute having its own callback routines, that code
defines a prototype for cpufreq-*specific* show and store routines and
a cpufreq-specific "freq_attr":
struct freq_attr {
struct attribute attr;
ssize_t (*show)(struct cpufreq_policy *, char *);
ssize_t (*store)(struct cpufreq_policy *, const char *, size_t
count);
};
*however* (and here's the thing i want to make sure i understand),
when you register all of the cpufreq attribute files, each one still
has to be interpreted as if it's part of a generic kobj_attribute
structure with generic show() and store() routines, so what cpufreq
does is define two generic show() and store() routines, and a couple
helper macros that allow those two routines to then dereference to the
appropriate cpufreq_policy and freq_attr pointers, then call the
attribute-specific show() and store() routines:
//////////
#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
#define to_attr(a) container_of(a, struct freq_attr, attr)
static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
... snip ...
}
static ssize_t store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
... snip ...
}
//////////
and at the end of that file, the attributes are all registered with:
static const struct sysfs_ops sysfs_ops = {
.show = show,
.store = store,
};
static struct kobj_type ktype_cpufreq = {
.sysfs_ops = &sysfs_ops,
.default_attrs = default_attrs,
.release = cpufreq_sysfs_release,
};
which i interpret as saying that all of those attributes should be
registered with the same single show() and store() routines (as
opposed to ksm, which used different show() and store() routines for
each attribute.
in closing(?), as i understand it, when i access a kobject attribute
file, it is assumed that that attribute is enclosed in a
kobj_attribute structure, which contains the generic show() and
store() routines, and i've seen two patterns for that:
1) in mm/ksm.c, each attribute is *directly* registered with callback
routines with that prototype specific to that attribute, or
2) in cpufreq.c, all attributes are, in one operation, all registered
with the *same* pair of generic callback functions, and those
functions are then required to dereference the generic pointers to be
able to call the appropriate callbacks for the given attribute.
do i have this about right?
rday
--
========================================================================
Robert P. J. Day Ottawa, Ontario, CANADA
http://crashcourse.ca
Twitter: http://twitter.com/rpjday
LinkedIn: http://ca.linkedin.com/in/rpjday
========================================================================
^ permalink raw reply [flat|nested] 4+ messages in thread* what should be a simple question about sysfs attributes ...
2015-01-30 11:55 what should be a simple question about sysfs attributes Robert P. J. Day
@ 2015-01-30 12:06 ` Robert P. J. Day
2015-01-30 12:30 ` Robert P. J. Day
1 sibling, 0 replies; 4+ messages in thread
From: Robert P. J. Day @ 2015-01-30 12:06 UTC (permalink / raw)
To: kernelnewbies
hmmmmmmm ... i think i made a mess of that last
question/explanation so let me think about it more. darn.
rday
--
========================================================================
Robert P. J. Day Ottawa, Ontario, CANADA
http://crashcourse.ca
Twitter: http://twitter.com/rpjday
LinkedIn: http://ca.linkedin.com/in/rpjday
========================================================================
^ permalink raw reply [flat|nested] 4+ messages in thread* what should be a simple question about sysfs attributes ...
2015-01-30 11:55 what should be a simple question about sysfs attributes Robert P. J. Day
2015-01-30 12:06 ` Robert P. J. Day
@ 2015-01-30 12:30 ` Robert P. J. Day
2015-02-01 21:44 ` John de la Garza
1 sibling, 1 reply; 4+ messages in thread
From: Robert P. J. Day @ 2015-01-30 12:30 UTC (permalink / raw)
To: kernelnewbies
i'll try this one more time, but much more concisely. so far, i've
seen two different ways to create a kobject's attributes and register
callback routines for them:
the first general way i've seen is in mm/ksm.c, where each attribute
is enclosed in a surrounding kobj_attribute structure, which also
contains references to *generic* show() and store() routines:
struct kobj_attribute {
struct attribute attr;
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
char *buf);
ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count);
};
in mm/ksm.c file, each attribute is associated *directly* with a
different show() and store() routine specific to that attribute. so my
understanding is, when you try to access a ksm attribute file under
/sys, the generic attribute object is *assumed* to be contained inside
a kobj_attribute structure, so dereferencing to get to the show() and
store() routine for that attribute is easy.
is that correct? that is, the way ksm.c creates and registers
attributes means that it is assumed "kobj_attribute" structures will
be used as containers for generic attributes?
the second way is in cpufreq.c, where the difference is that, rather
than each attribute file being *directly* associated with its own pair
of callback routines, a pair of *generic* show() and store() routines
are defined:
static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
static ssize_t store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
and the way the attributes are registered in *that* source file:
static const struct sysfs_ops sysfs_ops = {
.show = show,
.store = store,
};
static struct kobj_type ktype_cpufreq = {
.sysfs_ops = &sysfs_ops,
.default_attrs = default_attrs,
.release = cpufreq_sysfs_release,
};
means that, rather than dereferencing each generic attribute to an
enclosing kobj_attribute, each attribute file reference is redirected
to the *same* generic show() and store() callback associated with the
ktype, at which point those two generic callbacks are responsible for
dereferencing a generic attribute pointer to get to (in this case),
the enclosing cpufreq-specific freq_attr structure.
i *think* i got it right this time. comments?
rday
--
========================================================================
Robert P. J. Day Ottawa, Ontario, CANADA
http://crashcourse.ca
Twitter: http://twitter.com/rpjday
LinkedIn: http://ca.linkedin.com/in/rpjday
========================================================================
^ permalink raw reply [flat|nested] 4+ messages in thread* what should be a simple question about sysfs attributes ...
2015-01-30 12:30 ` Robert P. J. Day
@ 2015-02-01 21:44 ` John de la Garza
0 siblings, 0 replies; 4+ messages in thread
From: John de la Garza @ 2015-02-01 21:44 UTC (permalink / raw)
To: kernelnewbies
On Fri, Jan 30, 2015 at 04:30:02AM -0800, Robert P. J. Day wrote:
>
> i'll try this one more time, but much more concisely. so far, i've
> seen two different ways to create a kobject's attributes and register
> callback routines for them:
>
> the first general way i've seen is in mm/ksm.c, where each attribute
> is enclosed in a surrounding kobj_attribute structure, which also
> contains references to *generic* show() and store() routines:
>
> struct kobj_attribute {
> struct attribute attr;
> ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
> char *buf);
> ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
> const char *buf, size_t count);
> };
>
> in mm/ksm.c file, each attribute is associated *directly* with a
> different show() and store() routine specific to that attribute. so my
> understanding is, when you try to access a ksm attribute file under
> /sys, the generic attribute object is *assumed* to be contained inside
> a kobj_attribute structure, so dereferencing to get to the show() and
> store() routine for that attribute is easy.
>
> is that correct? that is, the way ksm.c creates and registers
> attributes means that it is assumed "kobj_attribute" structures will
> be used as containers for generic attributes?
>
> the second way is in cpufreq.c, where the difference is that, rather
> than each attribute file being *directly* associated with its own pair
> of callback routines, a pair of *generic* show() and store() routines
> are defined:
>
> static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
>
> static ssize_t store(struct kobject *kobj, struct attribute *attr,
> const char *buf, size_t count)
>
> and the way the attributes are registered in *that* source file:
>
> static const struct sysfs_ops sysfs_ops = {
> .show = show,
> .store = store,
> };
>
> static struct kobj_type ktype_cpufreq = {
> .sysfs_ops = &sysfs_ops,
> .default_attrs = default_attrs,
> .release = cpufreq_sysfs_release,
> };
>
> means that, rather than dereferencing each generic attribute to an
> enclosing kobj_attribute, each attribute file reference is redirected
> to the *same* generic show() and store() callback associated with the
> ktype, at which point those two generic callbacks are responsible for
> dereferencing a generic attribute pointer to get to (in this case),
> the enclosing cpufreq-specific freq_attr structure.
>
> i *think* i got it right this time. comments?
If I'm understanding correctly, this is describing the same thing.
"Sometimes all that a developer wants is a way to create a simple directory
in the sysfs hierarchy, and not have to mess with the whole complication of
ksets, show and store functions, and other details. This is the one
exception where a single kobject should be created."
from: Documentation/kobject.txt
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-02-01 21:44 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-30 11:55 what should be a simple question about sysfs attributes Robert P. J. Day
2015-01-30 12:06 ` Robert P. J. Day
2015-01-30 12:30 ` Robert P. J. Day
2015-02-01 21:44 ` John de la Garza
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).