Re: [PATCH 4/4] Reduce memory required for SCSI logging

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

 



On 7/26/19 6:48 PM, Bart Van Assche wrote:
> The data structure used for log messages is so large that it can cause a
> boot failure. Since allocations from that data structure can fail anyway,
> use kmalloc() / kfree() instead of that data structure.
> 
> See also https://bugzilla.kernel.org/show_bug.cgi?id=204119.
> See also commit ded85c193a39 ("scsi: Implement per-cpu logging buffer") # v4.0.
> 
> Reported-by: Jan Palus <jpalus@xxxxxxxxxxxx>
> Cc: Christoph Hellwig <hch@xxxxxx>
> Cc: Hannes Reinecke <hare@xxxxxxxx>
> Cc: Johannes Thumshirn <jthumshirn@xxxxxxx>
> Cc: Ming Lei <ming.lei@xxxxxxxxxx>
> Cc: Jan Palus <jpalus@xxxxxxxxxxxx>
> Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx>
> ---
>  drivers/scsi/scsi_logging.c | 48 +++----------------------------------
>  include/scsi/scsi_dbg.h     |  2 --
>  2 files changed, 3 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_logging.c b/drivers/scsi/scsi_logging.c
> index 39b8cc4574b4..c6ed0b12e807 100644
> --- a/drivers/scsi/scsi_logging.c
> +++ b/drivers/scsi/scsi_logging.c
> @@ -15,57 +15,15 @@
>  #include <scsi/scsi_eh.h>
>  #include <scsi/scsi_dbg.h>
>  
> -#define SCSI_LOG_SPOOLSIZE 4096
> -
> -#if (SCSI_LOG_SPOOLSIZE / SCSI_LOG_BUFSIZE) > BITS_PER_LONG
> -#warning SCSI logging bitmask too large
> -#endif
> -
> -struct scsi_log_buf {
> -	char buffer[SCSI_LOG_SPOOLSIZE];
> -	unsigned long map;
> -};
> -
> -static DEFINE_PER_CPU(struct scsi_log_buf, scsi_format_log);
> -
>  static char *scsi_log_reserve_buffer(size_t *len)
>  {
> -	struct scsi_log_buf *buf;
> -	unsigned long map_bits = sizeof(buf->buffer) / SCSI_LOG_BUFSIZE;
> -	unsigned long idx = 0;
> -
> -	preempt_disable();
> -	buf = this_cpu_ptr(&scsi_format_log);
> -	idx = find_first_zero_bit(&buf->map, map_bits);
> -	if (likely(idx < map_bits)) {
> -		while (test_and_set_bit(idx, &buf->map)) {
> -			idx = find_next_zero_bit(&buf->map, map_bits, idx);
> -			if (idx >= map_bits)
> -				break;
> -		}
> -	}
> -	if (WARN_ON(idx >= map_bits)) {
> -		preempt_enable();
> -		return NULL;
> -	}
> -	*len = SCSI_LOG_BUFSIZE;
> -	return buf->buffer + idx * SCSI_LOG_BUFSIZE;
> +	*len = 128;
> +	return kmalloc(*len, GFP_ATOMIC);
>  }
>  
>  static void scsi_log_release_buffer(char *bufptr)
>  {
> -	struct scsi_log_buf *buf;
> -	unsigned long idx;
> -	int ret;
> -
> -	buf = this_cpu_ptr(&scsi_format_log);
> -	if (bufptr >= buf->buffer &&
> -	    bufptr < buf->buffer + SCSI_LOG_SPOOLSIZE) {
> -		idx = (bufptr - buf->buffer) / SCSI_LOG_BUFSIZE;
> -		ret = test_and_clear_bit(idx, &buf->map);
> -		WARN_ON(!ret);
> -	}
> -	preempt_enable();
> +	kfree(bufptr);
>  }
>  
>  static inline const char *scmd_name(const struct scsi_cmnd *scmd)
> diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
> index e03bd9d41fa8..7b196d234626 100644
> --- a/include/scsi/scsi_dbg.h
> +++ b/include/scsi/scsi_dbg.h
> @@ -6,8 +6,6 @@ struct scsi_cmnd;
>  struct scsi_device;
>  struct scsi_sense_hdr;
>  
> -#define SCSI_LOG_BUFSIZE 128
> -
>  extern void scsi_print_command(struct scsi_cmnd *);
>  extern size_t __scsi_format_command(char *, size_t,
>  				   const unsigned char *, size_t);
> 
Nope.

You've just disabled the prime reason why I did implement SCSI logging;
namely to provide per-cpu buffers where messages can be printed into.

We can move to kmalloc (or even kvmalloc), but the per-cpu pointer need
to be kept.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@xxxxxxx			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)



[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