protected:
uint64_t size = 0;
uint64_t block_size = 0;
+ uint64_t optimal_io_size = 0;
bool support_discard = false;
bool rotational = true;
bool lock_exclusive = true;
uint64_t get_size() const { return size; }
uint64_t get_block_size() const { return block_size; }
+ uint64_t get_optimal_io_size() const { return optimal_io_size; }
/// hook to provide utilization of thinly-provisioned device
virtual bool get_thin_utilization(uint64_t *total, uint64_t *avail) const {
dout(20) << __func__ << " devname " << devname << dendl;
rotational = blkdev_buffered.is_rotational();
support_discard = blkdev_buffered.support_discard();
+ optimal_io_size = blkdev_buffered.get_optimal_io_size();
this->devname = devname;
_detect_vdo();
}
(*pm)[prefix + "rotational"] = stringify((int)(bool)rotational);
(*pm)[prefix + "size"] = stringify(get_size());
(*pm)[prefix + "block_size"] = stringify(get_block_size());
+ (*pm)[prefix + "optimal_io_size"] = stringify(get_optimal_io_size());
(*pm)[prefix + "driver"] = "KernelDevice";
if (rotational) {
(*pm)[prefix + "type"] = "hdd";
return ioctl(fd, BLKDISCARD, range);
}
+int BlkDev::get_optimal_io_size() const
+{
+ return get_int_property("queue/optimal_io_size");
+}
+
bool BlkDev::is_rotational() const
{
return get_int_property("queue/rotational") > 0;
int partition(char* partition, size_t max) const;
// from a device (e.g., "sdb")
bool support_discard() const;
+ int get_optimal_io_size() const;
bool is_rotational() const;
int get_numa_node(int *node) const;
int dev(char *dev, size_t max) const;
flags:
- create
with_legacy: true
+- name: bluestore_use_optimal_io_size_for_min_alloc_size
+ type: bool
+ level: advanced
+ desc: Discover media optimal IO Size and use for min_alloc_size
+ default: false
+ see_also:
+ - bluestore_min_alloc_size
+ flags:
+ - create
+ with_legacy: true
- name: bluestore_max_alloc_size
type: size
level: advanced
if (r < 0) {
goto fail_close;
}
+ // get block dev optimal io size
+ optimal_io_size = bdev->get_optimal_io_size();
return 0;
dout(10) << " freelist_type " << freelist_type << dendl;
// choose min_alloc_size
- if (cct->_conf->bluestore_min_alloc_size) {
+ dout(5) << __func__ << " optimal_io_size 0x" << std::hex << optimal_io_size
+ << " block_size: 0x" << block_size << std::dec << dendl;
+ if ((cct->_conf->bluestore_use_optimal_io_size_for_min_alloc_size) && (optimal_io_size != 0)) {
+ dout(5) << __func__ << " optimal_io_size 0x" << std::hex << optimal_io_size
+ << " for min_alloc_size 0x" << min_alloc_size << std::dec << dendl;
+ min_alloc_size = optimal_io_size;
+ }
+ else if (cct->_conf->bluestore_min_alloc_size) {
min_alloc_size = cct->_conf->bluestore_min_alloc_size;
} else {
ceph_assert(bdev);
goto out_close_bdev;
}
+ // make sure min_alloc_size is >= and aligned with block size
+ if (min_alloc_size % block_size != 0) {
+ derr << __func__ << " min_alloc_size 0x"
+ << std::hex << min_alloc_size
+ << " is less or not aligned with block_size: 0x"
+ << block_size << std::dec << dendl;
+ r = -EINVAL;
+ goto out_close_bdev;
+ }
+
r = _create_alloc();
if (r < 0) {
goto out_close_bdev;
uint64_t block_size = 0; ///< block size of block device (power of 2)
uint64_t block_mask = 0; ///< mask to get just the block offset
size_t block_size_order = 0; ///< bits to shift to get block size
+ uint64_t optimal_io_size = 0;///< best performance io size for block device
uint64_t min_alloc_size; ///< minimum allocation unit (power of 2)
///< bits for min_alloc_size