~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/rust/kernel/block/mq.rs

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 
  3 //! This module provides types for implementing block drivers that interface the
  4 //! blk-mq subsystem.
  5 //!
  6 //! To implement a block device driver, a Rust module must do the following:
  7 //!
  8 //! - Implement [`Operations`] for a type `T`.
  9 //! - Create a [`TagSet<T>`].
 10 //! - Create a [`GenDisk<T>`], via the [`GenDiskBuilder`].
 11 //! - Add the disk to the system by calling [`GenDiskBuilder::build`] passing in
 12 //!   the `TagSet` reference.
 13 //!
 14 //! The types available in this module that have direct C counterparts are:
 15 //!
 16 //! - The [`TagSet`] type that abstracts the C type `struct tag_set`.
 17 //! - The [`GenDisk`] type that abstracts the C type `struct gendisk`.
 18 //! - The [`Request`] type that abstracts the C type `struct request`.
 19 //!
 20 //! The kernel will interface with the block device driver by calling the method
 21 //! implementations of the `Operations` trait.
 22 //!
 23 //! IO requests are passed to the driver as [`kernel::types::ARef<Request>`]
 24 //! instances. The `Request` type is a wrapper around the C `struct request`.
 25 //! The driver must mark end of processing by calling one of the
 26 //! `Request::end`, methods. Failure to do so can lead to deadlock or timeout
 27 //! errors. Please note that the C function `blk_mq_start_request` is implicitly
 28 //! called when the request is queued with the driver.
 29 //!
 30 //! The `TagSet` is responsible for creating and maintaining a mapping between
 31 //! `Request`s and integer ids as well as carrying a pointer to the vtable
 32 //! generated by `Operations`. This mapping is useful for associating
 33 //! completions from hardware with the correct `Request` instance. The `TagSet`
 34 //! determines the maximum queue depth by setting the number of `Request`
 35 //! instances available to the driver, and it determines the number of queues to
 36 //! instantiate for the driver. If possible, a driver should allocate one queue
 37 //! per core, to keep queue data local to a core.
 38 //!
 39 //! One `TagSet` instance can be shared between multiple `GenDisk` instances.
 40 //! This can be useful when implementing drivers where one piece of hardware
 41 //! with one set of IO resources are represented to the user as multiple disks.
 42 //!
 43 //! One significant difference between block device drivers implemented with
 44 //! these Rust abstractions and drivers implemented in C, is that the Rust
 45 //! drivers have to own a reference count on the `Request` type when the IO is
 46 //! in flight. This is to ensure that the C `struct request` instances backing
 47 //! the Rust `Request` instances are live while the Rust driver holds a
 48 //! reference to the `Request`. In addition, the conversion of an integer tag to
 49 //! a `Request` via the `TagSet` would not be sound without this bookkeeping.
 50 //!
 51 //! [`GenDisk`]: gen_disk::GenDisk
 52 //! [`GenDisk<T>`]: gen_disk::GenDisk
 53 //! [`GenDiskBuilder`]: gen_disk::GenDiskBuilder
 54 //! [`GenDiskBuilder::build`]: gen_disk::GenDiskBuilder::build
 55 //!
 56 //! # Example
 57 //!
 58 //! ```rust
 59 //! use kernel::{
 60 //!     alloc::flags,
 61 //!     block::mq::*,
 62 //!     new_mutex,
 63 //!     prelude::*,
 64 //!     sync::{Arc, Mutex},
 65 //!     types::{ARef, ForeignOwnable},
 66 //! };
 67 //!
 68 //! struct MyBlkDevice;
 69 //!
 70 //! #[vtable]
 71 //! impl Operations for MyBlkDevice {
 72 //!
 73 //!     fn queue_rq(rq: ARef<Request<Self>>, _is_last: bool) -> Result {
 74 //!         Request::end_ok(rq);
 75 //!         Ok(())
 76 //!     }
 77 //!
 78 //!     fn commit_rqs() {}
 79 //! }
 80 //!
 81 //! let tagset: Arc<TagSet<MyBlkDevice>> =
 82 //!     Arc::pin_init(TagSet::new(1, 256, 1), flags::GFP_KERNEL)?;
 83 //! let mut disk = gen_disk::GenDiskBuilder::new()
 84 //!     .capacity_sectors(4096)
 85 //!     .build(format_args!("myblk"), tagset)?;
 86 //!
 87 //! # Ok::<(), kernel::error::Error>(())
 88 //! ```
 89 
 90 pub mod gen_disk;
 91 mod operations;
 92 mod raw_writer;
 93 mod request;
 94 mod tag_set;
 95 
 96 pub use operations::Operations;
 97 pub use request::Request;
 98 pub use tag_set::TagSet;

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php