Split big IO requests
OCF cannot allocate request map bigger than 4MiB (due to kmalloc limitations), thus we need to split bigger IOs into series smaller ones to reduce request map size. Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
88
configure.d/1_bio_split.conf
Normal file
88
configure.d/1_bio_split.conf
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright(c) 2012-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
#
|
||||
|
||||
. $(dirname $3)/conf_framework
|
||||
|
||||
check() {
|
||||
cur_name=$(basename $2)
|
||||
config_file_path=$1
|
||||
if compile_module $cur_name "bio_split(NULL, 0, 0, 0);" "linux/bio.h"
|
||||
then
|
||||
echo $cur_name "1" >> $config_file_path
|
||||
elif compile_module $cur_name "bio_split(NULL, 0);" "linux/bio.h"
|
||||
then
|
||||
echo $cur_name "2" >> $config_file_path
|
||||
else
|
||||
echo $cur_name "X" >> $config_file_path
|
||||
fi
|
||||
}
|
||||
|
||||
apply() {
|
||||
case "$1" in
|
||||
"1")
|
||||
add_function "
|
||||
static inline struct bio *cas_bio_split(struct bio *bio, int sectors)
|
||||
{
|
||||
return bio_split(bio, sectors, GFP_NOIO, NULL);
|
||||
}" ;;
|
||||
"2")
|
||||
add_function "
|
||||
static inline struct bio *cas_bio_split(struct bio *bio, int sectors)
|
||||
{
|
||||
struct bio *split, copy;
|
||||
int bytes = sectors << 9;
|
||||
uint32_t idx, vecs = 0;
|
||||
int ret;
|
||||
|
||||
copy = *bio;
|
||||
copy.bi_io_vec = ©.bi_io_vec[copy.bi_idx];
|
||||
copy.bi_vcnt -= copy.bi_idx;
|
||||
copy.bi_idx = 0;
|
||||
|
||||
BUG_ON(bytes >= bio->bi_size);
|
||||
|
||||
// For simplicity we assume that split is alligned.
|
||||
// Otherwise bvec modification would be required.
|
||||
while (bytes) {
|
||||
if (bytes >= bio_iovec_idx(©, vecs)->bv_len) {
|
||||
bytes -= bio_iovec_idx(©, vecs)->bv_len;
|
||||
vecs++;
|
||||
} else {
|
||||
vecs++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
split = bio_alloc_bioset(GFP_NOIO, vecs, NULL);
|
||||
if (!split)
|
||||
return NULL;
|
||||
|
||||
copy.bi_max_vecs = vecs;
|
||||
__bio_clone(split, ©);
|
||||
split->bi_size = sectors << 9;
|
||||
split->bi_vcnt = vecs;
|
||||
|
||||
if (bio_integrity((©))) {
|
||||
ret = bio_integrity_clone(split, bio, GFP_NOIO);
|
||||
if (ret < 0) {
|
||||
bio_put(split);
|
||||
return NULL;
|
||||
}
|
||||
for (idx = 0, bytes = 0; idx < bio->bi_idx; idx++)
|
||||
bytes += bio_iovec_idx(bio, idx)->bv_len;
|
||||
bio_integrity_trim(split, bytes >> 9, sectors);
|
||||
}
|
||||
|
||||
bio_advance(bio, split->bi_size);
|
||||
|
||||
return split;
|
||||
}" ;;
|
||||
*)
|
||||
exit 1
|
||||
esac
|
||||
}
|
||||
|
||||
conf_run $@
|
||||
Reference in New Issue
Block a user