Skip to content

Commit f468cf5

Browse files
committed
Merge tag 'bitmap-for-6.19' of github.com:/norov/linux
Pull bitmap updates from Yury Norov: - Runtime field_{get,prep}() (Geert) - Rust ID pool updates (Alice) - min_t() simplification (David) - __sw_hweightN kernel-doc fixes (Andy) - cpumask.h headers cleanup (Andy) * tag 'bitmap-for-6.19' of github.com:/norov/linux: (32 commits) rust_binder: use bitmap for allocation of handles rust: id_pool: do not immediately acquire new ids rust: id_pool: do not supply starting capacity rust: id_pool: rename IdPool::new() to with_capacity() rust: bitmap: add BitmapVec::new_inline() rust: bitmap: add MAX_LEN and MAX_INLINE_LEN constants cpumask: Don't use "proxy" headers soc: renesas: Use bitfield helpers clk: renesas: Use bitfield helpers ALSA: usb-audio: Convert to common field_{get,prep}() helpers soc: renesas: rz-sysc: Convert to common field_get() helper pinctrl: ma35: Convert to common field_{get,prep}() helpers iio: mlx90614: Convert to common field_{get,prep}() helpers iio: dac: Convert to common field_prep() helper gpio: aspeed: Convert to common field_{get,prep}() helpers EDAC/ie31200: Convert to common field_get() helper crypto: qat - convert to common field_get() helper clk: at91: Convert to common field_{get,prep}() helpers bitfield: Add non-constant field_{prep,get}() helpers bitfield: Add less-checking __FIELD_{GET,PREP}() ...
2 parents 309e490 + 5ba7119 commit f468cf5

23 files changed

Lines changed: 302 additions & 141 deletions

File tree

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4432,6 +4432,7 @@ F: arch/*/lib/bitops.c
44324432
F: include/asm-generic/bitops
44334433
F: include/asm-generic/bitops.h
44344434
F: include/linux/bitops.h
4435+
F: lib/hweight.c
44354436
F: lib/test_bitops.c
44364437
F: tools/*/bitops*
44374438

arch/x86/include/asm/cpumask.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#ifndef _ASM_X86_CPUMASK_H
33
#define _ASM_X86_CPUMASK_H
44
#ifndef __ASSEMBLER__
5+
6+
#include <linux/compiler.h>
57
#include <linux/cpumask.h>
68

79
extern void setup_cpu_local_masks(void);

