Skip to content

Commit 67222c4

Browse files
Li Lingfengakpm00
authored andcommitted
lib: parser: optimize match_NUMBER apis to use local array
Memory will be allocated to store substring_t in match_strdup(), which means the caller of match_strdup() may need to be scheduled out to wait for reclaiming memory. smatch complains that this can cuase sleeping in an atoic context. Using local array to store substring_t to remove the restriction. Link: https://lkml.kernel.org/r/[email protected] Link: https://lore.kernel.org/all/[email protected]/ Link: https://lkml.kernel.org/r/[email protected] Fixes: 2c06479 ("blk-iocost: don't release 'ioc->lock' while updating params") Signed-off-by: Li Lingfeng <[email protected]> Reported-by: Yu Kuai <[email protected]> Acked-by: Tejun Heo <[email protected]> Cc: BingJing Chang <[email protected]> Cc: Eric Biggers <[email protected]> Cc: Hou Tao <[email protected]> Cc: James Smart <[email protected]> Cc: Jan Kara <[email protected]> Cc: Jens Axboe <[email protected]> Cc: yangerkun <[email protected]> Cc: Zhang Yi <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent badc28d commit 67222c4

File tree

1 file changed

+20
-19
lines changed

1 file changed

+20
-19
lines changed

lib/parser.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@
1111
#include <linux/slab.h>
1212
#include <linux/string.h>
1313

14+
/*
15+
* max size needed by different bases to express U64
16+
* HEX: "0xFFFFFFFFFFFFFFFF" --> 18
17+
* DEC: "18446744073709551615" --> 20
18+
* OCT: "01777777777777777777777" --> 23
19+
* pick the max one to define NUMBER_BUF_LEN
20+
*/
21+
#define NUMBER_BUF_LEN 24
22+
1423
/**
1524
* match_one - Determines if a string matches a simple pattern
1625
* @s: the string to examine for presence of the pattern
@@ -129,14 +138,12 @@ EXPORT_SYMBOL(match_token);
129138
static int match_number(substring_t *s, int *result, int base)
130139
{
131140
char *endp;
132-
char *buf;
141+
char buf[NUMBER_BUF_LEN];
133142
int ret;
134143
long val;
135144

136-
buf = match_strdup(s);
137-
if (!buf)
138-
return -ENOMEM;
139-
145+
if (match_strlcpy(buf, s, NUMBER_BUF_LEN) >= NUMBER_BUF_LEN)
146+
return -ERANGE;
140147
ret = 0;
141148
val = simple_strtol(buf, &endp, base);
142149
if (endp == buf)
@@ -145,7 +152,6 @@ static int match_number(substring_t *s, int *result, int base)
145152
ret = -ERANGE;
146153
else
147154
*result = (int) val;
148-
kfree(buf);
149155
return ret;
150156
}
151157

@@ -163,18 +169,15 @@ static int match_number(substring_t *s, int *result, int base)
163169
*/
164170
static int match_u64int(substring_t *s, u64 *result, int base)
165171
{
166-
char *buf;
172+
char buf[NUMBER_BUF_LEN];
167173
int ret;
168174
u64 val;
169175

170-
buf = match_strdup(s);
171-
if (!buf)
172-
return -ENOMEM;
173-
176+
if (match_strlcpy(buf, s, NUMBER_BUF_LEN) >= NUMBER_BUF_LEN)
177+
return -ERANGE;
174178
ret = kstrtoull(buf, base, &val);
175179
if (!ret)
176180
*result = val;
177-
kfree(buf);
178181
return ret;
179182
}
180183

@@ -206,14 +209,12 @@ EXPORT_SYMBOL(match_int);
206209
*/
207210
int match_uint(substring_t *s, unsigned int *result)
208211
{
209-
int err = -ENOMEM;
210-
char *buf = match_strdup(s);
212+
char buf[NUMBER_BUF_LEN];
211213

212-
if (buf) {
213-
err = kstrtouint(buf, 10, result);
214-
kfree(buf);
215-
}
216-
return err;
214+
if (match_strlcpy(buf, s, NUMBER_BUF_LEN) >= NUMBER_BUF_LEN)
215+
return -ERANGE;
216+
217+
return kstrtouint(buf, 10, result);
217218
}
218219
EXPORT_SYMBOL(match_uint);
219220

0 commit comments

Comments
 (0)