diff options
author | Nikolay Borisov <kernel@kyup.com> | 2016-07-13 09:19:15 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-07-26 07:52:25 -0400 |
commit | 35f4e5e6f198a11c11606a742b309aa80271c66d (patch) | |
tree | 3fa80aaf08c8a7902ea0df03cac1b0ae50481f8d /fs/btrfs | |
parent | 5a488b9d2c25d98cdd11d09de311bfc83ba09fbd (diff) |
btrfs: Add ratelimit to btrfs printing
This patch adds ratelimiting to all messages which are not using the _rl
version of the various printing APIs in btrfs. This is designed to be
used as a safety net, since a flood messages might cause the softlockup
detector to trigger. To reduce interference between different classes of
messages use a separate ratelimit state for every class of message.
Signed-off-by: Nikolay Borisov <kernel@kyup.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/super.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 60e7179ed4b7..8766d560a48f 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -184,6 +184,22 @@ static const char * const logtypes[] = { | |||
184 | "debug", | 184 | "debug", |
185 | }; | 185 | }; |
186 | 186 | ||
187 | |||
188 | /* | ||
189 | * Use one ratelimit state per log level so that a flood of less important | ||
190 | * messages doesn't cause more important ones to be dropped. | ||
191 | */ | ||
192 | static struct ratelimit_state printk_limits[] = { | ||
193 | RATELIMIT_STATE_INIT(printk_limits[0], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
194 | RATELIMIT_STATE_INIT(printk_limits[1], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
195 | RATELIMIT_STATE_INIT(printk_limits[2], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
196 | RATELIMIT_STATE_INIT(printk_limits[3], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
197 | RATELIMIT_STATE_INIT(printk_limits[4], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
198 | RATELIMIT_STATE_INIT(printk_limits[5], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
199 | RATELIMIT_STATE_INIT(printk_limits[6], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
200 | RATELIMIT_STATE_INIT(printk_limits[7], DEFAULT_RATELIMIT_INTERVAL, 100), | ||
201 | }; | ||
202 | |||
187 | void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) | 203 | void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) |
188 | { | 204 | { |
189 | struct super_block *sb = fs_info->sb; | 205 | struct super_block *sb = fs_info->sb; |
@@ -192,6 +208,7 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) | |||
192 | va_list args; | 208 | va_list args; |
193 | const char *type = logtypes[4]; | 209 | const char *type = logtypes[4]; |
194 | int kern_level; | 210 | int kern_level; |
211 | struct ratelimit_state *ratelimit; | ||
195 | 212 | ||
196 | va_start(args, fmt); | 213 | va_start(args, fmt); |
197 | 214 | ||
@@ -202,13 +219,18 @@ void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) | |||
202 | lvl[size] = '\0'; | 219 | lvl[size] = '\0'; |
203 | fmt += size; | 220 | fmt += size; |
204 | type = logtypes[kern_level - '0']; | 221 | type = logtypes[kern_level - '0']; |
205 | } else | 222 | ratelimit = &printk_limits[kern_level - '0']; |
223 | } else { | ||
206 | *lvl = '\0'; | 224 | *lvl = '\0'; |
225 | /* Default to debug output */ | ||
226 | ratelimit = &printk_limits[7]; | ||
227 | } | ||
207 | 228 | ||
208 | vaf.fmt = fmt; | 229 | vaf.fmt = fmt; |
209 | vaf.va = &args; | 230 | vaf.va = &args; |
210 | 231 | ||
211 | printk("%sBTRFS %s (device %s): %pV\n", lvl, type, sb->s_id, &vaf); | 232 | if (__ratelimit(ratelimit)) |
233 | printk("%sBTRFS %s (device %s): %pV\n", lvl, type, sb->s_id, &vaf); | ||
212 | 234 | ||
213 | va_end(args); | 235 | va_end(args); |
214 | } | 236 | } |