local_irq_save(flags);
netif_tx_lock(dev);
if ((netif_queue_stopped(dev) ||
- netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+ netif_subqueue_stopped(dev, skb)) ||
dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
skb_queue_head(&npinfo->txq, skb);
netif_tx_unlock(dev);
* network adapter, forcing superfluous retries and possibly timeouts.
* Thus, we set our budget to greater than 1.
*/
+static int poll_one_napi(struct netpoll_info *npinfo,
+ struct napi_struct *napi, int budget)
+{
+ int work;
+
+ /* net_rx_action's ->poll() invocations and our's are
+ * synchronized by this test which is only made while
+ * holding the napi->poll_lock.
+ */
+ if (!test_bit(NAPI_STATE_SCHED, &napi->state))
+ return budget;
+
+ npinfo->rx_flags |= NETPOLL_RX_DROP;
+ atomic_inc(&trapped);
+
+ work = napi->poll(napi, budget);
+
+ atomic_dec(&trapped);
+ npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+
+ return budget - work;
+}
+
static void poll_napi(struct netpoll *np)
{
struct netpoll_info *npinfo = np->dev->npinfo;
int budget = 16;
list_for_each_entry(napi, &np->dev->napi_list, dev_list) {
- if (test_bit(NAPI_STATE_SCHED, &napi->state) &&
- napi->poll_owner != smp_processor_id() &&
+ if (napi->poll_owner != smp_processor_id() &&
spin_trylock(&napi->poll_lock)) {
- npinfo->rx_flags |= NETPOLL_RX_DROP;
- atomic_inc(&trapped);
-
- napi->poll(napi, budget);
-
- atomic_dec(&trapped);
- npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+ budget = poll_one_napi(npinfo, napi, budget);
spin_unlock(&napi->poll_lock);
+
+ if (!budget)
+ break;
}
}
}
tries > 0; --tries) {
if (netif_tx_trylock(dev)) {
if (!netif_queue_stopped(dev) &&
- !netif_subqueue_stopped(dev, skb->queue_mapping))
+ !netif_subqueue_stopped(dev, skb))
status = dev->hard_start_xmit(skb, dev);
netif_tx_unlock(dev);
send_skb->protocol = htons(ETH_P_ARP);
/* Fill the device header for the ARP frame */
-
- if (np->dev->hard_header &&
- np->dev->hard_header(send_skb, skb->dev, ptype,
- sha, np->local_mac,
- send_skb->len) < 0) {
+ if (dev_hard_header(send_skb, skb->dev, ptype,
+ sha, np->local_mac,
+ send_skb->len) < 0) {
kfree_skb(send_skb);
return;
}
return 0;
}
+void netpoll_print_options(struct netpoll *np)
+{
+ DECLARE_MAC_BUF(mac);
+ printk(KERN_INFO "%s: local port %d\n",
+ np->name, np->local_port);
+ printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
+ np->name, HIPQUAD(np->local_ip));
+ printk(KERN_INFO "%s: interface %s\n",
+ np->name, np->dev_name);
+ printk(KERN_INFO "%s: remote port %d\n",
+ np->name, np->remote_port);
+ printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
+ np->name, HIPQUAD(np->remote_ip));
+ printk(KERN_INFO "%s: remote ethernet address %s\n",
+ np->name, print_mac(mac, np->remote_mac));
+}
+
int netpoll_parse_options(struct netpoll *np, char *opt)
{
char *cur=opt, *delim;
cur = delim;
}
cur++;
- printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port);
if (*cur != '/') {
if ((delim = strchr(cur, '/')) == NULL)
*delim = 0;
np->local_ip = ntohl(in_aton(cur));
cur = delim;
-
- printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
- np->name, HIPQUAD(np->local_ip));
}
cur++;
}
cur++;
- printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name);
-
if (*cur != '@') {
/* dst port */
if ((delim = strchr(cur, '@')) == NULL)
cur = delim;
}
cur++;
- printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port);
/* dst ip */
if ((delim = strchr(cur, '/')) == NULL)
np->remote_ip = ntohl(in_aton(cur));
cur = delim + 1;
- printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
- np->name, HIPQUAD(np->remote_ip));
-
if (*cur != 0) {
/* MAC address */
if ((delim = strchr(cur, ':')) == NULL)
np->remote_mac[5] = simple_strtol(cur, NULL, 16);
}
- printk(KERN_INFO "%s: remote ethernet address "
- "%02x:%02x:%02x:%02x:%02x:%02x\n",
- np->name,
- np->remote_mac[0],
- np->remote_mac[1],
- np->remote_mac[2],
- np->remote_mac[3],
- np->remote_mac[4],
- np->remote_mac[5]);
+ netpoll_print_options(np);
return 0;
int err;
if (np->dev_name)
- ndev = dev_get_by_name(np->dev_name);
+ ndev = dev_get_by_name(&init_net, np->dev_name);
if (!ndev) {
printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
np->name, np->dev_name);
EXPORT_SYMBOL(netpoll_set_trap);
EXPORT_SYMBOL(netpoll_trap);
+EXPORT_SYMBOL(netpoll_print_options);
EXPORT_SYMBOL(netpoll_parse_options);
EXPORT_SYMBOL(netpoll_setup);
EXPORT_SYMBOL(netpoll_cleanup);