From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from sphereful.davidgow.net (sphereful.davidgow.net [203.29.242.92]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDB6A455171 for ; Fri, 21 Aug 2026 09:19:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.242.92 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787303984; cv=none; b=FF3EZqWqXtlLKyXzMPAvFkkXCyIc5+Snwqv8qvMfoTVuKOKnPpIrNElPWGyQaEA4wEW5EZEOKJS6PYc88LTrqjs5lZ+GkZpHBznDcw7EM7yOz9xDTXfpcUC/3IidYiCJT7KJbG3OgLHddo0plF+YgtqnE4Q1VzCfQ64DvRsDMkk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787303984; c=relaxed/simple; bh=KhfaCxu9CYcfTGiFUzZp+0lIyY4vQ25s9e5pWtaA4wA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=fV9xv0lidlDdc8yA425yIGiXAxnAqfKJkF2Vwaoihe38iaWTtzFqTIhfu1PacXsdhNZq0YHdVDiekI92OpT8RVfZtpmwbIgLESJ5GQ7bWfIcp0dhENMsA6gNkkRcsn8NMZpd3ZvKKKkZILyaOQJLcUoev1FL88icHAuGHge+Qq0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ingeniumdigital.com; spf=fail smtp.mailfrom=ingeniumdigital.com; arc=none smtp.client-ip=203.29.242.92 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ingeniumdigital.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=ingeniumdigital.com Received: by sphereful.davidgow.net (Postfix, from userid 119) id E22941EAA59; Fri, 21 Aug 2026 17:19:32 +0800 (AWST) X-Spam-Level: Received: from shelley.lan (unknown [IPv6:2001:8003:8802:7000::41b]) by sphereful.davidgow.net (Postfix) with ESMTPSA id 689E11EAA47; Fri, 21 Aug 2026 17:19:29 +0800 (AWST) From: David Gow To: Jim Cromie , "Maciej W . Rozycki" , Andrew Morton , Matthew Auld , Arun Pravin , Joel Fernandes , David Airlie , Simona Vetter Cc: David Gow , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] linux/log2.h: Add round{up,down}_pow_of_two64() Date: Fri, 21 Aug 2026 17:19:14 +0800 Message-ID: <20260821091918.1902032-1-david@ingeniumdigital.com> X-Mailer: git-send-email 2.55.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: David Gow The existing roundup_pow_of_two() and rounddown_pow_of_two() functions work on values of type unsigned long, which is 32-bit on 32-bit systems. There are cases (most notably in the GPU buddy allocator) which always operate on 64-bit values (as a 32-bit host can still use a GPU which internally has 64-bit addresses). Add a version of these which always operate on a 64-bit value. These have the (unimaginative) names roundup_pow_of_two64() and rounddown_pow_of_two64(), and otherwise work identically to their unsigned long counterparts. They are a bit ugly, but better than everyone hardcoding calls to ilog2() -- which does handle 64-bit values -- directly. Signed-off-by: David Gow --- Hi all, This series is basically a reworked and rebased version of https://lore.kernel.org/all/20260326185413.1205870-40-jim.cromie@gmail.com/ Most importantly, the drm_test_buddy_alloc_exceeds_max_order KUnit test was failing in linux-next on 32-bit systems, which this series fixes. In rebasing it, I decided to add these helper functions, rather than having an open-coded round{up,down} implementation in the buddy allocator, but if no-one thinks it's worth having these for (at the moment) just one user, I'm not too worried either way. Cheers, -- David --- include/linux/log2.h | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/include/linux/log2.h b/include/linux/log2.h index e17ceb32e0c9..67446d5ce9a3 100644 --- a/include/linux/log2.h +++ b/include/linux/log2.h @@ -195,6 +195,63 @@ unsigned long __rounddown_pow_of_two(unsigned long n) __rounddown_pow_of_two(n) \ ) +/** + * __rounddown_pow_of_two64() - round a 64-bit value down to nearest power of two + * @n: value to round up + */ +static inline __attribute_const__ +u64 __rounddown_pow_of_two64(u64 n) +{ + return 1ULL << ilog2(n); +} + +/** + * rounddown_pow_of_two64 - round a 64-bit value down to nearest power of two + * @n: parameter + * + * round the given value down to the nearest power of two + * - this always operates on 64-bit values, even on 32-bit systems + * - the result is undefined when n == 0 + * - this can be used to initialise global variables from constant data + */ +#define rounddown_pow_of_two64(n) \ +( \ + __builtin_constant_p(n) ? ( \ + ((n) == 1) ? 1ULL : \ + (1ULL << ilog2((n))) \ + ) : \ + __rounddown_pow_of_two64(n) \ +) + + +/** + * __roundup_pow_of_two64() - round a 64-bit value up to nearest power of two + * @n: value to round up + */ +static inline __attribute_const__ +u64 __roundup_pow_of_two64(u64 n) +{ + return 1ULL << (ilog2(n - 1) + 1); +} + +/** + * roundup_pow_of_two64 - round a 64-bit value up to nearest power of two + * @n: parameter + * + * round the given value up to the nearest power of two + * - this always operates on 64-bit values, even on 32-bit systems + * - the result is undefined when n == 0 + * - this can be used to initialise global variables from constant data + */ +#define roundup_pow_of_two64(n) \ +( \ + __builtin_constant_p(n) ? ( \ + ((n) == 1) ? 1ULL : \ + (1ULL << (ilog2((n) - 1) + 1)) \ + ) : \ + __roundup_pow_of_two64(n) \ +) + static inline __attribute_const__ int __order_base_2(unsigned long n) { -- 2.55.0