]>
Commit | Line | Data |
---|---|---|
56738dc2 JP |
1 | From dccc96abfb21dc19d69e707c38c8ba439bba7160 Mon Sep 17 00:00:00 2001 |
2 | From: Bart Van Assche <bvanassche@acm.org> | |
3 | Date: Thu, 1 Aug 2019 15:38:14 -0700 | |
4 | Subject: scsi: core: Reduce memory required for SCSI logging | |
5 | ||
6 | The data structure used for log messages is so large that it can cause a | |
7 | boot failure. Since allocations from that data structure can fail anyway, | |
8 | use kmalloc() / kfree() instead of that data structure. | |
9 | ||
10 | See also https://bugzilla.kernel.org/show_bug.cgi?id=204119. | |
11 | See also commit ded85c193a39 ("scsi: Implement per-cpu logging buffer") # v4.0. | |
12 | ||
13 | Reported-by: Jan Palus <jpalus@fastmail.com> | |
14 | Cc: Christoph Hellwig <hch@lst.de> | |
15 | Cc: Hannes Reinecke <hare@suse.com> | |
16 | Cc: Johannes Thumshirn <jthumshirn@suse.de> | |
17 | Cc: Ming Lei <ming.lei@redhat.com> | |
18 | Cc: Jan Palus <jpalus@fastmail.com> | |
19 | Signed-off-by: Bart Van Assche <bvanassche@acm.org> | |
20 | Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> | |
21 | --- | |
22 | drivers/scsi/scsi_logging.c | 48 +++------------------------------------------ | |
23 | include/scsi/scsi_dbg.h | 2 -- | |
24 | 2 files changed, 3 insertions(+), 47 deletions(-) | |
25 | ||
d2973294 | 26 | diff --git a/drivers/scsi/scsi_logging.c b/drivers/scsi/scsi_logging.c |
56738dc2 | 27 | index 39b8cc4574b4..c6ed0b12e807 100644 |
d2973294 JP |
28 | --- a/drivers/scsi/scsi_logging.c |
29 | +++ b/drivers/scsi/scsi_logging.c | |
56738dc2 | 30 | @@ -15,57 +15,15 @@ |
d2973294 JP |
31 | #include <scsi/scsi_eh.h> |
32 | #include <scsi/scsi_dbg.h> | |
56738dc2 | 33 | |
d2973294 | 34 | -#define SCSI_LOG_SPOOLSIZE 4096 |
56738dc2 JP |
35 | - |
36 | -#if (SCSI_LOG_SPOOLSIZE / SCSI_LOG_BUFSIZE) > BITS_PER_LONG | |
37 | -#warning SCSI logging bitmask too large | |
38 | -#endif | |
39 | - | |
40 | -struct scsi_log_buf { | |
41 | - char buffer[SCSI_LOG_SPOOLSIZE]; | |
42 | - unsigned long map; | |
43 | -}; | |
44 | - | |
45 | -static DEFINE_PER_CPU(struct scsi_log_buf, scsi_format_log); | |
46 | - | |
47 | static char *scsi_log_reserve_buffer(size_t *len) | |
48 | { | |
49 | - struct scsi_log_buf *buf; | |
50 | - unsigned long map_bits = sizeof(buf->buffer) / SCSI_LOG_BUFSIZE; | |
51 | - unsigned long idx = 0; | |
52 | - | |
53 | - preempt_disable(); | |
54 | - buf = this_cpu_ptr(&scsi_format_log); | |
55 | - idx = find_first_zero_bit(&buf->map, map_bits); | |
56 | - if (likely(idx < map_bits)) { | |
57 | - while (test_and_set_bit(idx, &buf->map)) { | |
58 | - idx = find_next_zero_bit(&buf->map, map_bits, idx); | |
59 | - if (idx >= map_bits) | |
60 | - break; | |
61 | - } | |
62 | - } | |
63 | - if (WARN_ON(idx >= map_bits)) { | |
64 | - preempt_enable(); | |
65 | - return NULL; | |
66 | - } | |
67 | - *len = SCSI_LOG_BUFSIZE; | |
68 | - return buf->buffer + idx * SCSI_LOG_BUFSIZE; | |
69 | + *len = 128; | |
70 | + return kmalloc(*len, GFP_ATOMIC); | |
71 | } | |
72 | ||
73 | static void scsi_log_release_buffer(char *bufptr) | |
74 | { | |
75 | - struct scsi_log_buf *buf; | |
76 | - unsigned long idx; | |
77 | - int ret; | |
78 | - | |
79 | - buf = this_cpu_ptr(&scsi_format_log); | |
80 | - if (bufptr >= buf->buffer && | |
81 | - bufptr < buf->buffer + SCSI_LOG_SPOOLSIZE) { | |
82 | - idx = (bufptr - buf->buffer) / SCSI_LOG_BUFSIZE; | |
83 | - ret = test_and_clear_bit(idx, &buf->map); | |
84 | - WARN_ON(!ret); | |
85 | - } | |
86 | - preempt_enable(); | |
87 | + kfree(bufptr); | |
88 | } | |
89 | ||
90 | static inline const char *scmd_name(const struct scsi_cmnd *scmd) | |
91 | diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h | |
92 | index e03bd9d41fa8..7b196d234626 100644 | |
93 | --- a/include/scsi/scsi_dbg.h | |
94 | +++ b/include/scsi/scsi_dbg.h | |
95 | @@ -6,8 +6,6 @@ struct scsi_cmnd; | |
96 | struct scsi_device; | |
97 | struct scsi_sense_hdr; | |
98 | ||
99 | -#define SCSI_LOG_BUFSIZE 128 | |
100 | - | |
101 | extern void scsi_print_command(struct scsi_cmnd *); | |
102 | extern size_t __scsi_format_command(char *, size_t, | |
103 | const unsigned char *, size_t); | |
104 | -- | |
105 | cgit 1.2-0.3.lf.el7 | |
d2973294 | 106 |