Skip to content

Commit d7c36d6

Browse files
arndbfbq
authored andcommitted
locking/lockdep: Avoid struct return in lock_stats()
Returning a large structure from the lock_stats() function causes clang to have multiple copies of it on the stack and copy between them, which can end up exceeding the frame size warning limit: kernel/locking/lockdep.c:300:25: error: stack frame size (1464) exceeds limit (1280) in 'lock_stats' [-Werror,-Wframe-larger-than] 300 | struct lock_class_stats lock_stats(struct lock_class *class) Change the calling conventions to directly operate on the caller's copy, which apparently is what gcc does already. Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Boqun Feng <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f84a15b commit d7c36d6

File tree

3 files changed

+14
-17
lines changed

3 files changed

+14
-17
lines changed

include/linux/lockdep_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ struct lock_class_stats {
175175
unsigned long bounces[nr_bounce_types];
176176
};
177177

178-
struct lock_class_stats lock_stats(struct lock_class *class);
178+
void lock_stats(struct lock_class *class, struct lock_class_stats *stats);
179179
void clear_lock_stats(struct lock_class *class);
180180
#endif
181181

kernel/locking/lockdep.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -297,33 +297,30 @@ static inline void lock_time_add(struct lock_time *src, struct lock_time *dst)
297297
dst->nr += src->nr;
298298
}
299299

300-
struct lock_class_stats lock_stats(struct lock_class *class)
300+
void lock_stats(struct lock_class *class, struct lock_class_stats *stats)
301301
{
302-
struct lock_class_stats stats;
303302
int cpu, i;
304303

305-
memset(&stats, 0, sizeof(struct lock_class_stats));
304+
memset(stats, 0, sizeof(struct lock_class_stats));
306305
for_each_possible_cpu(cpu) {
307306
struct lock_class_stats *pcs =
308307
&per_cpu(cpu_lock_stats, cpu)[class - lock_classes];
309308

310-
for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++)
311-
stats.contention_point[i] += pcs->contention_point[i];
309+
for (i = 0; i < ARRAY_SIZE(stats->contention_point); i++)
310+
stats->contention_point[i] += pcs->contention_point[i];
312311

313-
for (i = 0; i < ARRAY_SIZE(stats.contending_point); i++)
314-
stats.contending_point[i] += pcs->contending_point[i];
312+
for (i = 0; i < ARRAY_SIZE(stats->contending_point); i++)
313+
stats->contending_point[i] += pcs->contending_point[i];
315314

316-
lock_time_add(&pcs->read_waittime, &stats.read_waittime);
317-
lock_time_add(&pcs->write_waittime, &stats.write_waittime);
315+
lock_time_add(&pcs->read_waittime, &stats->read_waittime);
316+
lock_time_add(&pcs->write_waittime, &stats->write_waittime);
318317

319-
lock_time_add(&pcs->read_holdtime, &stats.read_holdtime);
320-
lock_time_add(&pcs->write_holdtime, &stats.write_holdtime);
318+
lock_time_add(&pcs->read_holdtime, &stats->read_holdtime);
319+
lock_time_add(&pcs->write_holdtime, &stats->write_holdtime);
321320

322-
for (i = 0; i < ARRAY_SIZE(stats.bounces); i++)
323-
stats.bounces[i] += pcs->bounces[i];
321+
for (i = 0; i < ARRAY_SIZE(stats->bounces); i++)
322+
stats->bounces[i] += pcs->bounces[i];
324323
}
325-
326-
return stats;
327324
}
328325

329326
void clear_lock_stats(struct lock_class *class)

kernel/locking/lockdep_proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ static int lock_stat_open(struct inode *inode, struct file *file)
657657
if (!test_bit(idx, lock_classes_in_use))
658658
continue;
659659
iter->class = class;
660-
iter->stats = lock_stats(class);
660+
lock_stats(class, &iter->stats);
661661
iter++;
662662
}
663663

0 commit comments

Comments
 (0)