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:
Vladislav Bolkhovitin
2013-12-20 03:41:44 +00:00
parent 4b48ce668b
commit 6cfeda64ca
5 changed files with 47 additions and 43 deletions

View File

@@ -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)

View File

@@ -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;
/*

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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