From 2d027fd7de3fb2ef6a223d03e060d04dc5d9c84c 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 d87033c5..18246222 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)