diff options
author | Ying Xue <ying.xue@windriver.com> | 2013-12-10 20:45:42 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-11 00:17:43 -0500 |
commit | 6e967adf798ae5066488fd0c2b2466d06c642f23 (patch) | |
tree | 5087be7329e5f2fd83c0f92e5cade64fd3c0d545 /net/tipc/eth_media.c | |
parent | 37cb0620073cb64101d9307931c135c70b2e3f04 (diff) | |
download | op-kernel-dev-6e967adf798ae5066488fd0c2b2466d06c642f23.zip op-kernel-dev-6e967adf798ae5066488fd0c2b2466d06c642f23.tar.gz |
tipc: relocate common functions from media to bearer
Currently, registering a TIPC stack handler in the network device layer
is done twice, once for Ethernet (eth_media) and Infiniband (ib_media)
repectively. But, as this registration is not media specific, we can
avoid some code duplication by moving the registering function to
the generic bearer layer, to the file bearer.c, and call it only once.
The same is true for the network device event notifier.
As a side effect, the two workqueues we are using for for setting up/
cleaning up media can now be eliminated. Furthermore, the array for
storing the specific media type structs, media_array[], can be entirely
deleted.
Note that the eth_started and ib_started flags were removed during the
code relocation. There is now only one call to bearer_setup and
bearer_cleanup, and these can logically not race against each other.
Despite its size, this cleanup work incurs no functional changes in TIPC.
In particular, it should be noted that the sequence ordering of received
packets is unaffected by this change, since packet reception never was
subject to any work queue handling in the first place.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Cc: Patrick McHardy <kaber@trash.net>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/eth_media.c')
-rw-r--r-- | net/tipc/eth_media.c | 199 |
1 files changed, 3 insertions, 196 deletions
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index c5f685d..f28f716 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -37,49 +37,9 @@ #include "core.h" #include "bearer.h" -#define MAX_ETH_MEDIA MAX_BEARERS - #define ETH_ADDR_OFFSET 4 /* message header offset of MAC address */ /** - * struct eth_media - Ethernet bearer data structure - * @bearer: ptr to associated "generic" bearer structure - * @dev: ptr to associated Ethernet network device - * @tipc_packet_type: used in binding TIPC to Ethernet driver - * @setup: work item used when enabling bearer - * @cleanup: work item used when disabling bearer - */ -struct eth_media { - struct tipc_bearer *bearer; - struct net_device *dev; - struct packet_type tipc_packet_type; - struct work_struct setup; - struct work_struct cleanup; -}; - - -static struct eth_media eth_media_array[MAX_ETH_MEDIA]; -static int eth_started; - -static int recv_notification(struct notifier_block *nb, unsigned long evt, - void *dv); -static int recv_msg(struct sk_buff *buf, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev); - -/* - * Network device notifier info - */ -static struct notifier_block notifier = { - .notifier_call = recv_notification, - .priority = 0 -}; - -static struct packet_type tipc_packet_type __read_mostly = { - .type = __constant_htons(ETH_P_TIPC), - .func = recv_msg, -}; - -/** * eth_media_addr_set - initialize Ethernet media address structure * * Media-dependent "value" field stores MAC address in first 6 bytes @@ -101,16 +61,14 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, struct tipc_media_addr *dest) { struct sk_buff *clone; - struct net_device *dev; int delta; + struct net_device *dev = tb_ptr->dev; clone = skb_clone(buf, GFP_ATOMIC); if (!clone) return 0; - dev = ((struct eth_media *)(tb_ptr->usr_handle))->dev; delta = dev->hard_header_len - skb_headroom(buf); - if ((delta > 0) && pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { kfree_skb(clone); @@ -127,79 +85,21 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, } /** - * recv_msg - handle incoming TIPC message from an Ethernet interface - * - * Accept only packets explicitly sent to this node, or broadcast packets; - * ignores packets sent using Ethernet multicast, and traffic sent to other - * nodes (which can happen if interface is running in promiscuous mode). - */ -static int recv_msg(struct sk_buff *buf, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct tipc_bearer *b_ptr; - - if (!net_eq(dev_net(dev), &init_net)) { - kfree_skb(buf); - return NET_RX_DROP; - } - - rcu_read_lock(); - b_ptr = rcu_dereference(dev->tipc_ptr); - if (likely(b_ptr)) { - if (likely(buf->pkt_type <= PACKET_BROADCAST)) { - buf->next = NULL; - tipc_recv_msg(buf, b_ptr); - rcu_read_unlock(); - return NET_RX_SUCCESS; - } - } - rcu_read_unlock(); - - kfree_skb(buf); - return NET_RX_DROP; -} - -/** - * setup_media - setup association between Ethernet bearer and interface - */ -static void setup_media(struct work_struct *work) -{ - dev_add_pack(&tipc_packet_type); -} - -/** * enable_media - attach TIPC bearer to an Ethernet interface */ static int enable_media(struct tipc_bearer *tb_ptr) { struct net_device *dev; - struct eth_media *eb_ptr = ð_media_array[0]; - struct eth_media *stop = ð_media_array[MAX_ETH_MEDIA]; char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; - int pending_dev = 0; - - /* Find unused Ethernet bearer structure */ - while (eb_ptr->dev) { - if (!eb_ptr->bearer) - pending_dev++; - if (++eb_ptr == stop) - return pending_dev ? -EAGAIN : -EDQUOT; - } /* Find device with specified name */ dev = dev_get_by_name(&init_net, driver_name); if (!dev) return -ENODEV; - /* Create Ethernet bearer for device */ - eb_ptr->dev = dev; - INIT_WORK(&eb_ptr->setup, setup_media); - schedule_work(&eb_ptr->setup); - /* Associate TIPC bearer with Ethernet bearer */ tb_ptr->dev = dev; - eb_ptr->bearer = tb_ptr; - tb_ptr->usr_handle = (void *)eb_ptr; + tb_ptr->usr_handle = NULL; memset(tb_ptr->bcast_addr.value, 0, sizeof(tb_ptr->bcast_addr.value)); memcpy(tb_ptr->bcast_addr.value, dev->broadcast, ETH_ALEN); tb_ptr->bcast_addr.media_id = TIPC_MEDIA_TYPE_ETH; @@ -211,21 +111,6 @@ static int enable_media(struct tipc_bearer *tb_ptr) } /** - * cleanup_media - break association between Ethernet bearer and interface - * - * This routine must be invoked from a work queue because it can sleep. - */ -static void cleanup_media(struct work_struct *work) -{ - struct eth_media *eb_ptr = - container_of(work, struct eth_media, cleanup); - - dev_remove_pack(&tipc_packet_type); - dev_put(eb_ptr->dev); - eb_ptr->dev = NULL; -} - -/** * disable_media - detach TIPC bearer from an Ethernet interface * * Mark Ethernet bearer as inactive so that incoming buffers are thrown away, @@ -234,55 +119,8 @@ static void cleanup_media(struct work_struct *work) */ static void disable_media(struct tipc_bearer *tb_ptr) { - struct eth_media *eb_ptr = (struct eth_media *)tb_ptr->usr_handle; - - eb_ptr->bearer = NULL; - INIT_WORK(&eb_ptr->cleanup, cleanup_media); - schedule_work(&eb_ptr->cleanup); RCU_INIT_POINTER(tb_ptr->dev->tipc_ptr, NULL); -} - -/** - * recv_notification - handle device updates from OS - * - * Change the state of the Ethernet bearer (if any) associated with the - * specified device. - */ -static int recv_notification(struct notifier_block *nb, unsigned long evt, - void *ptr) -{ - struct tipc_bearer *b_ptr; - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - - if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - rcu_read_lock(); - b_ptr = rcu_dereference(dev->tipc_ptr); - if (!b_ptr) { - rcu_read_unlock(); - return NOTIFY_DONE; /* bearer had been disabled */ - } - - b_ptr->mtu = dev->mtu; - - switch (evt) { - case NETDEV_CHANGE: - if (netif_carrier_ok(dev)) - break; - case NETDEV_DOWN: - case NETDEV_CHANGEMTU: - case NETDEV_CHANGEADDR: - tipc_reset_bearer(b_ptr); - break; - case NETDEV_UNREGISTER: - case NETDEV_CHANGENAME: - tipc_disable_bearer(b_ptr->name); - break; - } - rcu_read_unlock(); - - return NOTIFY_OK; + dev_put(tb_ptr->dev); } /** @@ -338,34 +176,3 @@ struct tipc_media eth_media_info = { .name = "eth" }; -/** - * tipc_eth_media_start - activate Ethernet bearer support - * - * Register Ethernet media type with TIPC bearer code. Also register - * with OS for notifications about device state changes. - */ -int tipc_eth_media_start(void) -{ - int res; - - if (eth_started) - return -EINVAL; - - res = register_netdevice_notifier(¬ifier); - if (!res) - eth_started = 1; - return res; -} - -/** - * tipc_eth_media_stop - deactivate Ethernet bearer support - */ -void tipc_eth_media_stop(void) -{ - if (!eth_started) - return; - - flush_scheduled_work(); - unregister_netdevice_notifier(¬ifier); - eth_started = 0; -} |