mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-19 03:31:26 +00:00
Cleanup and clarification of allocation masks handling
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5166 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1947,14 +1947,6 @@ struct scst_cmd {
|
||||
/* Set if cmd is queued as hw pending */
|
||||
unsigned int cmd_hw_pending:1;
|
||||
|
||||
/*
|
||||
* Set, if for this cmd required to not have any IO or FS calls on
|
||||
* memory buffers allocations, at least for READ and WRITE commands.
|
||||
* Needed for cases like file systems mounted over scst_local's
|
||||
* devices.
|
||||
*/
|
||||
unsigned noio_mem_alloc:1;
|
||||
|
||||
/*
|
||||
* Set if the target driver wants to alloc data buffers on its own.
|
||||
* In this case tgt_alloc_data_buf() must be provided in the target
|
||||
@@ -2039,6 +2031,15 @@ struct scst_cmd {
|
||||
/* cmd's async flags */
|
||||
unsigned long cmd_flags;
|
||||
|
||||
/*
|
||||
* GFP mask with which memory on READ or WRITE data path for this cmd
|
||||
* should be allocated, if the current context is not ATOMIC. Useful
|
||||
* for cases like if this cmd required to not have any IO or FS calls
|
||||
* on allocations, like for file systems mounted over scst_local's
|
||||
* devices.
|
||||
*/
|
||||
gfp_t cmd_gfp_mask;
|
||||
|
||||
/* Keeps status of cmd's status/data delivery to remote initiator */
|
||||
int delivery_status;
|
||||
|
||||
@@ -2569,8 +2570,16 @@ struct scst_tgt_dev {
|
||||
struct scst_device *dev; /* to save extra dereferences */
|
||||
uint64_t lun; /* to save extra dereferences */
|
||||
|
||||
gfp_t gfp_mask;
|
||||
/*
|
||||
* Extra flags in GFP mask for data buffers allocations of this
|
||||
* tgt_dev's cmds
|
||||
*/
|
||||
gfp_t tgt_dev_gfp_mask;
|
||||
|
||||
/* SGV pool from which buffers of this tgt_dev's cmds should be allocated */
|
||||
struct sgv_pool *pool;
|
||||
|
||||
/* Max number of allowed in this tgt_dev SG segments */
|
||||
int max_sg_cnt;
|
||||
|
||||
/*************************************************************
|
||||
@@ -3545,16 +3554,13 @@ static inline void scst_cmd_set_tgt_sn(struct scst_cmd *cmd, uint32_t tgt_sn)
|
||||
}
|
||||
|
||||
/*
|
||||
* Get/Set functions for noio_mem_alloc
|
||||
* Forbids for this cmd any IO-causing allocations.
|
||||
*
|
||||
* !! Must be called before scst_cmd_init_done() !!
|
||||
*/
|
||||
static inline bool scst_cmd_get_noio_mem_alloc(struct scst_cmd *cmd)
|
||||
{
|
||||
return cmd->noio_mem_alloc;
|
||||
}
|
||||
|
||||
static inline void scst_cmd_set_noio_mem_alloc(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->noio_mem_alloc = 1;
|
||||
cmd->cmd_gfp_mask = GFP_NOIO;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4082,9 +4088,9 @@ int scst_get_buf_full(struct scst_cmd *cmd, uint8_t **buf);
|
||||
int scst_get_buf_full_sense(struct scst_cmd *cmd, uint8_t **buf);
|
||||
void scst_put_buf_full(struct scst_cmd *cmd, uint8_t *buf);
|
||||
|
||||
static inline gfp_t scst_cmd_get_gfp_flags(struct scst_cmd *cmd)
|
||||
static inline gfp_t scst_cmd_get_gfp_mask(struct scst_cmd *cmd)
|
||||
{
|
||||
return cmd->noio_mem_alloc ? GFP_NOIO : GFP_KERNEL;
|
||||
return cmd->cmd_gfp_mask;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(BACKPORT_LINUX_WORKQUEUE_TO_2_6_19)
|
||||
|
||||
@@ -1034,14 +1034,12 @@ static enum compl_status_e vdisk_synchronize_cache(struct vdisk_cmd_params *p)
|
||||
cmd->completed = 1;
|
||||
cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT,
|
||||
SCST_CONTEXT_SAME);
|
||||
vdisk_fsync(p, loff, data_len, dev,
|
||||
scst_cmd_get_gfp_flags(cmd), NULL, true);
|
||||
vdisk_fsync(p, loff, data_len, dev, cmd->cmd_gfp_mask, NULL, true);
|
||||
/* ToDo: vdisk_fsync() error processing */
|
||||
scst_cmd_put(cmd);
|
||||
res = RUNNING_ASYNC;
|
||||
} else {
|
||||
vdisk_fsync(p, loff, data_len, dev,
|
||||
scst_cmd_get_gfp_flags(cmd), cmd, true);
|
||||
vdisk_fsync(p, loff, data_len, dev, cmd->cmd_gfp_mask, cmd, true);
|
||||
res = RUNNING_ASYNC;
|
||||
}
|
||||
|
||||
@@ -1057,8 +1055,7 @@ static enum compl_status_e vdisk_exec_start_stop(struct vdisk_cmd_params *p)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
vdisk_fsync(p, 0, virt_dev->file_size, dev, scst_cmd_get_gfp_flags(cmd),
|
||||
cmd, false);
|
||||
vdisk_fsync(p, 0, virt_dev->file_size, dev, cmd->cmd_gfp_mask, cmd, false);
|
||||
|
||||
TRACE_EXIT();
|
||||
return CMD_SUCCEEDED;
|
||||
@@ -1472,7 +1469,7 @@ static int fileio_alloc_and_parse(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
p = kmem_cache_zalloc(vdisk_cmd_param_cachep, GFP_KERNEL);
|
||||
p = kmem_cache_zalloc(vdisk_cmd_param_cachep, cmd->cmd_gfp_mask);
|
||||
if (!p) {
|
||||
scst_set_busy(cmd);
|
||||
goto out_err;
|
||||
@@ -2136,7 +2133,7 @@ static int vdisk_unmap_range(struct scst_cmd *cmd,
|
||||
if (virt_dev->blockio) {
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)
|
||||
struct inode *inode = fd->f_dentry->d_inode;
|
||||
gfp_t gfp = scst_cmd_get_gfp_flags(cmd);
|
||||
gfp_t gfp = cmd->cmd_gfp_mask;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)
|
||||
err = blkdev_issue_discard(inode->i_bdev, start_lba, blocks, gfp);
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) \
|
||||
@@ -2373,7 +2370,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
buf = kzalloc(INQ_BUF_SZ, GFP_KERNEL);
|
||||
buf = kzalloc(INQ_BUF_SZ, cmd->cmd_gfp_mask);
|
||||
if (buf == NULL) {
|
||||
scst_set_busy(cmd);
|
||||
goto out;
|
||||
@@ -2934,7 +2931,7 @@ static enum compl_status_e vdisk_exec_mode_sense(struct vdisk_cmd_params *p)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
buf = kzalloc(MSENSE_BUF_SZ, GFP_KERNEL);
|
||||
buf = kzalloc(MSENSE_BUF_SZ, cmd->cmd_gfp_mask);
|
||||
if (buf == NULL) {
|
||||
scst_set_busy(cmd);
|
||||
goto out;
|
||||
@@ -3651,7 +3648,7 @@ static struct iovec *vdisk_alloc_iv(struct scst_cmd *cmd,
|
||||
p->iv_count = 0;
|
||||
/* It can't be called in atomic context */
|
||||
p->iv = (iv_count <= ARRAY_SIZE(p->small_iv)) ? p->small_iv :
|
||||
kmalloc(sizeof(*p->iv) * iv_count, GFP_KERNEL);
|
||||
kmalloc(sizeof(*p->iv) * iv_count, cmd->cmd_gfp_mask);
|
||||
if (p->iv == NULL) {
|
||||
PRINT_ERROR("Unable to allocate iv (%d)", iv_count);
|
||||
goto out;
|
||||
@@ -3924,7 +3921,7 @@ out_sync:
|
||||
/* O_DSYNC flag is used for WT devices */
|
||||
if (p->fua)
|
||||
vdisk_fsync(p, loff, scst_cmd_get_data_len(cmd), cmd->dev,
|
||||
scst_cmd_get_gfp_flags(cmd), cmd, false);
|
||||
cmd->cmd_gfp_mask, cmd, false);
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return CMD_SUCCEEDED;
|
||||
@@ -4027,7 +4024,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
|
||||
int need_new_bio;
|
||||
struct scst_blockio_work *blockio_work;
|
||||
int bios = 0;
|
||||
gfp_t gfp_mask = scst_cmd_get_gfp_flags(cmd);
|
||||
gfp_t gfp_mask = cmd->cmd_gfp_mask;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
|
||||
struct blk_plug plug;
|
||||
#endif
|
||||
@@ -4244,7 +4241,7 @@ static int vdisk_blockio_flush(struct block_device *bdev, gfp_t gfp_mask,
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
|
||||
if (async) {
|
||||
struct bio *bio = bio_alloc(GFP_KERNEL, 0);
|
||||
struct bio *bio = bio_alloc(gfp_mask, 0);
|
||||
if (bio == NULL) {
|
||||
res = -ENOMEM;
|
||||
goto out_rep;
|
||||
@@ -4308,7 +4305,7 @@ static enum compl_status_e fileio_exec_verify(struct vdisk_cmd_params *p)
|
||||
sBUG_ON(virt_dev->blockio);
|
||||
|
||||
if (vdisk_fsync(p, loff, data_len, cmd->dev,
|
||||
scst_cmd_get_gfp_flags(cmd), cmd, false) != 0)
|
||||
cmd->cmd_gfp_mask, cmd, false) != 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
|
||||
@@ -1343,7 +1343,7 @@ static inline void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev) {}
|
||||
int scst_alloc_sense(struct scst_cmd *cmd, int atomic)
|
||||
{
|
||||
int res = 0;
|
||||
gfp_t gfp_mask = atomic ? GFP_ATOMIC : (GFP_KERNEL|__GFP_NOFAIL);
|
||||
gfp_t gfp_mask = atomic ? GFP_ATOMIC : (cmd->cmd_gfp_mask|__GFP_NOFAIL);
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -4482,7 +4482,7 @@ static struct scst_cmd *scst_create_prepare_internal_cmd(
|
||||
{
|
||||
struct scst_cmd *res;
|
||||
int rc;
|
||||
gfp_t gfp_mask = scst_cmd_atomic(orig_cmd) ? GFP_ATOMIC : GFP_KERNEL;
|
||||
gfp_t gfp_mask = scst_cmd_atomic(orig_cmd) ? GFP_ATOMIC : orig_cmd->cmd_gfp_mask;
|
||||
unsigned long flags;
|
||||
|
||||
TRACE_ENTRY();
|
||||
@@ -5318,6 +5318,7 @@ int scst_pre_init_cmd(struct scst_cmd *cmd, const uint8_t *cdb,
|
||||
cmd->start_time = jiffies;
|
||||
atomic_set(&cmd->cmd_ref, 1);
|
||||
cmd->cmd_threads = &scst_main_cmd_threads;
|
||||
cmd->cmd_gfp_mask = GFP_KERNEL;
|
||||
INIT_LIST_HEAD(&cmd->mgmt_cmd_list);
|
||||
cmd->cdb = cmd->cdb_buf;
|
||||
cmd->queue_type = SCST_CMD_QUEUE_SIMPLE;
|
||||
@@ -5652,7 +5653,7 @@ int scst_alloc_space(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
gfp_mask = tgt_dev->gfp_mask | (atomic ? GFP_ATOMIC : GFP_KERNEL);
|
||||
gfp_mask = tgt_dev->tgt_dev_gfp_mask | (atomic ? GFP_ATOMIC : cmd->cmd_gfp_mask);
|
||||
|
||||
flags = atomic ? SGV_POOL_NO_ALLOC_ON_CACHE_MISS : 0;
|
||||
if (cmd->no_sgv)
|
||||
@@ -5933,7 +5934,7 @@ int scst_scsi_exec_async(struct scst_cmd *cmd, void *data,
|
||||
struct request *rq;
|
||||
struct scsi_io_context *sioc;
|
||||
int write = (cmd->data_direction & SCST_DATA_WRITE) ? WRITE : READ;
|
||||
gfp_t gfp = scst_cmd_get_gfp_flags(cmd);
|
||||
gfp_t gfp = cmd->cmd_gfp_mask;
|
||||
int cmd_len = cmd->cdb_len;
|
||||
|
||||
sioc = kmem_cache_zalloc(scsi_io_context_cache, gfp);
|
||||
|
||||
@@ -98,7 +98,7 @@ static inline bool sgv_pool_clustered(const struct sgv_pool *pool)
|
||||
|
||||
void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
tgt_dev->gfp_mask = __GFP_NOWARN;
|
||||
tgt_dev->tgt_dev_gfp_mask = __GFP_NOWARN;
|
||||
tgt_dev->pool = sgv_norm_pool;
|
||||
tgt_dev->tgt_dev_clust_pool = 0;
|
||||
}
|
||||
@@ -106,7 +106,7 @@ void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev)
|
||||
void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
TRACE_MEM("%s", "Use clustering");
|
||||
tgt_dev->gfp_mask = __GFP_NOWARN;
|
||||
tgt_dev->tgt_dev_gfp_mask = __GFP_NOWARN;
|
||||
tgt_dev->pool = sgv_norm_clust_pool;
|
||||
tgt_dev->tgt_dev_clust_pool = 1;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev)
|
||||
void scst_sgv_pool_use_dma(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
TRACE_MEM("%s", "Use ISA DMA memory");
|
||||
tgt_dev->gfp_mask = __GFP_NOWARN | GFP_DMA;
|
||||
tgt_dev->tgt_dev_gfp_mask = __GFP_NOWARN | GFP_DMA;
|
||||
tgt_dev->pool = sgv_dma_pool;
|
||||
tgt_dev->tgt_dev_clust_pool = 0;
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ int scst_rx_cmd_prealloced(struct scst_cmd *cmd, struct scst_session *sess,
|
||||
unsigned int cdb_len, bool atomic)
|
||||
{
|
||||
int res;
|
||||
gfp_t gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
|
||||
gfp_t gfp_mask = atomic ? GFP_ATOMIC : cmd->cmd_gfp_mask;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -273,7 +273,7 @@ struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
|
||||
unsigned int cdb_len, bool atomic)
|
||||
{
|
||||
struct scst_cmd *cmd;
|
||||
gfp_t gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
|
||||
gfp_t gfp_mask = atomic ? GFP_ATOMIC : GFP_NOIO;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -2708,7 +2708,7 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
rc = scst_exec_req(scsi_dev, cmd->cdb, cmd->cdb_len,
|
||||
cmd->data_direction, cmd->sg, cmd->bufflen,
|
||||
cmd->sg_cnt, cmd->timeout, cmd->retries, cmd,
|
||||
scst_pass_through_cmd_done, GFP_KERNEL);
|
||||
scst_pass_through_cmd_done, cmd->cmd_gfp_mask);
|
||||
#else
|
||||
rc = scst_scsi_exec_async(cmd, cmd, scst_pass_through_cmd_done);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user