hv_netvsc: rework link status change handling

There are several issues in hv_netvsc driver with regards to link status
change handling:
- RNDIS_STATUS_NETWORK_CHANGE results in calling userspace helper doing
  '/etc/init.d/network restart' and this is inappropriate and broken for
  many reasons.
- link_watch infrastructure only sends one notification per second and
  in case of e.g. paired disconnect/connect events we get only one
  notification with last status. This makes it impossible to handle such
  situations in userspace.

Redo link status changes handling in the following way:
- Create a list of reconfig events in network device context.
- On a reconfig event add it to the list of events and schedule
  netvsc_link_change().
- In netvsc_link_change() ensure 2-second delay between link status
  changes.
- Handle RNDIS_STATUS_NETWORK_CHANGE as a paired disconnect/connect event.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vitaly Kuznetsov
2015-11-27 11:39:55 +01:00
committed by David S. Miller
parent 77b75f4d8c
commit 27a70af3f4
2 changed files with 109 additions and 49 deletions

View File

@@ -177,7 +177,6 @@ struct rndis_device {
enum rndis_device_state state;
bool link_state;
bool link_change;
atomic_t new_req_id;
spinlock_t request_lock;
@@ -644,11 +643,24 @@ struct netvsc_stats {
struct u64_stats_sync syncp;
};
struct netvsc_reconfig {
struct list_head list;
u32 event;
};
/* The context of the netvsc device */
struct net_device_context {
/* point back to our device context */
struct hv_device *device_ctx;
/* reconfigure work */
struct delayed_work dwork;
/* last reconfig time */
unsigned long last_reconfig;
/* reconfig events */
struct list_head reconfig_events;
/* list protection */
spinlock_t lock;
struct work_struct work;
u32 msg_enable; /* debug level */