Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -4459,7 +4459,7 @@ EXPORT_SYMBOL(blk_mq_destroy_queue);

struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set,
struct queue_limits *lim, void *queuedata,
struct lock_class_key *lkclass)
struct gendisk_lkclass *lkclass)
{
struct request_queue *q;
struct gendisk *disk;
Expand All @@ -4480,7 +4480,7 @@ struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set,
EXPORT_SYMBOL(__blk_mq_alloc_disk);

struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
struct lock_class_key *lkclass)
struct gendisk_lkclass *lkclass)
{
struct gendisk *disk;

Expand Down
2 changes: 1 addition & 1 deletion block/blk.h
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ void drop_partition(struct block_device *part);
void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors);

struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
struct lock_class_key *lkclass);
struct gendisk_lkclass *lkclass);
struct request_queue *blk_alloc_queue(struct queue_limits *lim, int node_id);

int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode);
Expand Down
8 changes: 4 additions & 4 deletions block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,7 @@ dev_t part_devt(struct gendisk *disk, u8 partno)
}

struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
struct lock_class_key *lkclass)
struct gendisk_lkclass *lkclass)
{
struct gendisk *disk;

Expand All @@ -1467,7 +1467,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
goto out_free_bdi;

disk->node_id = node_id;
mutex_init(&disk->open_mutex);
mutex_init_with_key(&disk->open_mutex, &lkclass->open_mutex_lkclass);
xa_init(&disk->part_tbl);
if (xa_insert(&disk->part_tbl, 0, disk->part0, GFP_KERNEL))
goto out_destroy_part_tbl;
Expand All @@ -1482,7 +1482,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
device_initialize(disk_to_dev(disk));
inc_diskseq(disk);
q->disk = disk;
lockdep_init_map(&disk->lockdep_map, "(bio completion)", lkclass, 0);
lockdep_init_map(&disk->lockdep_map, "(bio completion)", &lkclass->bio_lkclass, 0);
#ifdef CONFIG_BLOCK_HOLDER_DEPRECATED
INIT_LIST_HEAD(&disk->slave_bdevs);
#endif
Expand Down Expand Up @@ -1510,7 +1510,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
}

struct gendisk *__blk_alloc_disk(struct queue_limits *lim, int node,
struct lock_class_key *lkclass)
struct gendisk_lkclass *lkclass)
{
struct queue_limits default_lim = { };
struct request_queue *q;
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/rnull/rnull.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl NullBlkDevice {
.logical_block_size(block_size)?
.physical_block_size(block_size)?
.rotational(rotational)
.build(fmt!("{}", name.to_str()?), tagset, queue_data)
.build(fmt!("{}", name.to_str()?), tagset, queue_data, kernel::my_gendisk_lkclass!())
}
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static DEFINE_MUTEX(sd_mutex_lock);
static mempool_t *sd_page_pool;
static mempool_t *sd_large_page_pool;
static atomic_t sd_large_page_pool_users = ATOMIC_INIT(0);
static struct lock_class_key sd_bio_compl_lkclass;
static struct gendisk_lkclass sd_bio_compl_lkclass;

static const char *sd_cache_types[] = {
"write through", "none", "write back",
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/sr.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static struct scsi_driver sr_template = {
static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
static DEFINE_SPINLOCK(sr_index_lock);

static struct lock_class_key sr_bio_compl_lkclass;
static struct gendisk_lkclass sr_bio_compl_lkclass;

static int sr_open(struct cdrom_device_info *, int);
static void sr_release(struct cdrom_device_info *);
Expand Down
6 changes: 3 additions & 3 deletions include/linux/blk-mq.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,15 +726,15 @@ enum {

struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set,
struct queue_limits *lim, void *queuedata,
struct lock_class_key *lkclass);
struct gendisk_lkclass *lkclass);
#define blk_mq_alloc_disk(set, lim, queuedata) \
({ \
static struct lock_class_key __key; \
static struct gendisk_lkclass __key; \
\
__blk_mq_alloc_disk(set, lim, queuedata, &__key); \
})
struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
struct lock_class_key *lkclass);
struct gendisk_lkclass *lkclass);
struct request_queue *blk_mq_alloc_queue(struct blk_mq_tag_set *set,
struct queue_limits *lim, void *queuedata);
int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
Expand Down
9 changes: 7 additions & 2 deletions include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ extern const struct device_type disk_type;
extern const struct device_type part_type;
extern const struct class block_class;