drivers/android/binder/process.rs

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use kernel::{
1919
cred::Credential,
2020
error::Error,
2121
fs::file::{self, File},
22+
id_pool::IdPool,
2223
list::{List, ListArc, ListArcField, ListLinks},
2324
mm,
2425
prelude::*,
@@ -394,6 +395,8 @@ kernel::list::impl_list_item! {
394395
struct ProcessNodeRefs {
395396
/// Used to look up nodes using the 32-bit id that this process knows it by.
396397
by_handle: RBTree<u32, ListArc<NodeRefInfo, { NodeRefInfo::LIST_PROC }>>,
398+
/// Used to quickly find unused ids in `by_handle`.
399+
handle_is_present: IdPool,
397400
/// Used to look up nodes without knowing their local 32-bit id. The usize is the address of
398401
/// the underlying `Node` struct as returned by `Node::global_id`.
399402
by_node: RBTree<usize, u32>,
@@ -408,6 +411,7 @@ impl ProcessNodeRefs {
408411
fn new() -> Self {
409412
Self {
410413
by_handle: RBTree::new(),
414+
handle_is_present: IdPool::new(),
411415
by_node: RBTree::new(),
412416
freeze_listeners: RBTree::new(),
413417
}
@@ -802,7 +806,7 @@ impl Process {
802806
pub(crate) fn insert_or_update_handle(
803807
self: ArcBorrow<'_, Process>,
804808
node_ref: NodeRef,
805-
is_mananger: bool,
809+
is_manager: bool,
806810
) -> Result<u32> {
807811
{
808812
let mut refs = self.node_refs.lock();
@@ -821,7 +825,33 @@ impl Process {
821825
let reserve2 = RBTreeNodeReservation::new(GFP_KERNEL)?;
822826
let info = UniqueArc::new_uninit(GFP_KERNEL)?;
823827

824-
let mut refs = self.node_refs.lock();
828+
let mut refs_lock = self.node_refs.lock();
829+
let mut refs = &mut *refs_lock;
830+
831+
let (unused_id, by_handle_slot) = loop {
832+
// ID 0 may only be used by the manager.
833+
let start = if is_manager { 0 } else { 1 };
834+
835+
if let Some(res) = refs.handle_is_present.find_unused_id(start) {
836+
match refs.by_handle.entry(res.as_u32()) {
837+
rbtree::Entry::Vacant(entry) => break (res, entry),
838+
rbtree::Entry::Occupied(_) => {
839+
pr_err!("Detected mismatch between handle_is_present and by_handle");
840+
res.acquire();
841+
kernel::warn_on!(true);
842+
return Err(EINVAL);
843+
}
844+
}
845+
}
846+
847+
let grow_request = refs.handle_is_present.grow_request().ok_or(ENOMEM)?;
848+
drop(refs_lock);
849+
let resizer = grow_request.realloc(GFP_KERNEL)?;
850+
refs_lock = self.node_refs.lock();
851+
refs = &mut *refs_lock;
852+
refs.handle_is_present.grow(resizer);
853+
};
854+
let handle = unused_id.as_u32();
825855

826856
// Do a lookup again as node may have been inserted before the lock was reacquired.
827857
if let Some(handle_ref) = refs.by_node.get(&node_ref.node.global_id()) {
@@ -831,20 +861,9 @@ impl Process {
831861
return Ok(handle);
832862
}
833863

834-
// Find id.
835-
let mut target: u32 = if is_mananger { 0 } else { 1 };
836-
for handle in refs.by_handle.keys() {
837-
if *handle > target {
838-
break;
839-
}
840-
if *handle == target {
841-
target = target.checked_add(1).ok_or(ENOMEM)?;
842-
}
843-
}
844-
845864
let gid = node_ref.node.global_id();
846865
let (info_proc, info_node) = {
847-
let info_init = NodeRefInfo::new(node_ref, target, self.into());
866+
let info_init = NodeRefInfo::new(node_ref, handle, self.into());
848867
match info.pin_init_with(info_init) {
849868
Ok(info) => ListArc::pair_from_pin_unique(info),
850869
// error is infallible
@@ -865,9 +884,10 @@ impl Process {
865884
// `info_node` into the right node's `refs` list.
866885
unsafe { info_proc.node_ref2().node.insert_node_info(info_node) };
867886

868-
refs.by_node.insert(reserve1.into_node(gid, target));
869-
refs.by_handle.insert(reserve2.into_node(target, info_proc));
870-
Ok(target)
887+
refs.by_node.insert(reserve1.into_node(gid, handle));
888+
by_handle_slot.insert(info_proc, reserve2);
889+
unused_id.acquire();
890+
Ok(handle)
871891
}
872892

873893
pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult<NodeRef> {
@@ -932,6 +952,16 @@ impl Process {
932952
let id = info.node_ref().node.global_id();
933953
refs.by_handle.remove(&handle);
934954
refs.by_node.remove(&id);
955+
refs.handle_is_present.release_id(handle as usize);
956+
957+
if let Some(shrink) = refs.handle_is_present.shrink_request() {
958+
drop(refs);
959+
// This intentionally ignores allocation failures.
960+
if let Ok(new_bitmap) = shrink.realloc(GFP_KERNEL) {
961+
refs = self.node_refs.lock();
962+
refs.handle_is_present.shrink(new_bitmap);
963+
}
964+
}
935965
}
936966
} else {
937967
// All refs are cleared in process exit, so this warning is expected in that case.

drivers/clk/at91/clk-peripheral.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
44
*/
55

6+
#include <linux/bitfield.h>
67
#include <linux/bitops.h>
78
#include <linux/clk-provider.h>
89
#include <linux/clkdev.h>

drivers/clk/at91/pmc.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,6 @@ struct at91_clk_pms {
117117
unsigned int parent;
118118
};
119119

120-
#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
121-
#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
122-
123120
#define ndck(a, s) (a[s - 1].id + 1)
124121
#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
125122

drivers/clk/renesas/clk-div6.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
88
*/
99

10+
#include <linux/bitfield.h>
1011
#include <linux/clk-provider.h>
1112
#include <linux/init.h>
1213
#include <linux/io.h>
@@ -171,8 +172,7 @@ static u8 cpg_div6_clock_get_parent(struct clk_hw *hw)
171172
if (clock->src_mask == 0)
172173
return 0;
173174

174-
hw_index = (readl(clock->reg) & clock->src_mask) >>
175-
__ffs(clock->src_mask);
175+
hw_index = field_get(clock->src_mask, readl(clock->reg));
176176
for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
177177
if (clock->parents[i] == hw_index)
178178
return i;
@@ -191,7 +191,7 @@ static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index)
191191
if (index >= clk_hw_get_num_parents(hw))
192192
return -EINVAL;
193193

194-
src = clock->parents[index] << __ffs(clock->src_mask);
194+
src = field_prep(clock->src_mask, clock->parents[index]);
195195
writel((readl(clock->reg) & ~clock->src_mask) | src, clock->reg);
196196
return 0;
197197
}

drivers/clk/renesas/rcar-gen3-cpg.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,8 @@ static unsigned long cpg_pll_clk_recalc_rate(struct clk_hw *hw,
5454
{
5555
struct cpg_pll_clk *pll_clk = to_pll_clk(hw);
5656
unsigned int mult;
57-
u32 val;
5857

59-
val = readl(pll_clk->pllcr_reg) & CPG_PLLnCR_STC_MASK;
60-
mult = (val >> __ffs(CPG_PLLnCR_STC_MASK)) + 1;
58+
mult = FIELD_GET(CPG_PLLnCR_STC_MASK, readl(pll_clk->pllcr_reg)) + 1;
6159

6260
return parent_rate * mult * pll_clk->fixed_mult;
6361
}
@@ -94,7 +92,7 @@ static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
9492

9593
val = readl(pll_clk->pllcr_reg);
9694
val &= ~CPG_PLLnCR_STC_MASK;
97-
val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK);
95+
val |= FIELD_PREP(CPG_PLLnCR_STC_MASK, mult - 1);
9896
writel(val, pll_clk->pllcr_reg);
9997

10098
for (i = 1000; i; i--) {
@@ -176,11 +174,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
176174
unsigned long parent_rate)
177175
{
178176
struct cpg_z_clk *zclk = to_z_clk(hw);
179-
unsigned int mult;
180-
u32 val;
181-
182-
val = readl(zclk->reg) & zclk->mask;
183-
mult = 32 - (val >> __ffs(zclk->mask));
177+
unsigned int mult = 32 - field_get(zclk->mask, readl(zclk->reg));
184178

185179
return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult,
186180
32 * zclk->fixed_div);
@@ -231,7 +225,8 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
231225
if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
232226
return -EBUSY;
233227

234-
cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask));
228+
cpg_reg_modify(zclk->reg, zclk->mask,
229+
field_prep(zclk->mask, 32 - mult));
235230

236231
/*
237232
* Set KICK bit in FRQCRB to update hardware setting and wait for

drivers/clk/renesas/rcar-gen4-cpg.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
279279
unsigned long parent_rate)
280280
{
281281
struct cpg_z_clk *zclk = to_z_clk(hw);
282-
unsigned int mult;
283-
u32 val;
284-
285-
val = readl(zclk->reg) & zclk->mask;
286-
mult = 32 - (val >> __ffs(zclk->mask));
282+
unsigned int mult = 32 - field_get(zclk->mask, readl(zclk->reg));
287283

288284
return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult,
289285
32 * zclk->fixed_div);
@@ -334,7 +330,8 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
334330
if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
335331
return -EBUSY;
336332

337-
cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask));
333+
cpg_reg_modify(zclk->reg, zclk->mask,
334+
field_prep(zclk->mask, 32 - mult));
338335

339336
/*
340337
* Set KICK bit in FRQCRB to update hardware setting and wait for

drivers/crypto/intel/qat/qat_common/adf_pm_dbgfs_utils.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/* Copyright(c) 2025 Intel Corporation */
3+
#include <linux/bitfield.h>
34
#include <linux/bitops.h>
45
#include <linux/sprintf.h>
56
#include <linux/string_helpers.h>
67

78
#include "adf_pm_dbgfs_utils.h"
89

9-
/*
10-
* This is needed because a variable is used to index the mask at
11-
* pm_scnprint_table(), making it not compile time constant, so the compile
12-
* asserts from FIELD_GET() or u32_get_bits() won't be fulfilled.
13-
*/
14-
#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
15-
1610
#define PM_INFO_MAX_KEY_LEN 21
1711

1812
static int pm_scnprint_table(char *buff, const struct pm_status_row *table,

drivers/edac/ie31200_edac.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* but lo_hi_readq() ensures that we are safe across all e3-1200 processors.
4545
*/
4646

47+
#include <linux/bitfield.h>
4748
#include <linux/module.h>
4849
#include <linux/init.h>
4950
#include <linux/pci.h>
@@ -139,9 +140,6 @@
139140
#define IE31200_CAPID0_DDPCD BIT(6)
140141
#define IE31200_CAPID0_ECC BIT(1)
141142

142-
/* Non-constant mask variant of FIELD_GET() */
143-
#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
144-
145143
static int nr_channels;
146144
static struct pci_dev *mci_pdev;
147145
static int ie31200_registered = 1;

0 commit comments

Comments
 (0)