diff options
Diffstat (limited to 'net/core/dst.c')
| -rw-r--r-- | net/core/dst.c | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/net/core/dst.c b/net/core/dst.c index f307bc18f6a0..9920722cc82b 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
| @@ -44,7 +44,7 @@ static atomic_t dst_total = ATOMIC_INIT(0); | |||
| 44 | */ | 44 | */ |
| 45 | static struct { | 45 | static struct { |
| 46 | spinlock_t lock; | 46 | spinlock_t lock; |
| 47 | struct dst_entry *list; | 47 | struct dst_entry *list; |
| 48 | unsigned long timer_inc; | 48 | unsigned long timer_inc; |
| 49 | unsigned long timer_expires; | 49 | unsigned long timer_expires; |
| 50 | } dst_garbage = { | 50 | } dst_garbage = { |
| @@ -52,7 +52,7 @@ static struct { | |||
| 52 | .timer_inc = DST_GC_MAX, | 52 | .timer_inc = DST_GC_MAX, |
| 53 | }; | 53 | }; |
| 54 | static void dst_gc_task(struct work_struct *work); | 54 | static void dst_gc_task(struct work_struct *work); |
| 55 | static void ___dst_free(struct dst_entry * dst); | 55 | static void ___dst_free(struct dst_entry *dst); |
| 56 | 56 | ||
| 57 | static DECLARE_DELAYED_WORK(dst_gc_work, dst_gc_task); | 57 | static DECLARE_DELAYED_WORK(dst_gc_work, dst_gc_task); |
| 58 | 58 | ||
| @@ -136,8 +136,8 @@ loop: | |||
| 136 | } | 136 | } |
| 137 | expires = dst_garbage.timer_expires; | 137 | expires = dst_garbage.timer_expires; |
| 138 | /* | 138 | /* |
| 139 | * if the next desired timer is more than 4 seconds in the future | 139 | * if the next desired timer is more than 4 seconds in the |
| 140 | * then round the timer to whole seconds | 140 | * future then round the timer to whole seconds |
| 141 | */ | 141 | */ |
| 142 | if (expires > 4*HZ) | 142 | if (expires > 4*HZ) |
| 143 | expires = round_jiffies_relative(expires); | 143 | expires = round_jiffies_relative(expires); |
| @@ -152,7 +152,8 @@ loop: | |||
| 152 | " expires: %lu elapsed: %lu us\n", | 152 | " expires: %lu elapsed: %lu us\n", |
| 153 | atomic_read(&dst_total), delayed, work_performed, | 153 | atomic_read(&dst_total), delayed, work_performed, |
| 154 | expires, | 154 | expires, |
| 155 | elapsed.tv_sec * USEC_PER_SEC + elapsed.tv_nsec / NSEC_PER_USEC); | 155 | elapsed.tv_sec * USEC_PER_SEC + |
| 156 | elapsed.tv_nsec / NSEC_PER_USEC); | ||
| 156 | #endif | 157 | #endif |
| 157 | } | 158 | } |
| 158 | 159 | ||
| @@ -163,9 +164,9 @@ int dst_discard(struct sk_buff *skb) | |||
| 163 | } | 164 | } |
| 164 | EXPORT_SYMBOL(dst_discard); | 165 | EXPORT_SYMBOL(dst_discard); |
| 165 | 166 | ||
| 166 | void * dst_alloc(struct dst_ops * ops) | 167 | void *dst_alloc(struct dst_ops *ops) |
| 167 | { | 168 | { |
| 168 | struct dst_entry * dst; | 169 | struct dst_entry *dst; |
| 169 | 170 | ||
| 170 | if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) { | 171 | if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) { |
| 171 | if (ops->gc(ops)) | 172 | if (ops->gc(ops)) |
| @@ -185,19 +186,20 @@ void * dst_alloc(struct dst_ops * ops) | |||
| 185 | atomic_inc(&ops->entries); | 186 | atomic_inc(&ops->entries); |
| 186 | return dst; | 187 | return dst; |
| 187 | } | 188 | } |
| 189 | EXPORT_SYMBOL(dst_alloc); | ||
| 188 | 190 | ||
| 189 | static void ___dst_free(struct dst_entry * dst) | 191 | static void ___dst_free(struct dst_entry *dst) |
| 190 | { | 192 | { |
| 191 | /* The first case (dev==NULL) is required, when | 193 | /* The first case (dev==NULL) is required, when |
| 192 | protocol module is unloaded. | 194 | protocol module is unloaded. |
| 193 | */ | 195 | */ |
| 194 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { | 196 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) |
| 195 | dst->input = dst->output = dst_discard; | 197 | dst->input = dst->output = dst_discard; |
| 196 | } | ||
| 197 | dst->obsolete = 2; | 198 | dst->obsolete = 2; |
| 198 | } | 199 | } |
| 200 | EXPORT_SYMBOL(__dst_free); | ||
| 199 | 201 | ||
| 200 | void __dst_free(struct dst_entry * dst) | 202 | void __dst_free(struct dst_entry *dst) |
| 201 | { | 203 | { |
| 202 | spin_lock_bh(&dst_garbage.lock); | 204 | spin_lock_bh(&dst_garbage.lock); |
| 203 | ___dst_free(dst); | 205 | ___dst_free(dst); |
| @@ -262,15 +264,16 @@ again: | |||
| 262 | } | 264 | } |
| 263 | return NULL; | 265 | return NULL; |
| 264 | } | 266 | } |
| 267 | EXPORT_SYMBOL(dst_destroy); | ||
| 265 | 268 | ||
| 266 | void dst_release(struct dst_entry *dst) | 269 | void dst_release(struct dst_entry *dst) |
| 267 | { | 270 | { |
| 268 | if (dst) { | 271 | if (dst) { |
| 269 | int newrefcnt; | 272 | int newrefcnt; |
| 270 | 273 | ||
| 271 | smp_mb__before_atomic_dec(); | 274 | smp_mb__before_atomic_dec(); |
| 272 | newrefcnt = atomic_dec_return(&dst->__refcnt); | 275 | newrefcnt = atomic_dec_return(&dst->__refcnt); |
| 273 | WARN_ON(newrefcnt < 0); | 276 | WARN_ON(newrefcnt < 0); |
| 274 | } | 277 | } |
| 275 | } | 278 | } |
| 276 | EXPORT_SYMBOL(dst_release); | 279 | EXPORT_SYMBOL(dst_release); |
| @@ -283,8 +286,8 @@ EXPORT_SYMBOL(dst_release); | |||
| 283 | * | 286 | * |
| 284 | * Commented and originally written by Alexey. | 287 | * Commented and originally written by Alexey. |
| 285 | */ | 288 | */ |
| 286 | static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | 289 | static void dst_ifdown(struct dst_entry *dst, struct net_device *dev, |
| 287 | int unregister) | 290 | int unregister) |
| 288 | { | 291 | { |
| 289 | if (dst->ops->ifdown) | 292 | if (dst->ops->ifdown) |
| 290 | dst->ops->ifdown(dst, dev, unregister); | 293 | dst->ops->ifdown(dst, dev, unregister); |
| @@ -306,7 +309,8 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
| 306 | } | 309 | } |
| 307 | } | 310 | } |
| 308 | 311 | ||
| 309 | static int dst_dev_event(struct notifier_block *this, unsigned long event, void *ptr) | 312 | static int dst_dev_event(struct notifier_block *this, unsigned long event, |
| 313 | void *ptr) | ||
| 310 | { | 314 | { |
| 311 | struct net_device *dev = ptr; | 315 | struct net_device *dev = ptr; |
| 312 | struct dst_entry *dst, *last = NULL; | 316 | struct dst_entry *dst, *last = NULL; |
| @@ -329,9 +333,8 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void | |||
| 329 | last->next = dst; | 333 | last->next = dst; |
| 330 | else | 334 | else |
| 331 | dst_busy_list = dst; | 335 | dst_busy_list = dst; |
| 332 | for (; dst; dst = dst->next) { | 336 | for (; dst; dst = dst->next) |
| 333 | dst_ifdown(dst, dev, event != NETDEV_DOWN); | 337 | dst_ifdown(dst, dev, event != NETDEV_DOWN); |
| 334 | } | ||
| 335 | mutex_unlock(&dst_gc_mutex); | 338 | mutex_unlock(&dst_gc_mutex); |
| 336 | break; | 339 | break; |
| 337 | } | 340 | } |
| @@ -346,7 +349,3 @@ void __init dst_init(void) | |||
| 346 | { | 349 | { |
| 347 | register_netdevice_notifier(&dst_dev_notifier); | 350 | register_netdevice_notifier(&dst_dev_notifier); |
| 348 | } | 351 | } |
| 349 | |||
| 350 | EXPORT_SYMBOL(__dst_free); | ||
| 351 | EXPORT_SYMBOL(dst_alloc); | ||
| 352 | EXPORT_SYMBOL(dst_destroy); | ||
