Re: Changes to Linux/SCSI target mode infrastructure for v2.6.28

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2008-12-02 at 10:39 +0200, Boaz Harrosh wrote:
> Nicholas A. Bellinger wrote:
> > Greetings Tomo-san and Co,
> > 
> > With the ongoing work in Linux/SCSI for v2.6.28 to map target mode
> > struct scatterlist memory directly down to struct scsi_cmnd without the
> > need for a intermediate struct bio as with the existing
> > scsi_execute_async(), I have started the porting process for the
> > Linux/SCSI subsystem plugin in generic target core v3.0
> > (lio-core-2.6.git) on v2.6.28-rc6.
> > 
> > So far, using struct request for ICF_SCSI_CONTROL_NONSG_IO_CDB is up
> > using blk_rq_map_kern(), as well as ICF_SCSI_NON_DATA_CDB ops using
> > struct request.  In order to get the first READ_10s of type
> > ICF_SCSI_DATA_SG_IO_CDB to work, I had to add a temporary
> > EXPORT_SYMBOL_GPL() for drivers/scsi/scsi_lib.c:scsi_req_map_sg() in
> > lio-core-2.6.git for v2.6.28-rc6 in order to get TYPE_DISK up using an
> > software emulated MPT-Fusion HBA driver with struct request.  I have
> > been looking at drivers/scsi/scsi_tgt_lib.c() (which currently uses
> > struct request), and I figure we need something similar for the generic
> > target infrastructure, although __scsi_get_command() and
> > __scsi_put_command() are currently used in that code.
> > 
> > Below is what my patch looks like so far, I will probably just end up
> > commiting an temporary ifdef to keep scsi_execute_async() until the
> > proper pieces are in place and the other issues are resolved below.
> >>From there I will be able to drop in the proper upstream mapping bits
> > for struct scatterlist in
> > drivers/lio-core/target_core_pscsi.c:pscsi_map_task_SG() get rid of
> > scsi_req_map_sg() usage all together.
> > 
> > So far during my initial testing, I am running into a two different
> > exceptions.  One NULL pointer deference OOPS after half dozen Open/iSCSI
> > login/logouts in block/elevator.c:elv_dequeue_request().   Here is the
> > trace from SCSI softirq context:
> > 
> > http://linux-iscsi.org/builds/user/nab/2.6.28-rc6-oops-0.png
> > http://linux-iscsi.org/builds/user/nab/2.6.28-rc6-oops-1.png
> > 
> > The other one is a BUG_ON in blk/blk-timeout.c:177 in blk_add_timeout()
> > that happens after a few hundred MB of READ_10 traffic, which also
> > appears to pass through elv_dequeue_request() at some point:
> > 
> > http://linux-iscsi.org/builds/user/nab/2.6.28-rc6-oops-2.png
> > http://linux-iscsi.org/builds/user/nab/2.6.28-rc6-oops-4.png
> > 
> > Tomo, Boaz, Jens, any comments..?
> > 
> > --nab
> > 
> > diff --git a/drivers/lio-core/target_core_pscsi.c b/drivers/lio-core/target_core_pscsi.c
> > index ed9f588..5161483 100644
> > --- a/drivers/lio-core/target_core_pscsi.c
> > +++ b/drivers/lio-core/target_core_pscsi.c
> > @@ -37,6 +37,7 @@
> >  #include <linux/spinlock.h>
> >  #include <linux/smp_lock.h>
> >  #include <linux/genhd.h>
> > +#include <linux/cdrom.h>
> >  #include <linux/file.h>
> >  
> >  #include <scsi/scsi.h>
> > @@ -44,6 +45,7 @@
> >  #include <scsi/scsi_cmnd.h>
> >  #include <scsi/scsi_host.h>
> >  #include <sd.h>
> > +#include <sr.h>
> >  
> >  #include <iscsi_linux_os.h>
> >  #include <iscsi_linux_defs.h>
> > @@ -763,11 +765,11 @@ extern void *pscsi_allocate_request (
> >  	se_device_t *dev)
> >  {
> >  	pscsi_plugin_task_t *pt;
> > -	if (!(pt = kmalloc(sizeof(pscsi_plugin_task_t), GFP_KERNEL))) {
> > -		TRACE_ERROR("Unable to allocate pscsi_plugin_task_t\n");
> > +	
> > +	if (!(pt = kzalloc(sizeof(pscsi_plugin_task_t), GFP_KERNEL))) {
> > +		printk(KERN_ERR "Unable to allocate pscsi_plugin_task_t\n");
> >  		return(NULL);
> >  	}
> > -	memset(pt, 0, sizeof(pscsi_plugin_task_t));
> >  
> >  	return(pt);
> >  }
> > @@ -788,7 +790,44 @@ extern void pscsi_get_evpd_sn (unsigned char *buf, u32 size, se_device_t *dev)
> >  	return;
> >  }
> >  
> > -/*	pscsi_do_task(): (Part of se_subsystem_api_t template)
> > +static int pscsi_blk_get_request (se_task_t *task)
> > +{
> > +	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> > +	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->iscsi_dev->dev_ptr;
> > +
> > +	pt->pscsi_req = blk_get_request(pdv->pdv_sd->request_queue,
> > +			(pt->pscsi_direction == DMA_TO_DEVICE), GFP_KERNEL);
> > +	if (!(pt->pscsi_req) || IS_ERR(pt->pscsi_req)) {
> > +		printk(KERN_ERR "PSCSI: blk_get_request() failed: %ld\n",
> > +				IS_ERR(pt->pscsi_req));
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +	}
> > +	/*
> > +	 * Defined as "scsi command" in include/linux/blkdev.h.
> > +	 */
> > +	pt->pscsi_req->cmd_type = REQ_TYPE_BLOCK_PC;
> > +	/*
> > +	 * Setup the done function pointer for struct request,
> > +	 * also set the end_io_data pointer.to se_task_t.
> > +	 */
> > +	pt->pscsi_req->end_io = pscsi_req_done;
> > +	pt->pscsi_req->end_io_data = (void *)task;
> > +	/*
> > +	 * Load the referenced se_task_t's SCSI CDB into
> > +	 * include/linux/blkdev.h:struct request->cmd
> > +	 */
> > +	pt->pscsi_req->cmd_len = COMMAND_SIZE(pt->pscsi_cdb[0]);
> > +	memcpy(pt->pscsi_req->cmd, pt->pscsi_cdb, pt->pscsi_req->cmd_len);
> 
> pt->pscsi_cdb is that a static sized buffer? What do you do with larger
> commands received on the iscsi wire. Are they dropped? 

