Where is run_node defined in the sched_fair.c of Linux 2.6.33?
I am reading Robert Love's Book Linux Kernel Development( https://rads.stackoverflow.com/amzn/click/com/B003V4ATI0). It uses the 2.6.33 kernel for demonstration. I have been going through certain parts of the source and can't find out where is the initial definition of many things. A lot of things are just used, like "magic" without me finding the definition. One example: static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) { struct rb_node *left = cfs_rq->rb_leftmost; if (!left) return NULL; return rb_entry(left, struct sched_entity, run_node); } static struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) { struct rb_node *last = rb_last(&cfs_rq->tasks_timeline); if (!last) return NULL; return rb_entry(last, struct sched_entity, run_node); } This in kernel/sched_fair.c lines 384 and 394 in 2.6.33 kernel. Where is the run_node coming from ? I have grep ed( https://livegrep.com/search/linuxq=run_node&fold_case=auto®ex=false&conte... <https://livegrep.com/search/linux?q=run_node&fold_case=auto®ex=false&cont...>) the entire source base over here, and I have not found any definition of run_node that would allow it to be used like this. There is a declaration( https://github.com/torvalds/linux/blob/219d54332a09e8d8741c1e1982f5eae56099d...) in the sched_entity structure, but nothing outside of it that would allow it to be used like this. I cannot understand how things are organized, its really confusing. What is going on ? -- Regards, Sreyan Chakravarty
On Wed, May 06, 2020 at 05:32:26PM +0530, Sreyan Chakravarty wrote:
I am reading Robert Love's Book Linux Kernel Development( https://rads.stackoverflow.com/amzn/click/com/B003V4ATI0).
It uses the 2.6.33 kernel for demonstration.
I have been going through certain parts of the source and can't find out where is the initial definition of many things. A lot of things are just used, like "magic" without me finding the definition.
One example:
static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) { struct rb_node *left = cfs_rq->rb_leftmost;
if (!left) return NULL;
return rb_entry(left, struct sched_entity, run_node); }
include/linux/rbtree.h:#define rb_entry(ptr, type, member) container_of(ptr, type, member) So rb_entry is a macro and it basically rewrites the return line into another macro: return container_of(left, struct sched_entity, run_node); And that one gives the address of the struct sched_entity that left is a member of by subtracting the offset from the struct start to run_node member: struct sched_entity { - ... | ... | offset ... | ... - struct rb_node run_node; <=== left points here ... } https://stackoverflow.com/questions/15832301/understanding-container-of-macr... -- Valentin
On Wed, May 6, 2020 at 2:13 PM Sreyan Chakravarty <sreyan32@gmail.com> wrote:
I am reading Robert Love's Book Linux Kernel Development(https://rads.stackoverflow.com/amzn/click/com/B003V4ATI0).
It uses the 2.6.33 kernel for demonstration.
I have been going through certain parts of the source and can't find out where is the initial definition of many things. A lot of things are just used, like "magic" without me finding the definition.
One example:
static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) { struct rb_node *left = cfs_rq->rb_leftmost;
if (!left) return NULL;
return rb_entry(left, struct sched_entity, run_node); }
static struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) { struct rb_node *last = rb_last(&cfs_rq->tasks_timeline);
if (!last) return NULL;
return rb_entry(last, struct sched_entity, run_node); }
This in kernel/sched_fair.c lines 384 and 394 in 2.6.33 kernel.
Where is the run_node coming from ?
I have grep ed(https://livegrep.com/search/linuxq=run_node&fold_case=auto®ex=false&conte...) the entire source base over here, and I have not found any definition of run_node that would allow it to be used like this.
There is a declaration(https://github.com/torvalds/linux/blob/219d54332a09e8d8741c1e1982f5eae56099d...) in the sched_entity structure, but nothing outside of it that would allow it to be used like this.
I cannot understand how things are organized, its really confusing.
What is going on ?
I believe you are assuming "rb_entry" is a C function and run_node is a variable, but it is not. Instead rb_entry is a macro that takes the argument as "plain source code strings" and creates an C-code expression out of that. If you look at the macro definitions of rb_entry and follow that to the truth, you will how everything magically resolves to C code that a C compiler could actually parse and make sense of. I hope that helps. Lukas
participants (3)
-
Lukas Bulwahn -
Sreyan Chakravarty -
Valentin Vidić