From 6ff9fd39fab7cdb9d8dc2c3870f6350b648f5f6a Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 4 Nov 2025 13:37:32 -0800 Subject: [PATCH] Don't stack alloc struct scoutfs_quorum_block_event old The size of this thing is well over 1kb, and the compiler will error on several supported distributions that this particular function reaches over 2k stack frame size, which is excessive, even for a function that isn't called regularly. We can allocate the thing in one go if we smartly allocate this as an array of (an array of structs) which allows us to index it as a 2d array as before, taking away some of the additional complexities. Signed-off-by: Auke Kok --- kmod/src/quorum.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/kmod/src/quorum.c b/kmod/src/quorum.c index fc25904e..a26d168c 100644 --- a/kmod/src/quorum.c +++ b/kmod/src/quorum.c @@ -542,7 +542,7 @@ int scoutfs_quorum_fence_leaders(struct super_block *sb, struct scoutfs_quorum_c u64 term) { #define NR_OLD 2 - struct scoutfs_quorum_block_event old[SCOUTFS_QUORUM_MAX_SLOTS][NR_OLD] = {{{0,}}}; + struct scoutfs_quorum_block_event (*old)[NR_OLD]; struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb); struct scoutfs_quorum_block blk; struct sockaddr_in sin; @@ -558,13 +558,20 @@ int scoutfs_quorum_fence_leaders(struct super_block *sb, struct scoutfs_quorum_c BUILD_BUG_ON(SCOUTFS_QUORUM_BLOCKS < SCOUTFS_QUORUM_MAX_SLOTS); + old = kmalloc(NR_OLD * SCOUTFS_QUORUM_MAX_SLOTS * sizeof(struct scoutfs_quorum_block_event), GFP_KERNEL); + if (!old) { + ret = -ENOMEM; + goto out; + } + memset(old, 0, NR_OLD * SCOUTFS_QUORUM_MAX_SLOTS * sizeof(struct scoutfs_quorum_block_event)); + for (i = 0; i < SCOUTFS_QUORUM_MAX_SLOTS; i++) { if (!quorum_slot_present(qconf, i)) continue; ret = read_quorum_block(sb, SCOUTFS_QUORUM_BLKNO + i, &blk, false); if (ret < 0) - goto out; + goto out_free; /* elected leader still running */ if (le64_to_cpu(blk.events[SCOUTFS_QUORUM_EVENT_ELECT].term) > @@ -601,11 +608,13 @@ int scoutfs_quorum_fence_leaders(struct super_block *sb, struct scoutfs_quorum_c ret = scoutfs_fence_start(sb, le64_to_cpu(fence_rid), sin.sin_addr.s_addr, SCOUTFS_FENCE_QUORUM_BLOCK_LEADER); if (ret < 0) - goto out; + goto out_free; fence_started = true; } } +out_free: + kfree(old); out: err = scoutfs_fence_wait_fenced(sb, msecs_to_jiffies(SCOUTFS_QUORUM_FENCE_TO_MS)); if (ret == 0)