link_watch.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Linux network device link state notification
  3. *
  4. * Author:
  5. * Stefan Rompf <sux@loplof.de>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version
  10. * 2 of the License, or (at your option) any later version.
  11. *
  12. */
  13. #include <linux/config.h>
  14. #include <linux/module.h>
  15. #include <linux/netdevice.h>
  16. #include <linux/if.h>
  17. #include <net/sock.h>
  18. #include <linux/rtnetlink.h>
  19. #include <linux/jiffies.h>
  20. #include <linux/spinlock.h>
  21. #include <linux/list.h>
  22. #include <linux/slab.h>
  23. #include <linux/workqueue.h>
  24. #include <linux/bitops.h>
  25. #include <asm/types.h>
  26. enum lw_bits {
  27. LW_RUNNING = 0,
  28. LW_SE_USED
  29. };
  30. static unsigned long linkwatch_flags;
  31. static unsigned long linkwatch_nextevent;
  32. static void linkwatch_event(void *dummy);
  33. static DECLARE_WORK(linkwatch_work, linkwatch_event, NULL);
  34. static LIST_HEAD(lweventlist);
  35. static DEFINE_SPINLOCK(lweventlist_lock);
  36. struct lw_event {
  37. struct list_head list;
  38. struct net_device *dev;
  39. };
  40. /* Avoid kmalloc() for most systems */
  41. static struct lw_event singleevent;
  42. /* Must be called with the rtnl semaphore held */
  43. void linkwatch_run_queue(void)
  44. {
  45. LIST_HEAD(head);
  46. struct list_head *n, *next;
  47. spin_lock_irq(&lweventlist_lock);
  48. list_splice_init(&lweventlist, &head);
  49. spin_unlock_irq(&lweventlist_lock);
  50. list_for_each_safe(n, next, &head) {
  51. struct lw_event *event = list_entry(n, struct lw_event, list);
  52. struct net_device *dev = event->dev;
  53. if (event == &singleevent) {
  54. clear_bit(LW_SE_USED, &linkwatch_flags);
  55. } else {
  56. kfree(event);
  57. }
  58. /* We are about to handle this device,
  59. * so new events can be accepted
  60. */
  61. clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
  62. if (dev->flags & IFF_UP) {
  63. netdev_state_change(dev);
  64. }
  65. dev_put(dev);
  66. }
  67. }
  68. static void linkwatch_event(void *dummy)
  69. {
  70. /* Limit the number of linkwatch events to one
  71. * per second so that a runaway driver does not
  72. * cause a storm of messages on the netlink
  73. * socket
  74. */
  75. linkwatch_nextevent = jiffies + HZ;
  76. clear_bit(LW_RUNNING, &linkwatch_flags);
  77. rtnl_shlock();
  78. linkwatch_run_queue();
  79. rtnl_shunlock();
  80. }
  81. void linkwatch_fire_event(struct net_device *dev)
  82. {
  83. if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) {
  84. unsigned long flags;
  85. struct lw_event *event;
  86. if (test_and_set_bit(LW_SE_USED, &linkwatch_flags)) {
  87. event = kmalloc(sizeof(struct lw_event), GFP_ATOMIC);
  88. if (unlikely(event == NULL)) {
  89. clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
  90. return;
  91. }
  92. } else {
  93. event = &singleevent;
  94. }
  95. dev_hold(dev);
  96. event->dev = dev;
  97. spin_lock_irqsave(&lweventlist_lock, flags);
  98. list_add_tail(&event->list, &lweventlist);
  99. spin_unlock_irqrestore(&lweventlist_lock, flags);
  100. if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) {
  101. unsigned long thisevent = jiffies;
  102. if (thisevent >= linkwatch_nextevent) {
  103. schedule_work(&linkwatch_work);
  104. } else {
  105. schedule_delayed_work(&linkwatch_work, linkwatch_nextevent - thisevent);
  106. }
  107. }
  108. }
  109. }
  110. EXPORT_SYMBOL(linkwatch_fire_event);