Re: Some plans for scsi_cmnd

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

 



On Tue, Sep 25 2007 at 15:37 +0200, Matthew Wilcox <matthew@xxxxxx> wrote:
> Christoph grabbed me on IRC and we debated some of my plans for scsi_cmnd;
> with his permission I'm summarising the result of that debate for posterity.
> There's four main things discussed:
> 
> 1. I'm going to be writing and posting patches over the next week or so
> to kill all the (ab)uses of ->scsi_done in drivers.  Once that is done,
> I'll post a patch that exports the midlayer's scsi_done and switch all
> the drivers to calling that.  After that, I'll post another patch that
> changes the prototype *and the semantics* of queuecommand; the midlayer
> will no longer take the host_lock for the driver.  I'll just push the
> acquisition down into queuecommand, and it'll be up to individual driver
> authors to do something sensible with it then.
> 
> 2. Thanks to a thinko, we also discussed the upper-layer ->done.  We think
> it should be feasible to move this from the scsi_cmnd to the scsi_device
> since sg doesn't use it.
> 
> 3. We also discussed scsi_pointer.  It's really quite crufty, and it
> gets recycled for storing all kinds of things.  The ambitious plan here
> is to change the whole way scsi_cmnds are allocated.  Code is clearer
> than my description ...
> 
> sym2.c:
> 
> struct sym2_cmnd {
> 	struct scsi_cmnd cmd;
> 	int Phase;
> 	char *data_in;
> }
> 
> struct scsi_host_template sym2_template {
> 	.cmnd_size = sizeof(sym2_cmnd);
> }
> 
> int sym2_queuecommand(struct scsi_cmnd *scp)
> {
> 	struct sym2_cmnd *cmnd = container_of(scp, sym2_cmnd, cmd);
> }
> 
> The midlayer will create a slab pool per host template for allocating
> scsi_cmnd.
> 
I have in my Q a small variation on this principle where I wanted
to allocate bigger commands for bidi-able hosts like iscsi_tcp. So
not to pay the extra allocation per command. Above will do just fine.

> As I said, it's ambitious.  But it'll let us get rid of scsi_pointer
> and host_scribble entirely.
> 
This all is an excellent idea and you will find that in the patchset to
gdth, I have made the work of one driver a bit easier for you.

I suggest gradual work, where both Scp and host_scribble are intact
but the .cmnd_size and mechanics are available with few major drivers
moved to that. Than one kernel after that deprecating both, while 
converting lots of drivers, and 1-2 kernels after that remove them when
all drivers are converted. Don't sit on a large patchset with lots of
drivers and submit them all at once.

> 4. We don't understand why sense_buffer is 96 bytes long.  mkp says that
> devices are coming which need more than 96 bytes (the standard allows up
> to 252).  I propose splitting the 96-byte buffer like so:
> 
> -#define SCSI_SENSE_BUFFERSIZE  96
> -       unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
> +       unsigned char sense_buffer_head[8];
> +       unsigned char *sense_buffer_desc;
> 
> and then adding:
> 
> +int scsi_set_sense_buffer(struct scsi_cmnd *cmd, unsigned char *sense,
> +                                                               int sense_len)
> +{
> +       int len = min(sense[7], sense_len - 8);
> +       memcpy(cmd->sense_buffer_head, sense, min(8, sense_len));
> +       if (len <= 0)
> +               return 0;
> +       cmd->sense_buffer_desc = kmalloc(len, GFP_ATOMIC);
> +       if (!cmd->sense_buffer_desc)
> +               return 1;
> +       memcpy(cmd->sense_buffer_desc, sense + 8, len);
> +       return 0;
> +}
> +EXPORT_SYMBOL(scsi_set_sense_buffer);
> 
> Drivers then do something like:
> 
> -                       memset(&cmd->sense_buffer, 0, sizeof(cmd->sense_buffer))
> -                       memcpy(cmd->sense_buffer, cp->sns_bbuf,
> -                             min(sizeof(cmd->sense_buffer),
> -                                 (size_t)SYM_SNS_BBUF_LEN));
> +                       scsi_set_sense_buffer(cmd, cp->sns_bbuf,
> +                                                       SYM_SNS_BBUF_LEN);
> 
> or even ...
> 
> -               /* Copy Sense Data into sense buffer. */
> -               memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
> -
>                 if (!(scsi_status & SS_SENSE_LEN_VALID))
>                         break;
>  
> -               if (sense_len >= sizeof(cp->sense_buffer))
> -                       sense_len = sizeof(cp->sense_buffer);
> -
> -               CMD_ACTUAL_SNSLEN(cp) = sense_len;
> -               sp->request_sense_length = sense_len;
> -               sp->request_sense_ptr = cp->sense_buffer;
> -
> -               if (sp->request_sense_length > 32)
> -                       sense_len = 32;
> -
> -               memcpy(cp->sense_buffer, sense_data, sense_len);
> -
> -               sp->request_sense_ptr += sense_len;
> -               sp->request_sense_length -= sense_len;
> -               if (sp->request_sense_length != 0)
> -                       ha->status_srb = sp;
> +               scsi_set_sense_buffer(cp, sense_data, sense_len);
> 
Please review my patches to scsi_error and the REQUEST_SENSE paths
(James are they not going to be accepted into 2.6.24-rcx?)
I have introduced an abstract way to convert a command to point to
it's sense buffer, So drivers can now transfer data to the sense buffer
the way they do to regular IO, throw an sg_list.

Also if you are converting to pointers than please do not do the above.
struct request already has a sense pointer and length. Directly use
these. The transient first 8 bytes are not necessary, and just complicate
the code. The all sense allocation can be settled with part 3 of your mail 
above. we can widen it to be:
struct scsi_host_template sym2_template {
	.cmnd_size = sizeof(sym2_cmnd);
	.sense_size = SYM_SNS_BBUF_LEN;
	.bidi_cmnd = 1;
}
By default .sense_size will be 96 allocated from cmnd-pool and pointed
to by the struct request pointers.
Drivers that want privately allocated space can put 0 in .sense_size 
and use Christoph's alloc/destroy_cmnd to set up their own. 
Drivers should access all these members throw accessors So to be abstracted 
from all that.

> If any of this seems unwelcome, please say so.  It's going to be a lot of
> churn (and part 4 may well take six months or more), so I'd like people
> to voice objections now rather than later.
> 

RFC patches early and set up a git tree, if possible. I will help in any way 
I can also with drivers.

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