struct gendisk_lkclass {
struct lock_class_key bio_lkclass;
struct lock_class_key open_mutex_lkclass;
};

/*
* Maximum number of blkcg policies allowed to be registered concurrently.
* Defined here to simplify include dependency.
Expand Down Expand Up @@ -980,7 +985,7 @@ int bdev_disk_changed(struct gendisk *disk, bool invalidate);

void put_disk(struct gendisk *disk);
struct gendisk *__blk_alloc_disk(struct queue_limits *lim, int node,
struct lock_class_key *lkclass);
struct gendisk_lkclass *lkclass);

/**
* blk_alloc_disk - allocate a gendisk structure
Expand All @@ -996,7 +1001,7 @@ struct gendisk *__blk_alloc_disk(struct queue_limits *lim, int node,
*/
#define blk_alloc_disk(lim, node_id) \
({ \
static struct lock_class_key __key; \
static struct gendisk_lkclass __key; \
\
__blk_alloc_disk(lim, node_id, &__key); \
})
Expand Down
2 changes: 1 addition & 1 deletion rust/kernel/block/mq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
//! Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KERNEL)?;
//! let mut disk = gen_disk::GenDiskBuilder::new()
//! .capacity_sectors(4096)
//! .build(fmt!("myblk"), tagset, ())?;
//! .build(fmt!("myblk"), tagset, (), kernel::my_gendisk_lkclass!())?;
//!
//! # Ok::<(), kernel::error::Error>(())
//! ```
Expand Down
41 changes: 39 additions & 2 deletions rust/kernel/block/mq/gen_disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::{
error::{self, from_err_ptr, Result},
fmt::{self, Write},
prelude::*,
static_lock_class,
str::NullTerminatedFormatter,
sync::Arc,
types::{ForeignOwnable, ScopeGuard},
Expand All @@ -38,6 +37,43 @@ impl Default for GenDiskBuilder {
}
}

/// A wrapper type for safely passing "struct gendisk_lkclass" argument.
///
/// This type can only be instantiated via the [`my_gendisk_lkclass!`] macro.
pub struct GenDiskLockClass(pub(crate) *mut bindings::gendisk_lkclass);

impl GenDiskLockClass {
/// Retrieve the underlying raw pointer.
pub(crate) fn as_ptr(&self) -> *mut bindings::gendisk_lkclass {
self.0
}
}

#[doc(hidden)]
pub mod __internal {
use super::*;

/// Internal constructor used ONLY by the `my_gendisk_lkclass!` macro.
///
/// SAFETY: `ptr` must point to a valid static `gendisk_lkclass` instance.
pub const unsafe fn new_lock_class(ptr: *mut bindings::gendisk_lkclass) -> GenDiskLockClass {
GenDiskLockClass(ptr)
}
}

/// Helper macro to generate a unique caller-local static lock class struct
#[macro_export]
macro_rules! my_gendisk_lkclass {
() => {{
static mut LKCLASS: $crate::bindings::gendisk_lkclass = $crate::bindings::gendisk_lkclass {
bio_lkclass: const { unsafe { ::core::mem::zeroed() } },
open_mutex_lkclass: const { unsafe { ::core::mem::zeroed() } },
};

unsafe { $crate::block::mq::gen_disk::__internal::new_lock_class(&raw mut LKCLASS) }
}};
}

impl GenDiskBuilder {
/// Create a new instance.
pub fn new() -> Self {
Expand Down Expand Up @@ -100,6 +136,7 @@ impl GenDiskBuilder {
name: fmt::Arguments<'_>,
tagset: Arc<TagSet<T>>,
queue_data: T::QueueData,
lkclass: GenDiskLockClass,
) -> Result<GenDisk<T>> {
let data = queue_data.into_foreign();
let recover_data = ScopeGuard::new(|| {
Expand All @@ -121,7 +158,7 @@ impl GenDiskBuilder {
tagset.raw_tag_set(),
&mut lim,
data,
static_lock_class!().as_ptr(),
lkclass.as_ptr(),
)
})?;

Expand Down
Loading