Support for this is on the short-term TODO list for v3.0 in the generic
target engine..

> If you did have
> the full > 16 CDB in some buffer you could do:
> 
> +	pt->pscsi_req->cmd_len = scsi_command_size(pt->pscsi_cdb);
> +	pt->pscsi_req->cmd = pt->pscsi_cdb;
> 

<nod>, the plan is to remove pt->pscsi_cdb[] and use the struct
request->_cmd[] through the subsystem plugin API for the v3.0 generic
target core in lio-core-2.6.git..

> > +	/*
> > +	 * Setup pointer for outgoing sense data.
> > +	 */
> > +	pt->pscsi_req->sense = (void *)&pt->pscsi_sense[0];
> > +	pt->pscsi_req->sense_len = 0;
> > +
> > +	return(0);
> > +}
> > +
> > +/*      pscsi_do_task(): (Part of se_subsystem_api_t template)
> >   *
> >   *
> >   */
> > @@ -796,17 +835,32 @@ extern int pscsi_do_task (se_task_t *task)
> >  {
> >  	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> >  	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->iscsi_dev->dev_ptr;
> > -	int ret;
> > -	
> > -	if ((ret = scsi_execute_async((struct scsi_device *)pdv->pdv_sd,
> > -			   pt->pscsi_cdb, COMMAND_SIZE(pt->pscsi_cdb[0]), pt->pscsi_direction,
> > -			   pt->pscsi_buf, task->task_size, task->task_sg_num,
> > -			   (task->se_obj_api->get_device_type(task->se_obj_ptr) == 0) ?
> > -			   PS_TIMEOUT_DISK : PS_TIMEOUT_OTHER, PS_RETRY,
> > -			   (void *)task, pscsi_req_done, GFP_KERNEL)) != 0) {
> > -		TRACE_ERROR("PSCSI Execute(): returned: %d\n", ret);
> > -		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > -	}	
> > +	struct gendisk *gd = NULL;
> > +	/*
> > +	 * Grab pointer to struct gendisk for TYPE_DISK and TYPE_ROM
> > +	 * cases (eg: cases where struct scsi_device has a backing
> > +	 * struct block_device.  Also set the struct request->timeout
> > +	 * value based on peripheral device type (from SCSI).
> > +	 */
> > +	if (pdv->pdv_sd->type == TYPE_DISK) {
> > +		struct scsi_disk *sdisk = dev_get_drvdata(
> > +					&pdv->pdv_sd->sdev_gendev);
> > +		gd = sdisk->disk;
> > +		pt->pscsi_req->timeout = PS_TIMEOUT_DISK;
> > +	} else if (pdv->pdv_sd->type == TYPE_ROM) {
> > +		struct scsi_cd *scd = dev_get_drvdata(
> > +					&pdv->pdv_sd->sdev_gendev);
> > +		gd = scd->disk;
> > +		pt->pscsi_req->timeout = PS_TIMEOUT_OTHER;
> > +	} else
> > +		pt->pscsi_req->timeout = PS_TIMEOUT_OTHER;
> > +
> > +	pt->pscsi_req->retries = PS_RETRY;
> > +	/*
> > +	 * Queue the struct request into the struct scsi_device->request_queue.
> > +	 */
> > +	blk_execute_rq_nowait(pdv->pdv_sd->request_queue, gd,
> > +			      pt->pscsi_req, 1, pscsi_req_done);
> >  
> >  	return(PYX_TRANSPORT_SENT_TO_TRANSPORT);
> >  }
> > @@ -817,7 +871,14 @@ extern int pscsi_do_task (se_task_t *task)
> >   */
> >  extern void pscsi_free_task (se_task_t *task)
> >  {
> > -	kfree(task->transport_req);
> > +	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> > +
> > +	if (pt->pscsi_req) {
> > +		blk_put_request(pt->pscsi_req);	
> > +		pt->pscsi_req = NULL;
> > +	}
> > +
> > +	kfree(pt);
> >  	return;
> >  }
> >  
> > @@ -1099,31 +1160,65 @@ extern void __pscsi_get_dev_info (pscsi_dev_virt_t *pdv, char *b, int *bl)
> >  	return;
> >  }
> >  
> > -/*	pscsi_map_task_SG(): 
> > +extern int scsi_req_map_sg(struct request *, struct scatterlist *, int,  unsigned , gfp_t );
> > +
> > +/*      pscsi_map_task_SG(): 
> >   *
> >   *
> >   */
> > -extern void pscsi_map_task_SG (se_task_t *task)
> > +extern int pscsi_map_task_SG (se_task_t *task)
> >  {
> >          pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> > +	int ret = 0;
> > +
> >  	pt->pscsi_buf = (void *)task->task_buf;
> >  
> > -	return;
> > +	if (!task->task_size)
> > +		return(0);
> > +#if 0
> > +	if ((ret = blk_rq_map_sg(pdv->pdv_sd->request_queue,
> > +			pt->pscsi_req,
> > +			(struct scatterlist *)pt->pscsi_buf)) < 0) {
> > +		printk(KERN_ERR "PSCSI: blk_rq_map_sg() returned %d\n", ret);
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +	}
> > +#else
> > +	if ((ret = scsi_req_map_sg(pt->pscsi_req,
> > +			(struct scatterlist *)pt->pscsi_buf,
> > +			task->task_sg_num, task->task_size,
> > +			GFP_KERNEL)) < 0) {
> > +		printk(KERN_ERR "PSCSI: scsi_req_map_sg() failed: %d\n", ret);
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +	}
> > +#endif
> > +	return(0);
> >  }
> >  
> >  /*	pscsi_map_task_non_SG():
> >   *
> >   *
> >   */
> > -extern void pscsi_map_task_non_SG (se_task_t *task)
> > +extern int pscsi_map_task_non_SG (se_task_t *task)
> >  {
> >  	iscsi_cmd_t *cmd = task->iscsi_cmd;
> > +	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> > +	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->iscsi_dev->dev_ptr;
> >  	unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
> > +	int ret = 0;
> >  
> > -	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> >  	pt->pscsi_buf = (void *)buf;
> >  
> > -	return;
> > +	if (!task->task_size)
> > +		return(0);
> > +
> > +	if ((ret = blk_rq_map_kern(pdv->pdv_sd->request_queue,
> > +			pt->pscsi_req, pt->pscsi_buf,
> > +			task->task_size, GFP_KERNEL)) < 0) {
> > +		printk(KERN_ERR "PSCSI: blk_rq_map_kern() failed: %d\n", ret);
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +	}
> > +
> > +	return(0);
> >  }
> >  
> >  /*	pscsi_CDB_inquiry():
> > @@ -1135,9 +1230,11 @@ extern int pscsi_CDB_inquiry (se_task_t *task, u32 size)
> >  	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> >  
> >  	pt->pscsi_direction = DMA_FROM_DEVICE;
> > -	pscsi_map_task_non_SG(task);
> > +	
> > +	if (pscsi_blk_get_request(task) < 0)
> > +		return(-1);
> >  
> > -	return(0);
> > +	return(pscsi_map_task_non_SG(task));
> >  }
> >  
> >  extern int pscsi_CDB_none (se_task_t *task, u32 size)
> > @@ -1146,7 +1243,7 @@ extern int pscsi_CDB_none (se_task_t *task, u32 size)
> >  
> >  	pt->pscsi_direction = DMA_NONE;
> >  
> > -	return(0);
> > +	return(pscsi_blk_get_request(task));
> >  }
> >  
> >  /*	pscsi_CDB_read_non_SG():
> > @@ -1158,9 +1255,11 @@ extern int pscsi_CDB_read_non_SG (se_task_t *task, u32 size)
> >  	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> >  
> >  	pt->pscsi_direction = DMA_FROM_DEVICE;
> > -	pscsi_map_task_non_SG(task);
> >  
> > -	return(0);
> > +	if (pscsi_blk_get_request(task) < 0)
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +
> > +	return(pscsi_map_task_non_SG(task));
> >  }
> >  
> >  /*	pscsi_CDB_read_SG():
> > @@ -1172,7 +1271,12 @@ extern int pscsi_CDB_read_SG (se_task_t *task, u32 size)
> >  	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> >  
> >  	pt->pscsi_direction = DMA_FROM_DEVICE;
> > -	pscsi_map_task_SG(task);
> > +
> > +	if (pscsi_blk_get_request(task) < 0)
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +
> > +	if (pscsi_map_task_SG(task) < 0)
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> >  
> >  	return(task->task_sg_num);
> >  }
> > @@ -1186,9 +1290,11 @@ extern int pscsi_CDB_write_non_SG (se_task_t *task, u32 size)
> >  	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> >  
> >  	pt->pscsi_direction = DMA_TO_DEVICE;
> > -	pscsi_map_task_non_SG(task);
> >  
> > -	return(0);
> > +	if (pscsi_blk_get_request(task) < 0)
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +
> > +	return(pscsi_map_task_non_SG(task));
> >  }
> >  
> >  /*	pscsi_CDB_write_SG():
> > @@ -1200,7 +1306,12 @@ extern int pscsi_CDB_write_SG (se_task_t *task, u32 size)
> >  	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
> >  
> >  	pt->pscsi_direction = DMA_TO_DEVICE;
> > -	pscsi_map_task_SG(task);
> > +
> > +	if (pscsi_blk_get_request(task) < 0)
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> > +
> > +	if (pscsi_map_task_SG(task) < 0)
> > +		return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
> >  	
> >  	return(task->task_sg_num);
> >  }
> > @@ -1386,22 +1497,25 @@ extern void pscsi_shutdown_hba (se_hba_t *hba)
> >   *
> >   *
> >   */
> > -//#warning FIXME: We can do some custom handling of HBA fuckups here.
> > -extern inline void pscsi_process_SAM_status (se_task_t *task, unsigned char *cdb, int result)
> > +static inline void pscsi_process_SAM_status (
> > +	se_task_t *task,
> > +	pscsi_plugin_task_t *pt)
> >  {
> > -	if ((task->task_scsi_status = status_byte(result))) {
> > +	if ((task->task_scsi_status = status_byte(pt->pscsi_result))) {
> >  		task->task_scsi_status <<= 1;
> > -		PYXPRINT("Parallel SCSI Status Byte exception - ITT: 0x%08x Task: %p CDB: 0x%02x"
> > -			" Result: 0x%08x\n", task->iscsi_cmd->init_task_tag, task, cdb[0], result);
> > +		PYXPRINT("PSCSI Status Byte exception at task: %p CDB: 0x%02x"
> > +			" Result: 0x%08x\n", task, pt->pscsi_cdb[0],
> > +			pt->pscsi_result);
> >  	}
> >  
> > -	switch (host_byte(result)) {
> > +	switch (host_byte(pt->pscsi_result)) {
> >  	case DID_OK:
> >  		transport_complete_task(task, (!task->task_scsi_status));
> >  		break;
> >  	default:
> > -		PYXPRINT("Parallel SCSI Host Byte exception - ITT: 0x%08x Task: %p CDB: 0x%02x"
> > -			" Result: 0x%08x\n", task->iscsi_cmd->init_task_tag, task, cdb[0], result);
> > +		PYXPRINT("PSCSI Host Byte exception at task: %p CDB: 0x%02x"
> > +			" Result: 0x%08x\n", task, pt->pscsi_cdb[0],
> > +			pt->pscsi_result);
> >  		task->task_scsi_status = SAM_STAT_CHECK_CONDITION;
> >  		task->task_error_status = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> >  		task->iscsi_cmd->transport_error_status = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> > @@ -1412,21 +1526,17 @@ extern inline void pscsi_process_SAM_status (se_task_t *task, unsigned char *cdb
> >  	return;
> >  }
> >  
> > -extern void pscsi_req_done (void *data, char *sense, int result, int data_len)
> > +extern void pscsi_req_done (struct request *req, int uptodate)
> >  {
> > -	se_task_t *task = (se_task_t *)data;
> > +	se_task_t *task = (se_task_t *)req->end_io_data;	
> >  	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *)task->transport_req;
> > -#if 0
> > -	printk("pscsi_req_done(): result: %08x, sense: %p data_len: %d\n",
> > -			result, sense, data_len);
> > -#endif	
> > -	pt->pscsi_result = result;
> > -	pt->pscsi_data_len = data_len;
> > -
> > -	if (result != 0)
> > -		memcpy(pt->pscsi_sense, sense, SCSI_SENSE_BUFFERSIZE);
> > +
> > +	pt->pscsi_result = req->errors;
> > +	pt->pscsi_resid = req->data_len;
> >  	
> > -	pscsi_process_SAM_status(task, &pt->pscsi_cdb[0], result);
> > +	pscsi_process_SAM_status(task, pt);
> > +
> > +	__blk_put_request(req->q, req);
> > +
> >  	return;
> >  }
> > -
> > diff --git a/drivers/lio-core/target_core_pscsi.h b/drivers/lio-core/target_core_pscsi.h
> > index 980587d..090f0d2 100644
> > --- a/drivers/lio-core/target_core_pscsi.h
> > +++ b/drivers/lio-core/target_core_pscsi.h
> > @@ -90,7 +90,7 @@ extern struct scatterlist *pscsi_get_SG (se_task_t *);
> >  extern u32 pscsi_get_SG_count (se_task_t *);
> >  extern int pscsi_set_non_SG_buf (unsigned char *, se_task_t *);
> >  extern void pscsi_shutdown_hba (struct se_hba_s *);
> > -extern void pscsi_req_done (void *, char *, int, int);
> > +extern void pscsi_req_done (struct request *, int);
> >  #endif
> >  
> >  #include <linux/device.h>
> > @@ -104,8 +104,9 @@ typedef struct pscsi_plugin_task_s {
> >  	unsigned char pscsi_sense[SCSI_SENSE_BUFFERSIZE];
> >  	int	pscsi_direction;
> >  	int	pscsi_result;
> > -	u32	pscsi_data_len;
> > +	u32	pscsi_resid;
> >  	void	*pscsi_buf;
> 
> -	void	*pscsi_buf;
> +	struct scatterlist kern_buff;
> +	struct scatterlist *pscsi_sg;
> 
> See comment bellow, you will need to change all that code,
> functions APIs the works
> 

<nod>, as the I/O becomes stable using struct request, the plan is to
remove all of the duplicated structure members in struct
pscsi_plugin_task_s, and most likely getting rid of the structure all
together..

> > +	struct request *pscsi_req;
> >  } pscsi_plugin_task_t;
> >  
> >  #define PDF_HAS_CHANNEL_ID	0x01
> > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> > index f5d3b96..9e03a02 100644
> > --- a/drivers/scsi/scsi_lib.c
> > +++ b/drivers/scsi/scsi_lib.c
> > @@ -303,8 +303,8 @@ static void scsi_bi_endio(struct bio *bio, int error)
> >   * request can be sent to the block layer. We do not trust the scatterlist
> >   * sent to use, as some ULDs use that struct to only organize the pages.
> >   */
> > -static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
> > -			   int nsegs, unsigned bufflen, gfp_t gfp)
> > +int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
> > +		    int nsegs, unsigned bufflen, gfp_t gfp)
> >  {
> >  	struct request_queue *q = rq->q;
> >  	int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
> > @@ -379,6 +379,8 @@ free_bios:
> >  	return err;
> >  }
> >  
> > +EXPORT_SYMBOL_GPL(scsi_req_map_sg);
> > +
> 
> Hmmm this is going away from here soon I hope. Better copy past it into your
> own code. Perhaps optimize to your needs.
> 

The only reason I am using this (and hence using the BIOs behind it) is
because the upstream code for struct scatterlist -> struct request ->
struct scsi_device->request_queue via blk_execute_rq_nowait() ops does
not exist (yet :-)

> >  /**
> >   * scsi_execute_async - insert request
> >   * @sdev:	scsi device
> > 
> > 
> 
> Do you have this code on a gitweb somewhere. I'm to lazy to download everything
> here?
> 

The v3.0 tree is located at:

http://git.kernel.org/?p=linux/kernel/git/nab/lio-core-2.6.git;a=summary

So, I have not commited the original patch for scsi_execute_async()
removal in the LIO PSCSI plugin in v2.6.28-rc6, but I will add some
temporary stubs for both codepaths and default to the legacy codepath
(until the timeout issues are resolved) and make the commit soon.

> One thing I can not see is where you get your "(struct scatterlist *)pt->pscsi_buf"
> scatterlist from? is that from the network layer? don't you get them one by one
> from the network layer and copy them to your own allocated scatterlist array?

So, the generic target engine in v3.0 lio-core-2.6.git can either
internally allocate *OR* accept linked list scatterlist with struct page
members in drivers/lio-core/target_core_transport.h:se_mem_t->se_page
coming from a fabric module.  In current v2.9 and v3.0 LIO-Target
running code (just the iSCSi Target engine), this means the internally
allocation using Linux kernel sockets.

> Do you actually receive a network allocated scatterlist array? because if not
> you should go directly to BIOs and drop that scatterlist stuff.
> 

Well, this discussion is for the target_core_mod/PSCSI plugin located in
drivers/lio-core/target-core-pscsi.c.  The target_core_mod/IBLOCK plugin
located in drivers/lio-core/target-core-iblock.c already uses
bio_alloc() and bio_add_page() + submit_bio() when talking to struct
block_device for READ/WRITE I/O, and of course emulating the SCSI
control path for the rest.  This is used when talking with virtual
struct block_device, that do not map struct back to a single struct
scsi_device.

Considering the target_core_mod/PSCSI plugin is intended to be directly
queuing passthrough CDBs (the generic engine does handle sectors >
$STORAGE_OBJECT->max_sectors) into struct scsi_device->request_queue, I
would like to get rid of the BIO usage with scsi_execute_async() (/me
thinks of legacy scsi_do_req()) when a generic target engine is handling
the hardware restrictions related to max_sectors, queue_depth and struct
page memory allocation.

So I understand that getting rid of scsi_execute_async() and
scsi_req_map_sg() is a work in progress, and I am really asking more of
what should be used in place of scsi_req_map_sg() in
target_core_mod/PSCSI..?

> Also that void* SG/NON_SG type cast crap is not acceptable any more. We worked
> very hard to clean all that up. You need to hold typed scatterlist pointer and if
> you happen to have single kernel buffers for submission you hold an struct scatterlist
> somewhere and do an sg_init_one() on the kernel buffer.

Ok, drivers/lio-core/target_core_transport.c:transport_calc_sg_num() is
using include/linux/scatterlist.h:sg_init_table() to setup the freshly
allocated contigious array of struct scatterlist.  se_mem_t->se_page
located in the linked list of memory at
drivers/lio-core/target_core_base.h:se_transport_task_t->t_mem_list.
The generic target algortihms in target_core_transport.c allow the
linked list of struct page memory to be mapped to struct
scatterlist->page_link in
target_core_transport.c:transport_map_mem_to_sg() using
sg_assign_page().  This happens already across subsystem plugins for
Linux/SCSI, Linux/BLOCK and Linux/VFS using the same code path.

>  For me this is preliminary to
> even consider this code.
> 

Ok, I have no problem getting rid of the casts between target_core_mod
and the subsystem plugins related to contigious buffer or non contigious
buffer usage with struct scatterlist (or whatever that can reference
struct page).  I will make the stub commits for the original patch later
today, and will remove the casts from se_task_t->task_buf that are going
down to drivers/lio-core/target_core_base.h:se_subsystem_api_t at some
point in the near future.

Many thanks for your comments,

--nab


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux