diff options
author | Neil Horman <nhorman@tuxdriver.com> | 2009-09-02 17:37:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-02 17:37:45 -0400 |
commit | 5848cc096a23b80b3d15c27d72299f79caf7c517 (patch) | |
tree | f43257578c3e5fc248903544c430294d914287a7 /net | |
parent | 3f968de276a8e585deb182d4ba56013a479c80bc (diff) |
net: drop_monitor: make last_rx timestamp private
It was recently pointed out to me that the last_rx field of the
net_device structure wasn't updated regularly. In fact only the
bonding driver really uses it currently. Since the drop_monitor code
relies on the last_rx field to detect drops on recevie in hardware, We
need to find a more reliable way to rate limit our drop checks (so
that we don't check for drops on every frame recevied, which would be
inefficient. This patch makes a last_rx timestamp that is private to
the drop monitor code and is updated for every device that we track.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/drop_monitor.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index d31120248c03..0a113f26bc9f 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
@@ -52,6 +52,7 @@ struct per_cpu_dm_data { | |||
52 | 52 | ||
53 | struct dm_hw_stat_delta { | 53 | struct dm_hw_stat_delta { |
54 | struct net_device *dev; | 54 | struct net_device *dev; |
55 | unsigned long last_rx; | ||
55 | struct list_head list; | 56 | struct list_head list; |
56 | struct rcu_head rcu; | 57 | struct rcu_head rcu; |
57 | unsigned long last_drop_val; | 58 | unsigned long last_drop_val; |
@@ -180,18 +181,25 @@ static void trace_napi_poll_hit(struct napi_struct *napi) | |||
180 | struct dm_hw_stat_delta *new_stat; | 181 | struct dm_hw_stat_delta *new_stat; |
181 | 182 | ||
182 | /* | 183 | /* |
183 | * Ratelimit our check time to dm_hw_check_delta jiffies | 184 | * Don't check napi structures with no associated device |
184 | */ | 185 | */ |
185 | if (!napi->dev || | 186 | if (!napi->dev) |
186 | !time_after(jiffies, napi->dev->last_rx + dm_hw_check_delta)) | ||
187 | return; | 187 | return; |
188 | 188 | ||
189 | rcu_read_lock(); | 189 | rcu_read_lock(); |
190 | list_for_each_entry_rcu(new_stat, &hw_stats_list, list) { | 190 | list_for_each_entry_rcu(new_stat, &hw_stats_list, list) { |
191 | /* | ||
192 | * only add a note to our monitor buffer if: | ||
193 | * 1) this is the dev we received on | ||
194 | * 2) its after the last_rx delta | ||
195 | * 3) our rx_dropped count has gone up | ||
196 | */ | ||
191 | if ((new_stat->dev == napi->dev) && | 197 | if ((new_stat->dev == napi->dev) && |
198 | (time_after(jiffies, new_stat->last_rx + dm_hw_check_delta)) && | ||
192 | (napi->dev->stats.rx_dropped != new_stat->last_drop_val)) { | 199 | (napi->dev->stats.rx_dropped != new_stat->last_drop_val)) { |
193 | trace_drop_common(NULL, NULL); | 200 | trace_drop_common(NULL, NULL); |
194 | new_stat->last_drop_val = napi->dev->stats.rx_dropped; | 201 | new_stat->last_drop_val = napi->dev->stats.rx_dropped; |
202 | new_stat->last_rx = jiffies; | ||
195 | break; | 203 | break; |
196 | } | 204 | } |
197 | } | 205 | } |
@@ -287,6 +295,7 @@ static int dropmon_net_event(struct notifier_block *ev_block, | |||
287 | goto out; | 295 | goto out; |
288 | 296 | ||
289 | new_stat->dev = dev; | 297 | new_stat->dev = dev; |
298 | new_stat->last_rx = jiffies; | ||
290 | INIT_RCU_HEAD(&new_stat->rcu); | 299 | INIT_RCU_HEAD(&new_stat->rcu); |
291 | spin_lock(&trace_state_lock); | 300 | spin_lock(&trace_state_lock); |
292 | list_add_rcu(&new_stat->list, &hw_stats_list); | 301 | list_add_rcu(&new_stat->list, &hw_stats_list); |