Skip to content

Commit 3ba1110

Browse files
anna-marialxKAGA-KOKO
authored andcommitted
timers/migration: Use a single struct for hierarchy walk data
Two different structs are defined for propagating data from one to another level when walking the hierarchy. Several struct members exist in both structs which makes generalization harder. Merge those two structs into a single one and use it directly in walk_groups() and the corresponding function pointers instead of introducing pointer casting all over the place. Signed-off-by: Anna-Maria Behnsen <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Frederic Weisbecker <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 9250674 commit 3ba1110

File tree

1 file changed

+55
-71
lines changed

1 file changed

+55
-71
lines changed

kernel/time/timer_migration.c

Lines changed: 55 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -475,69 +475,31 @@ static bool tmigr_check_lonely(struct tmigr_group *group)
475475
return bitmap_weight(&active, BIT_CNT) <= 1;
476476
}
477477

478-
typedef bool (*up_f)(struct tmigr_group *, struct tmigr_group *, void *);
479-
480-
static void __walk_groups(up_f up, void *data,
481-
struct tmigr_cpu *tmc)
482-
{
483-
struct tmigr_group *child = NULL, *group = tmc->tmgroup;
484-
485-
do {
486-
WARN_ON_ONCE(group->level >= tmigr_hierarchy_levels);
487-
488-
if (up(group, child, data))
489-
break;
490-
491-
child = group;
492-
group = group->parent;
493-
} while (group);
494-
}
495-
496-
static void walk_groups(up_f up, void *data, struct tmigr_cpu *tmc)
497-
{
498-
lockdep_assert_held(&tmc->lock);
499-
500-
__walk_groups(up, data, tmc);
501-
}
502-
503478
/**
504479
* struct tmigr_walk - data required for walking the hierarchy
505480
* @nextexp: Next CPU event expiry information which is handed into
506481
* the timer migration code by the timer code
507482
* (get_next_timer_interrupt())
508-
* @firstexp: Contains the first event expiry information when last
509-
* active CPU of hierarchy is on the way to idle to make
510-
* sure CPU will be back in time. It is updated in top
511-
* level group only. Be aware, there could occur a new top
512-
* level of the hierarchy between the 'top level call' in
513-
* tmigr_update_events() and the check for the parent group
514-
* in walk_groups(). Then @firstexp might contain a value
515-
* != KTIME_MAX even if it was not the final top
516-
* level. This is not a problem, as the worst outcome is a
517-
* CPU which might wake up a little early.
483+
* @firstexp: Contains the first event expiry information when
484+
* hierarchy is completely idle. When CPU itself was the
485+
* last going idle, information makes sure, that CPU will
486+
* be back in time. When using this value in the remote
487+
* expiry case, firstexp is stored in the per CPU tmigr_cpu
488+
* struct of CPU which expires remote timers. It is updated
489+
* in top level group only. Be aware, there could occur a
490+
* new top level of the hierarchy between the 'top level
491+
* call' in tmigr_update_events() and the check for the
492+
* parent group in walk_groups(). Then @firstexp might
493+
* contain a value != KTIME_MAX even if it was not the
494+
* final top level. This is not a problem, as the worst
495+
* outcome is a CPU which might wake up a little early.
518496
* @evt: Pointer to tmigr_event which needs to be queued (of idle
519497
* child group)
520498
* @childmask: childmask of child group
521499
* @remote: Is set, when the new timer path is executed in
522500
* tmigr_handle_remote_cpu()
523-
*/
524-
struct tmigr_walk {
525-
u64 nextexp;
526-
u64 firstexp;
527-
struct tmigr_event *evt;
528-
u8 childmask;
529-
bool remote;
530-
};
531-
532-
/**
533-
* struct tmigr_remote_data - data required for remote expiry hierarchy walk
534501
* @basej: timer base in jiffies
535502
* @now: timer base monotonic
536-
* @firstexp: returns expiry of the first timer in the idle timer
537-
* migration hierarchy to make sure the timer is handled in
538-
* time; it is stored in the per CPU tmigr_cpu struct of
539-
* CPU which expires remote timers
540-
* @childmask: childmask of child group
541503
* @check: is set if there is the need to handle remote timers;
542504
* required in tmigr_requires_handle_remote() only
543505
* @tmc_active: this flag indicates, whether the CPU which triggers
@@ -546,15 +508,43 @@ struct tmigr_walk {
546508
* idle, only the first event of the top level has to be
547509
* considered.
548510
*/
549-
struct tmigr_remote_data {
550-
unsigned long basej;
551-
u64 now;
552-
u64 firstexp;
553-
u8 childmask;
554-
bool check;
555-
bool tmc_active;
511+
struct tmigr_walk {
512+
u64 nextexp;
513+
u64 firstexp;
514+
struct tmigr_event *evt;
515+
u8 childmask;
516+
bool remote;
517+
unsigned long basej;
518+
u64 now;
519+
bool check;
520+
bool tmc_active;
556521
};
557522

523+
typedef bool (*up_f)(struct tmigr_group *, struct tmigr_group *, struct tmigr_walk *);
524+
525+
static void __walk_groups(up_f up, struct tmigr_walk *data,
526+
struct tmigr_cpu *tmc)
527+
{
528+
struct tmigr_group *child = NULL, *group = tmc->tmgroup;
529+
530+
do {
531+
WARN_ON_ONCE(group->level >= tmigr_hierarchy_levels);
532+
533+
if (up(group, child, data))
534+
break;
535+
536+
child = group;
537+
group = group->parent;
538+
} while (group);
539+
}
540+
541+
static void walk_groups(up_f up, struct tmigr_walk *data, struct tmigr_cpu *tmc)
542+
{
543+
lockdep_assert_held(&tmc->lock);
544+
545+
__walk_groups(up, data, tmc);
546+
}
547+
558548
/*
559549
* Returns the next event of the timerqueue @group->events
560550
*
@@ -625,10 +615,9 @@ static u64 tmigr_next_groupevt_expires(struct tmigr_group *group)
625615

626616
static bool tmigr_active_up(struct tmigr_group *group,
627617
struct tmigr_group *child,
628-
void *ptr)
618+
struct tmigr_walk *data)
629619
{
630620
union tmigr_state curstate, newstate;
631-
struct tmigr_walk *data = ptr;
632621
bool walk_done;
633622
u8 childmask;
634623

@@ -867,10 +856,8 @@ bool tmigr_update_events(struct tmigr_group *group, struct tmigr_group *child,
867856

868857
static bool tmigr_new_timer_up(struct tmigr_group *group,
869858
struct tmigr_group *child,
870-
void *ptr)
859+
struct tmigr_walk *data)
871860
{
872-
struct tmigr_walk *data = ptr;
873-
874861
return tmigr_update_events(group, child, data);
875862
}
876863

@@ -1002,9 +989,8 @@ static void tmigr_handle_remote_cpu(unsigned int cpu, u64 now,
1002989

1003990
static bool tmigr_handle_remote_up(struct tmigr_group *group,
1004991
struct tmigr_group *child,
1005-
void *ptr)
992+
struct tmigr_walk *data)
1006993
{
1007-
struct tmigr_remote_data *data = ptr;
1008994
struct tmigr_event *evt;
1009995
unsigned long jif;
1010996
u8 childmask;
@@ -1062,7 +1048,7 @@ static bool tmigr_handle_remote_up(struct tmigr_group *group,
10621048
void tmigr_handle_remote(void)
10631049
{
10641050
struct tmigr_cpu *tmc = this_cpu_ptr(&tmigr_cpu);
1065-
struct tmigr_remote_data data;
1051+
struct tmigr_walk data;
10661052

10671053
if (tmigr_is_not_available(tmc))
10681054
return;
@@ -1104,9 +1090,8 @@ void tmigr_handle_remote(void)
11041090

11051091
static bool tmigr_requires_handle_remote_up(struct tmigr_group *group,
11061092
struct tmigr_group *child,
1107-
void *ptr)
1093+
struct tmigr_walk *data)
11081094
{
1109-
struct tmigr_remote_data *data = ptr;
11101095
u8 childmask;
11111096

11121097
childmask = data->childmask;
@@ -1164,7 +1149,7 @@ static bool tmigr_requires_handle_remote_up(struct tmigr_group *group,
11641149
bool tmigr_requires_handle_remote(void)
11651150
{
11661151
struct tmigr_cpu *tmc = this_cpu_ptr(&tmigr_cpu);
1167-
struct tmigr_remote_data data;
1152+
struct tmigr_walk data;
11681153
unsigned long jif;
11691154
bool ret = false;
11701155

@@ -1252,10 +1237,9 @@ u64 tmigr_cpu_new_timer(u64 nextexp)
12521237

12531238
static bool tmigr_inactive_up(struct tmigr_group *group,
12541239
struct tmigr_group *child,
1255-
void *ptr)
1240+
struct tmigr_walk *data)
12561241
{
12571242
union tmigr_state curstate, newstate, childstate;
1258-
struct tmigr_walk *data = ptr;
12591243
bool walk_done;
12601244
u8 childmask;
12611245

0 commit comments

Comments
 (0)