| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ratelimit.c - Do something with rate limit. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * 2008-05-01 rewrite the function and use a ratelimit_state data struct as |
|---|
| 7 | 8 | * parameter. Now every user can use their own standalone ratelimit_state. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This file is released under the GPLv2. |
|---|
| 10 | 9 | */ |
|---|
| 11 | 10 | |
|---|
| 12 | 11 | #include <linux/ratelimit.h> |
|---|
| .. | .. |
|---|
| 27 | 26 | */ |
|---|
| 28 | 27 | int ___ratelimit(struct ratelimit_state *rs, const char *func) |
|---|
| 29 | 28 | { |
|---|
| 29 | + /* Paired with WRITE_ONCE() in .proc_handler(). |
|---|
| 30 | + * Changing two values seperately could be inconsistent |
|---|
| 31 | + * and some message could be lost. (See: net_ratelimit_state). |
|---|
| 32 | + */ |
|---|
| 33 | + int interval = READ_ONCE(rs->interval); |
|---|
| 34 | + int burst = READ_ONCE(rs->burst); |
|---|
| 30 | 35 | unsigned long flags; |
|---|
| 31 | 36 | int ret; |
|---|
| 32 | 37 | |
|---|
| 33 | | - if (!rs->interval) |
|---|
| 38 | + if (!interval) |
|---|
| 34 | 39 | return 1; |
|---|
| 35 | 40 | |
|---|
| 36 | 41 | /* |
|---|
| .. | .. |
|---|
| 45 | 50 | if (!rs->begin) |
|---|
| 46 | 51 | rs->begin = jiffies; |
|---|
| 47 | 52 | |
|---|
| 48 | | - if (time_is_before_jiffies(rs->begin + rs->interval)) { |
|---|
| 53 | + if (time_is_before_jiffies(rs->begin + interval)) { |
|---|
| 49 | 54 | if (rs->missed) { |
|---|
| 50 | 55 | if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { |
|---|
| 51 | 56 | printk_deferred(KERN_WARNING |
|---|
| .. | .. |
|---|
| 57 | 62 | rs->begin = jiffies; |
|---|
| 58 | 63 | rs->printed = 0; |
|---|
| 59 | 64 | } |
|---|
| 60 | | - if (rs->burst && rs->burst > rs->printed) { |
|---|
| 65 | + if (burst && burst > rs->printed) { |
|---|
| 61 | 66 | rs->printed++; |
|---|
| 62 | 67 | ret = 1; |
|---|
| 63 | 68 | } else { |
|---|