public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Garzik <jgarzik@pobox.com>
To: Matt Mackall <mpm@selenic.com>
Cc: Andrew Morton <akpm@osdl.org>,
	Robert Walsh <rjwalsh@durables.org>,
	wangdi <wangdi@clusterfs.com>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 1/3] netpoll-core
Date: Mon, 22 Sep 2003 20:58:02 -0400	[thread overview]
Message-ID: <3F6F9A9A.9030003@pobox.com> (raw)
In-Reply-To: <20030922184526.GL2414@waste.org>

Matt Mackall wrote:

> +void netpoll_poll(struct netpoll *np)
> +{
> +	int budget = 1;
> +
> +	if(!np || !np->dev || !(np->dev->flags & IFF_UP))
> +		return;

should test netif_running() not IFF_UP, IMO


> +	disable_irq(np->dev->irq);
> +
> +	/* Process pending work on NIC */
> +	np->irqfunc(np->dev->irq, np->dev, 0);
> +
> +	/* If scheduling is stopped, tickle NAPI bits */
> +	if(trapped && np->dev->poll &&
> +	   test_bit(__LINK_STATE_RX_SCHED, &np->dev->state))
> +		np->dev->poll(np->dev, &budget);
> +
> +	enable_irq(np->dev->irq);
> +}

Calling the irq function from two different places, netpoll code and 
arch code, worries me.


> +static void refill_skbs(void)
> +{
> +	struct sk_buff *skb;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&skb_list_lock, flags);
> +	while (nr_skbs < MAX_SKBS) {
> +		skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
> +		if (!skb)
> +			break;
> +
> +		skb->next = skbs;
> +		skbs = skb;
> +		nr_skbs++;
> +	}
> +	spin_unlock_irqrestore(&skb_list_lock, flags);
> +}

if it's a simple list, why not lock, find out number of allocations, 
unlock, allocate a bunch of skbs, then finally lock again and tie back 
into list.


> +static void zap_completion_queue(void)
> +{
> +	unsigned long flags;
> +	struct softnet_data *sd = &get_cpu_var(softnet_data);
> +
> +	if (sd->completion_queue) {
> +		struct sk_buff *clist;
> +
> +		local_irq_save(flags);
> +		clist = sd->completion_queue;
> +		sd->completion_queue = NULL;
> +		local_irq_save(flags);
> +
> +		while (clist != NULL) {
> +			struct sk_buff *skb = clist;
> +			clist = clist->next;
> +			__kfree_skb(skb);
> +		}
> +	}
> +
> +	put_cpu_var(softnet_data);
> +}

this should be somewhere in a more general place...  otherwise, somebody 
will inevitably change softnet and forget to change this code.



> +void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
> +{
> +	int status;
> +
> +repeat:
> +	if(!np || !np->dev || !(np->dev->flags & IFF_UP)) {

netif_running()


> +	spin_lock(&np->dev->xmit_lock);
> +	np->dev->xmit_lock_owner = smp_processor_id();
> +
> +	if (netif_queue_stopped(np->dev)) {
> +		np->dev->xmit_lock_owner = -1;
> +		spin_unlock(&np->dev->xmit_lock);
> +
> +		netpoll_poll(np);
> +		zap_completion_queue();
> +		goto repeat;
> +	}
> +
> +	status = np->dev->hard_start_xmit(skb, np->dev);
> +	np->dev->xmit_lock_owner = -1;
> +	spin_unlock(&np->dev->xmit_lock);

this worries be too, but I don't have any outright objections.  Mainly 
similar to the above comments -- this is intimate with the net stack 
locking, and at the very least shouldn't be hidden in a little-used 
corner of the code :)



> +static int rx_hook(struct sk_buff *skb)
[...]

> diff -puN include/linux/netdevice.h~netpoll-core include/linux/netdevice.h
> --- l/include/linux/netdevice.h~netpoll-core	2003-09-22 13:15:31.000000000 -0500
> +++ l-mpm/include/linux/netdevice.h	2003-09-22 13:15:31.000000000 -0500
> @@ -452,13 +452,13 @@ struct net_device
>  						     unsigned char *haddr);
>  	int			(*neigh_setup)(struct net_device *dev, struct neigh_parms *);
>  	int			(*accept_fastpath)(struct net_device *, struct dst_entry*);
> +#ifdef CONFIG_NETPOLL
> +	int			(*rx_hook)(struct sk_buff *skb);
> +#endif
[...]
> diff -puN net/core/dev.c~netpoll-core net/core/dev.c
> --- l/net/core/dev.c~netpoll-core	2003-09-22 13:15:31.000000000 -0500
> +++ l-mpm/net/core/dev.c	2003-09-22 13:16:34.000000000 -0500
[...]
> @@ -1552,6 +1541,13 @@ int netif_receive_skb(struct sk_buff *sk
>  	int ret = NET_RX_DROP;
>  	unsigned short type = skb->protocol;
>  
> +#ifdef CONFIG_NETPOLL
> +	if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) {
> +		kfree_skb(skb);
> +		return NET_RX_DROP;
> +	}
> +#endif

This allows wholesale replacement of the IPv4 net stack, something we've 
traditionally avoided.

	Jeff




  reply	other threads:[~2003-09-23  0:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-09-22 18:45 [PATCH 1/3] netpoll-core Matt Mackall
2003-09-23  0:58 ` Jeff Garzik [this message]
2003-09-23  4:16   ` Matt Mackall
2003-09-23  1:19 ` Paul Mundt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3F6F9A9A.9030003@pobox.com \
    --to=jgarzik@pobox.com \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpm@selenic.com \
    --cc=rjwalsh@durables.org \
    --cc=wangdi@clusterfs.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox