lkml.org 
[lkml]   [2019]   [Sep]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.4 14/14] scsi: core: Reduce memory required for SCSI logging
    Date
    From: Bart Van Assche <bvanassche@acm.org>

    [ Upstream commit dccc96abfb21dc19d69e707c38c8ba439bba7160 ]

    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@fastmail.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Hannes Reinecke <hare@suse.com>
    Cc: Johannes Thumshirn <jthumshirn@suse.de>
    Cc: Ming Lei <ming.lei@redhat.com>
    Cc: Jan Palus <jpalus@fastmail.com>
    Signed-off-by: Bart Van Assche <bvanassche@acm.org>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    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 bd70339c1242e..03d9855a6afd7 100644
    --- a/drivers/scsi/scsi_logging.c
    +++ b/drivers/scsi/scsi_logging.c
    @@ -16,57 +16,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 f8170e90b49d2..bbe71a6361db9 100644
    --- a/include/scsi/scsi_dbg.h
    +++ b/include/scsi/scsi_dbg.h
    @@ -5,8 +5,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);
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-09-24 18:53    [W:3.279 / U:0.928 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site