All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.