aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/netpoll.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2014-03-14 20:50:58 -0700
committerDavid S. Miller <davem@davemloft.net>2014-03-17 15:48:12 -0400
commite1bd4d3d7dd2a4a0e731ffe07c439927c23f16ea (patch)
tree1ea21340270dcd91feda2d8ed397dffa3d22a5ae /net/core/netpoll.c
parentnetpoll: Consolidate neigh_tx processing in service_neigh_queue (diff)
downloadlinux-dev-e1bd4d3d7dd2a4a0e731ffe07c439927c23f16ea.tar.xz
linux-dev-e1bd4d3d7dd2a4a0e731ffe07c439927c23f16ea.zip
netpoll: Move all receive processing under CONFIG_NETPOLL_TRAP
Make rx_skb_hook, and rx in struct netpoll depend on CONFIG_NETPOLL_TRAP Make rx_lock, rx_np, and neigh_tx in struct netpoll_info depend on CONFIG_NETPOLL_TRAP Make the functions netpoll_rx_on, netpoll_rx, and netpoll_receive_skb no-ops when CONFIG_NETPOLL_TRAP is not set. Only build netpoll_neigh_reply, checksum_udp service_neigh_queue, pkt_is_ns, and __netpoll_rx when CONFIG_NETPOLL_TRAP is defined. Add helper functions netpoll_trap_setup, netpoll_trap_setup_info, netpoll_trap_cleanup, and netpoll_trap_cleanup_info that initialize and cleanup the struct netpoll and struct netpoll_info receive specific fields when CONFIG_NETPOLL_TRAP is enabled and do nothing otherwise. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r--net/core/netpoll.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b69bb3f1ba3f..eed8b1d2d302 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -48,6 +48,7 @@ static struct sk_buff_head skb_pool;
#ifdef CONFIG_NETPOLL_TRAP
static atomic_t trapped;
+static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo);
#endif
DEFINE_STATIC_SRCU(netpoll_srcu);
@@ -61,7 +62,6 @@ DEFINE_STATIC_SRCU(netpoll_srcu);
MAX_UDP_CHUNK)
static void zap_completion_queue(void);
-static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo);
static void netpoll_async_cleanup(struct work_struct *work);
static unsigned int carrier_timeout = 4;
@@ -109,6 +109,7 @@ static void queue_process(struct work_struct *work)
}
}
+#ifdef CONFIG_NETPOLL_TRAP
static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
unsigned short ulen, __be32 saddr, __be32 daddr)
{
@@ -127,6 +128,7 @@ static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
return __skb_checksum_complete(skb);
}
+#endif /* CONFIG_NETPOLL_TRAP */
/*
* Check whether delayed processing was scheduled for our NIC. If so,
@@ -179,6 +181,7 @@ static void poll_napi(struct net_device *dev, int budget)
}
}
+#ifdef CONFIG_NETPOLL_TRAP
static void service_neigh_queue(struct net_device *dev,
struct netpoll_info *npi)
{
@@ -197,6 +200,12 @@ static void service_neigh_queue(struct net_device *dev,
while ((skb = skb_dequeue(&npi->neigh_tx)))
netpoll_neigh_reply(skb, npi);
}
+#else /* !CONFIG_NETPOLL_TRAP */
+static inline void service_neigh_queue(struct net_device *dev,
+ struct netpoll_info *npi)
+{
+}
+#endif /* CONFIG_NETPOLL_TRAP */
static void netpoll_poll_dev(struct net_device *dev)
{
@@ -522,6 +531,7 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
}
EXPORT_SYMBOL(netpoll_send_udp);
+#ifdef CONFIG_NETPOLL_TRAP
static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo)
{
int size, type = ARPOP_REPLY;
@@ -900,6 +910,55 @@ out:
return 0;
}
+static void netpoll_trap_setup_info(struct netpoll_info *npinfo)
+{
+ INIT_LIST_HEAD(&npinfo->rx_np);
+ spin_lock_init(&npinfo->rx_lock);
+ skb_queue_head_init(&npinfo->neigh_tx);
+}
+
+static void netpoll_trap_cleanup_info(struct netpoll_info *npinfo)
+{
+ skb_queue_purge(&npinfo->neigh_tx);
+}
+
+static void netpoll_trap_setup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+ unsigned long flags;
+ if (np->rx_skb_hook) {
+ spin_lock_irqsave(&npinfo->rx_lock, flags);
+ list_add_tail(&np->rx, &npinfo->rx_np);
+ spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+ }
+}
+
+static void netpoll_trap_cleanup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+ unsigned long flags;
+ if (!list_empty(&npinfo->rx_np)) {
+ spin_lock_irqsave(&npinfo->rx_lock, flags);
+ list_del(&np->rx);
+ spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+ }
+}
+
+#else /* !CONFIG_NETPOLL_TRAP */
+static inline void netpoll_trap_setup_info(struct netpoll_info *npinfo)
+{
+}
+static inline void netpoll_trap_cleanup_info(struct netpoll_info *npinfo)
+{
+}
+static inline
+void netpoll_trap_setup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+}
+static inline
+void netpoll_trap_cleanup(struct netpoll *np, struct netpoll_info *npinfo)
+{
+}
+#endif /* CONFIG_NETPOLL_TRAP */
+
void netpoll_print_options(struct netpoll *np)
{
np_info(np, "local port %d\n", np->local_port);
@@ -1023,7 +1082,6 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp)
{
struct netpoll_info *npinfo;
const struct net_device_ops *ops;
- unsigned long flags;
int err;
np->dev = ndev;
@@ -1045,11 +1103,9 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp)
goto out;
}
- INIT_LIST_HEAD(&npinfo->rx_np);
+ netpoll_trap_setup_info(npinfo);
- spin_lock_init(&npinfo->rx_lock);
sema_init(&npinfo->dev_lock, 1);
- skb_queue_head_init(&npinfo->neigh_tx);
skb_queue_head_init(&npinfo->txq);
INIT_DELAYED_WORK(&npinfo->tx_work, queue_process);
@@ -1068,11 +1124,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp)
npinfo->netpoll = np;
- if (np->rx_skb_hook) {
- spin_lock_irqsave(&npinfo->rx_lock, flags);
- list_add_tail(&np->rx, &npinfo->rx_np);
- spin_unlock_irqrestore(&npinfo->rx_lock, flags);
- }
+ netpoll_trap_setup(np, npinfo);
/* last thing to do is link it to the net device structure */
rcu_assign_pointer(ndev->npinfo, npinfo);
@@ -1222,7 +1274,7 @@ static void rcu_cleanup_netpoll_info(struct rcu_head *rcu_head)
struct netpoll_info *npinfo =
container_of(rcu_head, struct netpoll_info, rcu);
- skb_queue_purge(&npinfo->neigh_tx);
+ netpoll_trap_cleanup_info(npinfo);
skb_queue_purge(&npinfo->txq);
/* we can't call cancel_delayed_work_sync here, as we are in softirq */
@@ -1238,7 +1290,6 @@ static void rcu_cleanup_netpoll_info(struct rcu_head *rcu_head)
void __netpoll_cleanup(struct netpoll *np)
{
struct netpoll_info *npinfo;
- unsigned long flags;
/* rtnl_dereference would be preferable here but
* rcu_cleanup_netpoll path can put us in here safely without
@@ -1248,11 +1299,7 @@ void __netpoll_cleanup(struct netpoll *np)
if (!npinfo)
return;
- if (!list_empty(&npinfo->rx_np)) {
- spin_lock_irqsave(&npinfo->rx_lock, flags);
- list_del(&np->rx);
- spin_unlock_irqrestore(&npinfo->rx_lock, flags);
- }
+ netpoll_trap_cleanup(np, npinfo);
synchronize_srcu(&netpoll_srcu);