public inbox for kernel-janitors@vger.kernel.org
 help / color / mirror / Atom feed
* more potential janitor work: simplifying test for power of 2
@ 2026-03-31 11:49 Robert P. J. Day
  2026-04-01 12:16 ` Linus Probert
  0 siblings, 1 reply; 8+ messages in thread
From: Robert P. J. Day @ 2026-03-31 11:49 UTC (permalink / raw)
  To: Kernel Janitors List


  As another example of a cleanup script I wrote lo those many years
ago, this one checked if someone was manually testing if a value was a
power of two (do not make fun of my coding):

#!/bin/sh

DIR=${1-*}

echo "PATTERN:     x & (x - 1):\n"
grep -Ern "([^\(\)]+) ?\& ?\(\1 ?- ?1\)" ${DIR}
echo "PATTERN:     x & ((x) - 1):\n"
grep -Ern "([^\(\)]+) ?\& ?\(\(\1\) ?- ?1\)" ${DIR}
echo "PATTERN:     (x) & (x - 1):\n"
grep -Ern "\(([^\(\)]+)\) ?\& ?\(\1 ?- ?1\)" ${DIR}
echo "PATTERN:     (x) & ((x) - 1):\n"
grep -Ern "\(([^\(\)]+)\) ?\& ?\(\(\1\) ?- ?1\)" ${DIR}

  As you can see, the typical hacky check was to test the value of
some variant of "n & (n - 1)" to see if n was in fact a power of 2.
Note that, when run from the top of the kernel source tree, you can
focus the search on any subdirectory.  There is a ton of this sort of
thing scattered throughout the kernel source; for example:

$ test_for_power_of_2.sh drivers/net/ethernet
PATTERN:     x & (x - 1):

drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c:756:	if (eq->num_elem_in_pg & (eq->num_elem_in_pg - 1)) {
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c:456:	if (num_q_pages & (num_q_pages - 1)) {
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c:523:	if (q_depth & (q_depth - 1)) {
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c:620:	if (q_depth & (q_depth - 1)) {
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c:872:	if (attr->num_cells & (attr->num_cells - 1)) {
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c:691:	if (flags & (flags - 1))
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c:697:	if (flags & (flags - 1))
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c:702:	if (flags & (flags - 1))
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c:709:	if (flags & (flags - 1))
drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_rule.c:680:		byte_mask = byte_mask & (byte_mask - 1);
drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c:163:	if (!length || (length & (length - 1)) ||
drivers/net/ethernet/sfc/siena/siena_sriov.c:505:	return ((buf_count & (buf_count - 1)) || buf_count > max_buf_count);
drivers/net/ethernet/sfc/siena/siena_sriov.c:956:	BUG_ON(vf->evq0_count & (vf->evq0_count - 1));
drivers/net/ethernet/broadcom/bnxt/bnxt.c:4736:	while (pages & (pages - 1))
drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c:1230:#define POWER_OF_2(x)	((0 != x) && (0 == (x & (x-1))))
drivers/net/ethernet/synopsys/dwc-xlgmac-common.c:110:	if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) {
drivers/net/ethernet/synopsys/dwc-xlgmac-common.c:118:	if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) {
drivers/net/ethernet/freescale/fman/fman_keygen.c:700:	if (hash_size == 0 || (hash_size & (hash_size - 1)) != 0) {
drivers/net/ethernet/chelsio/cxgb4/sge.c:5094:	    (fl_large_pg & (fl_large_pg-1)) != 0) {
drivers/net/ethernet/chelsio/cxgb4vf/sge.c:2649:	    (fl_large_pg & (fl_large_pg - 1)) != 0) {
drivers/net/ethernet/chelsio/cxgb/cxgb2.c:657:		if (advertising & (advertising - 1))
drivers/net/ethernet/emulex/benet/be.h:136:	BUG_ON(limit & (limit - 1));
drivers/net/ethernet/intel/igc/igc_leds.c:156:	if (flags & (flags - 1))
drivers/net/ethernet/intel/igc/igc_ethtool.c:1286:	    (rule->filter.match_flags & (rule->filter.match_flags - 1)))
drivers/net/ethernet/intel/fm10k/fm10k_tlv.c:203:	if (!msg || !len || len > 8 || (len & (len - 1)))
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c:1917:	if ((table->mem_table.depth & (table->mem_table.depth - 1)) != 0) {
PATTERN:     x & ((x) - 1):

PATTERN:     (x) & (x - 1):

PATTERN:     (x) & ((x) - 1):

  This can be simplified using the kernel header file
include/linux/log2.h, which defines the test using an exclusive-OR
operation:

/**
 * is_power_of_2() - check if a value is a power of two
 * @n: the value to check
 *
 * Determine whether some value is a power of two, where zero is
 * *not* considered a power of two.
 * Return: true if @n is a power of 2, otherwise false.
 */
static __always_inline __attribute__((const))
bool is_power_of_2(unsigned long n)
{
	return n - 1 < (n ^ (n - 1));
}

  Lots of simplification there if one wants some janitor work; I don't
see a coccinelle test for this.

rday

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-04-02 13:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-31 11:49 more potential janitor work: simplifying test for power of 2 Robert P. J. Day
2026-04-01 12:16 ` Linus Probert
2026-04-02  9:50   ` Linus Probert
2026-04-02 10:07     ` Julia Lawall
2026-04-02 11:57       ` Linus Probert
2026-04-02 12:40         ` Robert P. J. Day
2026-04-02 13:04           ` Linus Probert
2026-04-02 13:21             ` Robert P. J. Day

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox