Re: [PATCH 3/9] scsi: use external buffer for command logging

2015-01-14 Thread James Bottomley
On Wed, 2015-01-14 at 10:36 +0100, h...@lst.de wrote:
> On Tue, Jan 13, 2015 at 06:56:17PM +, James Bottomley wrote:
> > I really hate using an on-stack buffer here ... we're pretty deep in the
> > call chain already.
> > 
> > Since it's just required for printing a "command: " prefix, why not just
> > use scsi_print_command()?
> 
> Both the ch and sr callers are not really a problem in terms of stack
> usage, as they are directly in file operations of character or block
> devices, so the whole FS/MM stack stack problem isn't an issue.

Trying to calculate minutely how much additional overhead there is isn't
really the point.  The point is we can just use a different function
that doesn't consume the on stack buffer, so we should, just as a matter
of best practise.  I agree it would have been a more finely balanced
problem if we definitely needed the allocation

> But using higher level functions might still be useful here.

James



Re: [PATCH 3/9] scsi: use external buffer for command logging

2015-01-14 Thread h...@lst.de
On Tue, Jan 13, 2015 at 06:56:17PM +, James Bottomley wrote:
> I really hate using an on-stack buffer here ... we're pretty deep in the
> call chain already.
> 
> Since it's just required for printing a "command: " prefix, why not just
> use scsi_print_command()?

Both the ch and sr callers are not really a problem in terms of stack
usage, as they are directly in file operations of character or block
devices, so the whole FS/MM stack stack problem isn't an issue.

But using higher level functions might still be useful here.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/9] scsi: use external buffer for command logging

2015-01-13 Thread James Bottomley
On Thu, 2015-01-08 at 07:43 +0100, Hannes Reinecke wrote:
> Use an external buffer for __scsi_print_command() and
> move command logging over to use the per-cpu logging
> buffer. With that we can guarantee the command always
> will always be formatted in one line.
> So we can even print out a variable length command
> correctly across several lines.
> Finally rename __scsi_print_command() to
> __scsi_format_comment() to better reflect the
> functionality.
> 
> Tested-by: Robert Elliott 
> Reviewed-by: Robert Elliott 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/ch.c   |   6 +-
>  drivers/scsi/constants.c|  74 +-
>  drivers/scsi/scsi_logging.c | 182 
> 
>  drivers/scsi/sr_ioctl.c |  13 +++-
>  include/scsi/scsi.h |   3 +
>  include/scsi/scsi_dbg.h |   6 +-
>  6 files changed, 192 insertions(+), 92 deletions(-)
> 
> diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
> index 6bac8a7..79e462f 100644
> --- a/drivers/scsi/ch.c
> +++ b/drivers/scsi/ch.c
> @@ -195,8 +195,10 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int 
> cmd_len,
>   retry:
>   errno = 0;
>   if (debug) {
> - DPRINTK("command: ");
> - __scsi_print_command(cmd, cmd_len);
> + char logbuf[SCSI_LOG_BUFSIZE];
> +
> + __scsi_format_command(logbuf, sizeof(logbuf), cmd, cmd_len);
> + DPRINTK("command: %s", logbuf);

I really hate using an on-stack buffer here ... we're pretty deep in the
call chain already.

Since it's just required for printing a "command: " prefix, why not just
use scsi_print_command()?


> diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
> index fb929fa..e8deb9c 100644
> --- a/drivers/scsi/sr_ioctl.c
> +++ b/drivers/scsi/sr_ioctl.c
> @@ -188,6 +188,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
> struct scsi_sense_hdr sshdr;
> int result, err = 0, retries = 0;
> struct request_sense *sense = cgc->sense;
> +   char logbuf[SCSI_LOG_BUFSIZE];

Same issue here.

> SDev = cd->device;
>  
> @@ -257,14 +258,20 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
> /* sense: Invalid command operation code */
> err = -EDRIVE_CANT_DO_THIS;
>  #ifdef DEBUG
> -   __scsi_print_command(cgc->cmd, CDROM_PACKET_SIZE);
> +   __scsi_format_command(logbuf, sizeof(logbuf),
> + cgc->cmd, CDROM_PACKET_SIZE);
> +   sr_printk(KERN_INFO, cd,
> + "CDROM (ioctl) invalid command: %s\n",
> + logbuf);

Looks like scsi_print_command() will work here too.

> scsi_print_sense_hdr(cd->device, cd->cdi.name, 
> &sshdr);
>  #endif
> break;
> default:
> +   __scsi_format_command(logbuf, sizeof(logbuf),
> + cgc->cmd, CDROM_PACKET_SIZE);
> sr_printk(KERN_ERR, cd,
> - "CDROM (ioctl) error, command: ");
> -   __scsi_print_command(cgc->cmd, CDROM_PACKET_SIZE);
> + "CDROM (ioctl) error, command: %s\n",
> + logbuf);

And realistically here (with the appropriate sdev_print()'s preceding).

> scsi_print_sense_hdr(cd->device, cd->cdi.name, 
> &sshdr);
> err = -EIO;
> }

James



[PATCH 3/9] scsi: use external buffer for command logging

2015-01-07 Thread Hannes Reinecke
Use an external buffer for __scsi_print_command() and
move command logging over to use the per-cpu logging
buffer. With that we can guarantee the command always
will always be formatted in one line.
So we can even print out a variable length command
correctly across several lines.
Finally rename __scsi_print_command() to
__scsi_format_comment() to better reflect the
functionality.

Tested-by: Robert Elliott 
Reviewed-by: Robert Elliott 
Reviewed-by: Christoph Hellwig 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/ch.c   |   6 +-
 drivers/scsi/constants.c|  74 +-
 drivers/scsi/scsi_logging.c | 182 
 drivers/scsi/sr_ioctl.c |  13 +++-
 include/scsi/scsi.h |   3 +
 include/scsi/scsi_dbg.h |   6 +-
 6 files changed, 192 insertions(+), 92 deletions(-)

diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 6bac8a7..79e462f 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -195,8 +195,10 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int 
cmd_len,
  retry:
errno = 0;
if (debug) {
-   DPRINTK("command: ");
-   __scsi_print_command(cmd, cmd_len);
+   char logbuf[SCSI_LOG_BUFSIZE];
+
+   __scsi_format_command(logbuf, sizeof(logbuf), cmd, cmd_len);
+   DPRINTK("command: %s", logbuf);
}
 
result = scsi_execute_req(ch->device, cmd, direction, buffer,
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 55a7157..7792960 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -24,8 +24,6 @@
 #define THIRD_PARTY_COPY_OUT 0x83
 #define THIRD_PARTY_COPY_IN 0x84
 
-#define VENDOR_SPECIFIC_CDB 0xc0
-
 struct sa_name_list {
int opcode;
const struct value_name_pair *arr;
@@ -281,8 +279,8 @@ static struct sa_name_list sa_names_arr[] = {
 };
 #endif /* CONFIG_SCSI_CONSTANTS */
 
-static bool scsi_opcode_sa_name(int opcode, int service_action,
-   const char **cdb_name, const char **sa_name)
+bool scsi_opcode_sa_name(int opcode, int service_action,
+const char **cdb_name, const char **sa_name)
 {
struct sa_name_list *sa_name_ptr;
const struct value_name_pair *arr = NULL;
@@ -315,74 +313,6 @@ static bool scsi_opcode_sa_name(int opcode, int 
service_action,
return true;
 }
 
-static void print_opcode_name(const unsigned char *cdbp, size_t cdb_len)
-{
-   int sa, cdb0;
-   const char *cdb_name = NULL, *sa_name = NULL;
-
-   cdb0 = cdbp[0];
-   if (cdb0 == VARIABLE_LENGTH_CMD) {
-   if (cdb_len < 10) {
-   printk("short variable length command, len=%zu",
-  cdb_len);
-   return;
-   }
-   sa = (cdbp[8] << 8) + cdbp[9];
-   } else
-   sa = cdbp[1] & 0x1f;
-
-   if (!scsi_opcode_sa_name(cdb0, sa, &cdb_name, &sa_name)) {
-   if (cdb_name)
-   printk("%s", cdb_name);
-   else if (cdb0 >= VENDOR_SPECIFIC_CDB)
-   printk("cdb[0]=0x%x (vendor)", cdb0);
-   else if (cdb0 >= 0x60 && cdb0 < 0x7e)
-   printk("cdb[0]=0x%x (reserved)", cdb0);
-   else
-   printk("cdb[0]=0x%x", cdb0);
-   } else {
-   if (sa_name)
-   printk("%s", sa_name);
-   else if (cdb_name)
-   printk("%s, sa=0x%x", cdb_name, sa);
-   else
-   printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
-   }
-}
-
-void __scsi_print_command(const unsigned char *cdb, size_t cdb_len)
-{
-   int k, len;
-
-   print_opcode_name(cdb, cdb_len);
-   len = scsi_command_size(cdb);
-   if (cdb_len < len)
-   len = cdb_len;
-   /* print out all bytes in cdb */
-   for (k = 0; k < len; ++k)
-   printk(" %02x", cdb[k]);
-   printk("\n");
-}
-EXPORT_SYMBOL(__scsi_print_command);
-
-void scsi_print_command(struct scsi_cmnd *cmd)
-{
-   int k;
-
-   if (cmd->cmnd == NULL)
-   return;
-
-   scmd_printk(KERN_INFO, cmd, "CDB: ");
-   print_opcode_name(cmd->cmnd, cmd->cmd_len);
-
-   /* print out all bytes in cdb */
-   printk(":");
-   for (k = 0; k < cmd->cmd_len; ++k)
-   printk(" %02x", cmd->cmnd[k]);
-   printk("\n");
-}
-EXPORT_SYMBOL(scsi_print_command);
-
 #ifdef CONFIG_SCSI_CONSTANTS
 
 struct error_info {
diff --git a/drivers/scsi/scsi_logging.c b/drivers/scsi/scsi_logging.c
index 4d20132..afba995 100644
--- a/drivers/scsi/scsi_logging.c
+++ b/drivers/scsi/scsi_logging.c
@@ -13,10 +13,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define SCSI_LOG_SPOOLSIZE 4096
-#define SCSI_LOG_BUFSIZE 128
 
 #if (SCSI_LOG_SPOOLSIZE / SCSI_LOG_BUFSIZE) > BITS_PER_LONG
 #warning SCSI logging bitmask too large
@@