Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] A device for zero-copy based on KVM virtio-net.
From: Michael S. Tsirkin @ 2010-04-07  8:15 UTC (permalink / raw)
  To: Xin, Xiaohui
  Cc: netdev@vger.kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, mingo@elte.hu,
	jdike@c2.user-mode-linux.org, yzhao81@gmail.com
In-Reply-To: <97F6D3BD476C464182C1B7BABF0B0AF5C183234A@shzsmsx502.ccr.corp.intel.com>

On Wed, Apr 07, 2010 at 10:41:08AM +0800, Xin, Xiaohui wrote:
> Michael,
>  
> >> Qemu needs a userspace write, is that a synchronous one or
> >>asynchronous one?
> 
> >It's a synchronous non-blocking write.
> Sorry, why the Qemu live migration needs the device have a userspace write?
> how does the write operation work? And why a read operation is not cared here?
> 
> Thanks
> Xiaohui

Roughly, with ethernet bridges, moving a device from one location in
the network to another makes forwarding tables incorrect (or incomplete),
until outgoing traffic from the device causes these tables
to be updated. Since there's no guarantee that guest
will generate outgoing traffic, after migration qemu sends out several
dummy packets itself.

-- 
MST

^ permalink raw reply

* Re: [PATCH v1 2/3] Provides multiple submits and asynchronous notifications.
From: Michael S. Tsirkin @ 2010-04-07  8:18 UTC (permalink / raw)
  To: Xin, Xiaohui
  Cc: netdev@vger.kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, mingo@elte.hu, jdike@addtoit.com
In-Reply-To: <97F6D3BD476C464182C1B7BABF0B0AF5C17B5EB2@shzsmsx502.ccr.corp.intel.com>

On Wed, Apr 07, 2010 at 09:36:36AM +0800, Xin, Xiaohui wrote:
> Michael,
> > > >>>> For the write logging, do you have a function in hand that we can
> > > >>>> recompute the log? If that, I think I can use it to recompute the
> > > >>>>log info when the logging is suddenly enabled.
> > > >>>> For the outstanding requests, do you mean all the user buffers have
> > > >>>>submitted before the logging ioctl changed? That may be a lot, and
> > > >> >>some of them are still in NIC ring descriptors. Waiting them to be
> > > >>>>finished may be need some time. I think when logging ioctl changed,
> > > >> >>then the logging is changed just after that is also reasonable.
> 
> > > >>>The key point is that after loggin ioctl returns, any
> > > >>>subsequent change to memory must be logged. It does not
> > > >>>matter when was the request submitted, otherwise we will
> > > >>>get memory corruption on migration.
> 
> > > >>The change to memory happens when vhost_add_used_and_signal(), right?
> > > >>So after ioctl returns, just recompute the log info to the events in the async queue,
> > > >>is ok. Since the ioctl and write log operations are all protected by vq->mutex.
> 
> > >>> Thanks
> > >> >Xiaohui
> 
> > >>Yes, I think this will work.
> 
> >> Thanks, so do you have the function to recompute the log info in your hand that I can
> >>use? I have weakly remembered that you have noticed it before some time.
> 
> >Doesn't just rerunning vhost_get_vq_desc work?
> 
> Am I missing something here?
> The vhost_get_vq_desc() looks in vq, and finds the first available buffers, and converts it
> to an iovec. I think the first available buffer is not the buffers in the async queue, so I
> think rerunning vhost_get_vq_desc() cannot work.
> 
> Thanks
> Xiaohui

Right, but we can move the head back, so we'll find the same buffers
again, or add a variant of vhost_get_vq_desc that will process
descriptors already consumed.

> > > > Thanks
> > > > Xiaohui
> > > >
> > > >  drivers/vhost/net.c   |  189 +++++++++++++++++++++++++++++++++++++++++++++++--
> > > >  drivers/vhost/vhost.h |   10 +++
> > > >  2 files changed, 192 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> > > > index 22d5fef..2aafd90 100644
> > > > --- a/drivers/vhost/net.c
> > > > +++ b/drivers/vhost/net.c
> > > > @@ -17,11 +17,13 @@
> > > >  #include <linux/workqueue.h>
> > > >  #include <linux/rcupdate.h>
> > > >  #include <linux/file.h>
> > > > +#include <linux/aio.h>
> > > >
> > > >  #include <linux/net.h>
> > > >  #include <linux/if_packet.h>
> > > >  #include <linux/if_arp.h>
> > > >  #include <linux/if_tun.h>
> > > > +#include <linux/mpassthru.h>
> > > >
> > > >  #include <net/sock.h>
> > > >
> > > > @@ -47,6 +49,7 @@ struct vhost_net {
> > > >   struct vhost_dev dev;
> > > >   struct vhost_virtqueue vqs[VHOST_NET_VQ_MAX];
> > > >   struct vhost_poll poll[VHOST_NET_VQ_MAX];
> > > > + struct kmem_cache       *cache;
> > > >   /* Tells us whether we are polling a socket for TX.
> > > >    * We only do this when socket buffer fills up.
> > > >    * Protected by tx vq lock. */
> > > > @@ -91,11 +94,88 @@ static void tx_poll_start(struct vhost_net *net, struct socket *sock)
> > > >   net->tx_poll_state = VHOST_NET_POLL_STARTED;
> > > >  }
> > > >
> > > > +struct kiocb *notify_dequeue(struct vhost_virtqueue *vq)
> > > > +{
> > > > + struct kiocb *iocb = NULL;
> > > > + unsigned long flags;
> > > > +
> > > > + spin_lock_irqsave(&vq->notify_lock, flags);
> > > > + if (!list_empty(&vq->notifier)) {
> > > > +         iocb = list_first_entry(&vq->notifier,
> > > > +                         struct kiocb, ki_list);
> > > > +         list_del(&iocb->ki_list);
> > > > + }
> > > > + spin_unlock_irqrestore(&vq->notify_lock, flags);
> > > > + return iocb;
> > > > +}
> > > > +
> > > > +static void handle_async_rx_events_notify(struct vhost_net *net,
> > > > +                                 struct vhost_virtqueue *vq)
> > > > +{
> > > > + struct kiocb *iocb = NULL;
> > > > + struct vhost_log *vq_log = NULL;
> > > > + int rx_total_len = 0;
> > > > + int log, size;
> > > > +
> > > > + if (vq->link_state != VHOST_VQ_LINK_ASYNC)
> > > > +         return;
> > > > +
> > > > + if (vq->receiver)
> > > > +         vq->receiver(vq);
> > > > +
> > > > + vq_log = unlikely(vhost_has_feature(
> > > > +                         &net->dev, VHOST_F_LOG_ALL)) ? vq->log : NULL;
> > > > + while ((iocb = notify_dequeue(vq)) != NULL) {
> > > > +         vhost_add_used_and_signal(&net->dev, vq,
> > > > +                         iocb->ki_pos, iocb->ki_nbytes);
> > > > +         log = (int)iocb->ki_user_data;
> > > > +         size = iocb->ki_nbytes;
> > > > +         rx_total_len += iocb->ki_nbytes;
> > > > +
> > > > +         if (iocb->ki_dtor)
> > > > +                 iocb->ki_dtor(iocb);
> > > > +         kmem_cache_free(net->cache, iocb);
> > > > +
> > > > +         if (unlikely(vq_log))
> > > > +                 vhost_log_write(vq, vq_log, log, size);
> > > > +         if (unlikely(rx_total_len >= VHOST_NET_WEIGHT)) {
> > > > +                 vhost_poll_queue(&vq->poll);
> > > > +                 break;
> > > > +         }
> > > > + }
> > > > +}
> > > > +
> > > > +static void handle_async_tx_events_notify(struct vhost_net *net,
> > > > +                                 struct vhost_virtqueue *vq)
> > > > +{
> > > > + struct kiocb *iocb = NULL;
> > > > + int tx_total_len = 0;
> > > > +
> > > > + if (vq->link_state != VHOST_VQ_LINK_ASYNC)
> > > > +         return;
> > > > +
> > > > + while ((iocb = notify_dequeue(vq)) != NULL) {
> > > > +         vhost_add_used_and_signal(&net->dev, vq,
> > > > +                         iocb->ki_pos, 0);
> > > > +         tx_total_len += iocb->ki_nbytes;
> > > > +
> > > > +         if (iocb->ki_dtor)
> > > > +                 iocb->ki_dtor(iocb);
> > > > +
> > > > +         kmem_cache_free(net->cache, iocb);
> > > > +         if (unlikely(tx_total_len >= VHOST_NET_WEIGHT)) {
> > > > +                 vhost_poll_queue(&vq->poll);
> > > > +                 break;
> > > > +         }
> > > > + }
> > > > +}
> > > > +
> > > >  /* Expects to be always run from workqueue - which acts as
> > > >   * read-size critical section for our kind of RCU. */
> > > >  static void handle_tx(struct vhost_net *net)
> > > >  {
> > > >   struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX];
> > > > + struct kiocb *iocb = NULL;
> > > >   unsigned head, out, in, s;
> > > >   struct msghdr msg = {
> > > >           .msg_name = NULL,
> > > > @@ -124,6 +204,8 @@ static void handle_tx(struct vhost_net *net)
> > > >           tx_poll_stop(net);
> > > >   hdr_size = vq->hdr_size;
> > > >
> > > > + handle_async_tx_events_notify(net, vq);
> > > > +
> > > >   for (;;) {
> > > >           head = vhost_get_vq_desc(&net->dev, vq, vq->iov,
> > > >                                    ARRAY_SIZE(vq->iov),
> > > > @@ -151,6 +233,15 @@ static void handle_tx(struct vhost_net *net)
> > > >           /* Skip header. TODO: support TSO. */
> > > >           s = move_iovec_hdr(vq->iov, vq->hdr, hdr_size, out);
> > > >           msg.msg_iovlen = out;
> > > > +
> > > > +         if (vq->link_state == VHOST_VQ_LINK_ASYNC) {
> > > > +                 iocb = kmem_cache_zalloc(net->cache, GFP_KERNEL);
> > > > +                 if (!iocb)
> > > > +                         break;
> > > > +                 iocb->ki_pos = head;
> > > > +                 iocb->private = (void *)vq;
> > > > +         }
> > > > +
> > > >           len = iov_length(vq->iov, out);
> > > >           /* Sanity check */
> > > >           if (!len) {
> > > > @@ -160,12 +251,16 @@ static void handle_tx(struct vhost_net *net)
> > > >                   break;
> > > >           }
> > > >           /* TODO: Check specific error and bomb out unless ENOBUFS? */
> > > > -         err = sock->ops->sendmsg(NULL, sock, &msg, len);
> > > > +         err = sock->ops->sendmsg(iocb, sock, &msg, len);
> > > >           if (unlikely(err < 0)) {
> > > >                   vhost_discard_vq_desc(vq);
> > > >                   tx_poll_start(net, sock);
> > > >                   break;
> > > >           }
> > > > +
> > > > +         if (vq->link_state == VHOST_VQ_LINK_ASYNC)
> > > > +                 continue;
> > > > +
> > > >           if (err != len)
> > > >                   pr_err("Truncated TX packet: "
> > > >                          " len %d != %zd\n", err, len);
> > > > @@ -177,6 +272,8 @@ static void handle_tx(struct vhost_net *net)
> > > >           }
> > > >   }
> > > >
> > > > + handle_async_tx_events_notify(net, vq);
> > > > +
> > > >   mutex_unlock(&vq->mutex);
> > > >   unuse_mm(net->dev.mm);
> > > >  }
> > > > @@ -186,6 +283,7 @@ static void handle_tx(struct vhost_net *net)
> > > >  static void handle_rx(struct vhost_net *net)
> > > >  {
> > > >   struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
> > > > + struct kiocb *iocb = NULL;
> > > >   unsigned head, out, in, log, s;
> > > >   struct vhost_log *vq_log;
> > > >   struct msghdr msg = {
> > > > @@ -206,7 +304,8 @@ static void handle_rx(struct vhost_net *net)
> > > >   int err;
> > > >   size_t hdr_size;
> > > >   struct socket *sock = rcu_dereference(vq->private_data);
> > > > - if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue))
> > > > + if (!sock || (skb_queue_empty(&sock->sk->sk_receive_queue) &&
> > > > +                 vq->link_state == VHOST_VQ_LINK_SYNC))
> > > >           return;
> > > >
> > > >   use_mm(net->dev.mm);
> > > > @@ -214,9 +313,18 @@ static void handle_rx(struct vhost_net *net)
> > > >   vhost_disable_notify(vq);
> > > >   hdr_size = vq->hdr_size;
> > > >
> > > > - vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ?
> > > > + /* In async cases, for write logging, the simple way is to get
> > > > +  * the log info always, and really logging is decided later.
> > > > +  * Thus, when logging enabled, we can get log, and when logging
> > > > +  * disabled, we can get log disabled accordingly.
> > > > +  */
> > > > +
> > > > + vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) |
> > > > +         (vq->link_state == VHOST_VQ_LINK_ASYNC) ?
> > > >           vq->log : NULL;
> > > >
> > > > + handle_async_rx_events_notify(net, vq);
> > > > +
> > > >   for (;;) {
> > > >           head = vhost_get_vq_desc(&net->dev, vq, vq->iov,
> > > >                                    ARRAY_SIZE(vq->iov),
> > > > @@ -245,6 +353,14 @@ static void handle_rx(struct vhost_net *net)
> > > >           s = move_iovec_hdr(vq->iov, vq->hdr, hdr_size, in);
> > > >           msg.msg_iovlen = in;
> > > >           len = iov_length(vq->iov, in);
> > > > +         if (vq->link_state == VHOST_VQ_LINK_ASYNC) {
> > > > +                 iocb = kmem_cache_zalloc(net->cache, GFP_KERNEL);
> > > > +                 if (!iocb)
> > > > +                         break;
> > > > +                 iocb->private = vq;
> > > > +                 iocb->ki_pos = head;
> > > > +                 iocb->ki_user_data = log;
> > > > +         }
> > > >           /* Sanity check */
> > > >           if (!len) {
> > > >                   vq_err(vq, "Unexpected header len for RX: "
> > > > @@ -252,13 +368,18 @@ static void handle_rx(struct vhost_net *net)
> > > >                          iov_length(vq->hdr, s), hdr_size);
> > > >                   break;
> > > >           }
> > > > -         err = sock->ops->recvmsg(NULL, sock, &msg,
> > > > +
> > > > +         err = sock->ops->recvmsg(iocb, sock, &msg,
> > > >                                    len, MSG_DONTWAIT | MSG_TRUNC);
> > > >           /* TODO: Check specific error and bomb out unless EAGAIN? */
> > > >           if (err < 0) {
> > > >                   vhost_discard_vq_desc(vq);
> > > >                   break;
> > > >           }
> > > > +
> > > > +         if (vq->link_state == VHOST_VQ_LINK_ASYNC)
> > > > +                 continue;
> > > > +
> > > >           /* TODO: Should check and handle checksum. */
> > > >           if (err > len) {
> > > >                   pr_err("Discarded truncated rx packet: "
> > > > @@ -284,10 +405,13 @@ static void handle_rx(struct vhost_net *net)
> > > >           }
> > > >   }
> > > >
> > > > + handle_async_rx_events_notify(net, vq);
> > > > +
> > > >   mutex_unlock(&vq->mutex);
> > > >   unuse_mm(net->dev.mm);
> > > >  }
> > > >
> > > > +
> > > >  static void handle_tx_kick(struct work_struct *work)
> > > >  {
> > > >   struct vhost_virtqueue *vq;
> > > > @@ -338,6 +462,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
> > > >   vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT);
> > > >   vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN);
> > > >   n->tx_poll_state = VHOST_NET_POLL_DISABLED;
> > > > + n->cache = NULL;
> > > >   return 0;
> > > >  }
> > > >
> > > > @@ -398,6 +523,17 @@ static void vhost_net_flush(struct vhost_net *n)
> > > >   vhost_net_flush_vq(n, VHOST_NET_VQ_RX);
> > > >  }
> > > >
> > > > +static void vhost_notifier_cleanup(struct vhost_net *n)
> > > > +{
> > > > + struct vhost_virtqueue *vq = &n->dev.vqs[VHOST_NET_VQ_RX];
> > > > + struct kiocb *iocb = NULL;
> > > > + if (n->cache) {
> > > > +         while ((iocb = notify_dequeue(vq)) != NULL)
> > > > +                 kmem_cache_free(n->cache, iocb);
> > > > +         kmem_cache_destroy(n->cache);
> > > > + }
> > > > +}
> > > > +
> > > >  static int vhost_net_release(struct inode *inode, struct file *f)
> > > >  {
> > > >   struct vhost_net *n = f->private_data;
> > > > @@ -414,6 +550,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
> > > >   /* We do an extra flush before freeing memory,
> > > >    * since jobs can re-queue themselves. */
> > > >   vhost_net_flush(n);
> > > > + vhost_notifier_cleanup(n);
> > > >   kfree(n);
> > > >   return 0;
> > > >  }
> > > > @@ -462,7 +599,19 @@ static struct socket *get_tun_socket(int fd)
> > > >   return sock;
> > > >  }
> > > >
> > > > -static struct socket *get_socket(int fd)
> > > > +static struct socket *get_mp_socket(int fd)
> > > > +{
> > > > + struct file *file = fget(fd);
> > > > + struct socket *sock;
> > > > + if (!file)
> > > > +         return ERR_PTR(-EBADF);
> > > > + sock = mp_get_socket(file);
> > > > + if (IS_ERR(sock))
> > > > +         fput(file);
> > > > + return sock;
> > > > +}
> > > > +
> > > > +static struct socket *get_socket(struct vhost_virtqueue *vq, int fd)
> > > >  {
> > > >   struct socket *sock;
> > > >   if (fd == -1)
> > > > @@ -473,9 +622,31 @@ static struct socket *get_socket(int fd)
> > > >   sock = get_tun_socket(fd);
> > > >   if (!IS_ERR(sock))
> > > >           return sock;
> > > > + sock = get_mp_socket(fd);
> > > > + if (!IS_ERR(sock)) {
> > > > +         vq->link_state = VHOST_VQ_LINK_ASYNC;
> > > > +         return sock;
> > > > + }
> > > >   return ERR_PTR(-ENOTSOCK);
> > > >  }
> > > >
> > > > +static void vhost_init_link_state(struct vhost_net *n, int index)
> > > > +{
> > > > + struct vhost_virtqueue *vq = n->vqs + index;
> > > > +
> > > > + WARN_ON(!mutex_is_locked(&vq->mutex));
> > > > + if (vq->link_state == VHOST_VQ_LINK_ASYNC) {
> > > > +         vq->receiver = NULL;
> > > > +         INIT_LIST_HEAD(&vq->notifier);
> > > > +         spin_lock_init(&vq->notify_lock);
> > > > +         if (!n->cache) {
> > > > +                 n->cache = kmem_cache_create("vhost_kiocb",
> > > > +                                 sizeof(struct kiocb), 0,
> > > > +                                 SLAB_HWCACHE_ALIGN, NULL);
> > > > +         }
> > > > + }
> > > > +}
> > > > +
> > > >  static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
> > > >  {
> > > >   struct socket *sock, *oldsock;
> > > > @@ -493,12 +664,15 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
> > > >   }
> > > >   vq = n->vqs + index;
> > > >   mutex_lock(&vq->mutex);
> > > > - sock = get_socket(fd);
> > > > + vq->link_state = VHOST_VQ_LINK_SYNC;
> > > > + sock = get_socket(vq, fd);
> > > >   if (IS_ERR(sock)) {
> > > >           r = PTR_ERR(sock);
> > > >           goto err;
> > > >   }
> > > >
> > > > + vhost_init_link_state(n, index);
> > > > +
> > > >   /* start polling new socket */
> > > >   oldsock = vq->private_data;
> > > >   if (sock == oldsock)
> > > > @@ -507,8 +681,8 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
> > > >   vhost_net_disable_vq(n, vq);
> > > >   rcu_assign_pointer(vq->private_data, sock);
> > > >   vhost_net_enable_vq(n, vq);
> > > > - mutex_unlock(&vq->mutex);
> > > >  done:
> > > > + mutex_unlock(&vq->mutex);
> > > >   mutex_unlock(&n->dev.mutex);
> > > >   if (oldsock) {
> > > >           vhost_net_flush_vq(n, index);
> > > > @@ -516,6 +690,7 @@ done:
> > > >   }
> > > >   return r;
> > > >  err:
> > > > + mutex_unlock(&vq->mutex);
> > > >   mutex_unlock(&n->dev.mutex);
> > > >   return r;
> > > >  }
> > > > diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> > > > index d1f0453..cffe39a 100644
> > > > --- a/drivers/vhost/vhost.h
> > > > +++ b/drivers/vhost/vhost.h
> > > > @@ -43,6 +43,11 @@ struct vhost_log {
> > > >   u64 len;
> > > >  };
> > > >
> > > > +enum vhost_vq_link_state {
> > > > + VHOST_VQ_LINK_SYNC =    0,
> > > > + VHOST_VQ_LINK_ASYNC =   1,
> > > > +};
> > > > +
> > > >  /* The virtqueue structure describes a queue attached to a device. */
> > > >  struct vhost_virtqueue {
> > > >   struct vhost_dev *dev;
> > > > @@ -96,6 +101,11 @@ struct vhost_virtqueue {
> > > >   /* Log write descriptors */
> > > >   void __user *log_base;
> > > >   struct vhost_log log[VHOST_NET_MAX_SG];
> > > > + /*Differiate async socket for 0-copy from normal*/
> > > > + enum vhost_vq_link_state link_state;
> > > > + struct list_head notifier;
> > > > + spinlock_t notify_lock;
> > > > + void (*receiver)(struct vhost_virtqueue *);
> > > >  };
> > > >
> > > >  struct vhost_dev {
> > > > --
> > > > 1.5.4.4

^ permalink raw reply

* [PATCH 7/7] au1000-eth: bump to 1.7
From: Florian Fainelli @ 2010-04-07  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 5afca6c..7abb2c8 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -80,7 +80,7 @@ static int au1000_debug = 3;
 				NETIF_MSG_LINK)
 
 #define DRV_NAME	"au1000_eth"
-#define DRV_VERSION	"1.6"
+#define DRV_VERSION	"1.7"
 #define DRV_AUTHOR	"Pete Popov <ppopov@embeddedalley.com>"
 #define DRV_DESC	"Au1xxx on-chip Ethernet driver"
 

^ permalink raw reply related

* [PATCH 6/7] au1000-eth: Use (dev|netdev|netif)_<level> macro helpers
From: Florian Fainelli @ 2010-04-07  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 0c59d4c..5afca6c 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -187,8 +187,7 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 	while (*mii_control_reg & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: read_MII busy timeout!!\n",
-					dev->name);
+			netdev_err(dev, "read_MII busy timeout!!\n");
 			return -1;
 		}
 	}
@@ -202,8 +201,7 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 	while (*mii_control_reg & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: mdio_read busy timeout!!\n",
-					dev->name);
+			netdev_err(dev, "mdio_read busy timeout!!\n");
 			return -1;
 		}
 	}
@@ -222,8 +220,7 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr,
 	while (*mii_control_reg & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
-			printk(KERN_ERR "%s: mdio_write busy timeout!!\n",
-					dev->name);
+			netdev_err(dev, "mdio_write busy timeout!!\n");
 			return;
 		}
 	}
@@ -270,8 +267,7 @@ static void au1000_hard_stop(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
-	if (au1000_debug > 4)
-		printk(KERN_INFO "%s: hard stop\n", dev->name);
+	netif_dbg(aup, drv, dev, "hard stop\n");
 
 	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
 	au_sync_delay(10);
@@ -281,8 +277,7 @@ static void au1000_enable_rx_tx(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
-	if (au1000_debug > 4)
-		printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
+	netif_dbg(aup, hw, dev, "enable_rx_tx\n");
 
 	aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
 	au_sync_delay(10);
@@ -309,9 +304,8 @@ au1000_adjust_link(struct net_device *dev)
 		case SPEED_100:
 			break;
 		default:
-			printk(KERN_WARNING
-			       "%s: Speed (%d) is not 10/100 ???\n",
-			       dev->name, phydev->speed);
+			netdev_warn(dev, "Speed (%d) is not 10/100 ???\n",
+							phydev->speed);
 			break;
 		}
 
@@ -359,11 +353,11 @@ au1000_adjust_link(struct net_device *dev)
 
 	if (status_change) {
 		if (phydev->link)
-			printk(KERN_INFO "%s: link up (%d/%s)\n",
-			       dev->name, phydev->speed,
+			netdev_info(dev, "link up (%d/%s)\n",
+			       phydev->speed,
 			       DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
 		else
-			printk(KERN_INFO "%s: link down\n", dev->name);
+			netdev_info(dev, "link down\n");
 	}
 }
 
@@ -378,8 +372,7 @@ static int au1000_mii_probe (struct net_device *dev)
 		if (aup->phy_addr)
 			phydev = aup->mii_bus->phy_map[aup->phy_addr];
 		else
-			printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
-				dev->name);
+			netdev_info(dev, "using PHY-less setup\n");
 		return 0;
 	} else {
 		int phy_addr;
@@ -396,7 +389,7 @@ static int au1000_mii_probe (struct net_device *dev)
 			/* try harder to find a PHY */
 			if (!phydev && (aup->mac_id == 1)) {
 				/* no PHY found, maybe we have a dual PHY? */
-				printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
+				dev_info(&dev->dev, ": no PHY found on MAC1, "
 					"let's see if it's attached to MAC0...\n");
 
 				/* find the first (lowest address) non-attached PHY on
@@ -422,7 +415,7 @@ static int au1000_mii_probe (struct net_device *dev)
 	}
 
 	if (!phydev) {
-		printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name);
+		netdev_err(dev, "no PHY found\n");
 		return -1;
 	}
 
@@ -433,7 +426,7 @@ static int au1000_mii_probe (struct net_device *dev)
 			0, PHY_INTERFACE_MODE_MII);
 
 	if (IS_ERR(phydev)) {
-		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+		netdev_err(dev, "Could not attach to PHY\n");
 		return PTR_ERR(phydev);
 	}
 
@@ -454,8 +447,8 @@ static int au1000_mii_probe (struct net_device *dev)
 	aup->old_duplex = -1;
 	aup->phy_dev = phydev;
 
-	printk(KERN_INFO "%s: attached PHY driver [%s] "
-	       "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+	netdev_info(dev, "attached PHY driver [%s] "
+	       "(mii_bus:phy_addr=%s, irq=%d)\n",
 	       phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
 
 	return 0;
@@ -517,9 +510,8 @@ static void au1000_reset_mac(struct net_device *dev)
 	struct au1000_private *const aup = netdev_priv(dev);
 	unsigned long flags;
 
-	if (au1000_debug > 4)
-		printk(KERN_INFO "%s: reset mac, aup %x\n",
-		       dev->name, (unsigned)aup);
+	netif_dbg(aup, hw, dev, "reset mac, aup %x\n",
+					(unsigned)aup);
 
 	spin_lock_irqsave(&aup->lock, flags);
 
@@ -625,8 +617,7 @@ static int au1000_init(struct net_device *dev)
 	int i;
 	u32 control;
 
-	if (au1000_debug > 4)
-		printk("%s: au1000_init\n", dev->name);
+	netif_dbg(aup, hw, dev, "au1000_init\n");
 
 	/* bring the device out of reset */
 	au1000_enable_mac(dev, 1);
@@ -703,8 +694,7 @@ static int au1000_rx(struct net_device *dev)
 	db_dest_t *pDB;
 	u32	frmlen;
 
-	if (au1000_debug > 5)
-		printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
+	netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head);
 
 	prxd = aup->rx_dma_ring[aup->rx_head];
 	buff_stat = prxd->buff_stat;
@@ -719,9 +709,7 @@ static int au1000_rx(struct net_device *dev)
 			frmlen -= 4; /* Remove FCS */
 			skb = dev_alloc_skb(frmlen + 2);
 			if (skb == NULL) {
-				printk(KERN_ERR
-				       "%s: Memory squeeze, dropping packet.\n",
-				       dev->name);
+				netdev_err(dev, "Memory squeeze, dropping packet.\n");
 				dev->stats.rx_dropped++;
 				continue;
 			}
@@ -833,20 +821,18 @@ static int au1000_open(struct net_device *dev)
 	int retval;
 	struct au1000_private *aup = netdev_priv(dev);
 
-	if (au1000_debug > 4)
-		printk("%s: open: dev=%p\n", dev->name, dev);
+	netif_dbg(aup, drv, dev, "open: dev=%p\n", dev);
 
 	retval = request_irq(dev->irq, au1000_interrupt, 0,
 					dev->name, dev);
 	if (retval) {
-		printk(KERN_ERR "%s: unable to get IRQ %d\n",
-				dev->name, dev->irq);
+		netdev_err(dev, "unable to get IRQ %d\n", dev->irq);
 		return retval;
 	}
 
 	retval = au1000_init(dev);
 	if (retval) {
-		printk(KERN_ERR "%s: error in au1000_init\n", dev->name);
+		netdev_err(dev, "error in au1000_init\n");
 		free_irq(dev->irq, dev);
 		return retval;
 	}
@@ -859,8 +845,7 @@ static int au1000_open(struct net_device *dev)
 
 	netif_start_queue(dev);
 
-	if (au1000_debug > 4)
-		printk("%s: open: Initialization done.\n", dev->name);
+	netif_dbg(aup, drv, dev, "open: Initialization done.\n");
 
 	return 0;
 }
@@ -870,8 +855,7 @@ static int au1000_close(struct net_device *dev)
 	unsigned long flags;
 	struct au1000_private *const aup = netdev_priv(dev);
 
-	if (au1000_debug > 4)
-		printk("%s: close: dev=%p\n", dev->name, dev);
+	netif_dbg(aup, drv, dev, "close: dev=%p\n", dev);
 
 	if (aup->phy_dev)
 		phy_stop(aup->phy_dev);
@@ -902,9 +886,8 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 	db_dest_t *pDB;
 	int i;
 
-	if (au1000_debug > 5)
-		printk("%s: tx: aup %x len=%d, data=%p, head %d\n",
-				dev->name, (unsigned)aup, skb->len,
+	netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n",
+				(unsigned)aup, skb->len,
 				skb->data, aup->tx_head);
 
 	ptxd = aup->tx_dma_ring[aup->tx_head];
@@ -951,7 +934,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
  */
 static void au1000_tx_timeout(struct net_device *dev)
 {
-	printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev);
+	netdev_err(dev, "au1000_tx_timeout: dev=%p\n", dev);
 	au1000_reset_mac(dev);
 	au1000_init(dev);
 	dev->trans_start = jiffies;
@@ -962,8 +945,7 @@ static void au1000_multicast_list(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
-	if (au1000_debug > 4)
-		printk("%s: au1000_multicast_list: flags=%x\n", dev->name, dev->flags);
+	netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n", dev->flags);
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		aup->mac->control |= MAC_PROMISCUOUS;
@@ -971,7 +953,7 @@ static void au1000_multicast_list(struct net_device *dev)
 			   netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
 		aup->mac->control |= MAC_PASS_ALL_MULTI;
 		aup->mac->control &= ~MAC_PROMISCUOUS;
-		printk(KERN_INFO "%s: Pass all multicast\n", dev->name);
+		netdev_info(dev, "Pass all multicast\n");
 	} else {
 		struct netdev_hw_addr *ha;
 		u32 mc_filter[2];	/* Multicast hash filter */
@@ -1025,40 +1007,40 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!base) {
-		printk(KERN_ERR DRV_NAME ": failed to retrieve base register\n");
+		dev_err(&pdev->dev, "failed to retrieve base register\n");
 		err = -ENODEV;
 		goto out;
 	}
 
 	macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!macen) {
-		printk(KERN_ERR DRV_NAME ": failed to retrieve MAC Enable register\n");
+		dev_err(&pdev->dev, "failed to retrieve MAC Enable register\n");
 		err = -ENODEV;
 		goto out;
 	}
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
-		printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n");
+		dev_err(&pdev->dev, "failed to retrieve IRQ\n");
 		err = -ENODEV;
 		goto out;
 	}
 
 	if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
-		printk(KERN_ERR DRV_NAME ": failed to request memory region for base registers\n");
+		dev_err(&pdev->dev, "failed to request memory region for base registers\n");
 		err = -ENXIO;
 		goto out;
 	}
 
 	if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
-		printk(KERN_ERR DRV_NAME ": failed to request memory region for MAC enable register\n");
+		dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n");
 		err = -ENXIO;
 		goto err_request;
 	}
 
 	dev = alloc_etherdev(sizeof(struct au1000_private));
 	if (!dev) {
-		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
+		dev_err(&pdev->dev, "alloc_etherdev failed\n");
 		err = -ENOMEM;
 		goto err_alloc;
 	}
@@ -1076,7 +1058,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 						(NUM_TX_BUFFS + NUM_RX_BUFFS),
 						&aup->dma_addr,	0);
 	if (!aup->vaddr) {
-		printk(KERN_ERR DRV_NAME ": failed to allocate data buffers\n");
+		dev_err(&pdev->dev, "failed to allocate data buffers\n");
 		err = -ENOMEM;
 		goto err_vaddr;
 	}
@@ -1084,7 +1066,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	/* aup->mac is the base address of the MAC's registers */
 	aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
 	if (!aup->mac) {
-		printk(KERN_ERR DRV_NAME ": failed to ioremap MAC registers\n");
+		dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
 		err = -ENXIO;
 		goto err_remap1;
 	}
@@ -1092,7 +1074,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
         /* Setup some variables for quick register address access */
 	aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
 	if (!aup->enable) {
-		printk(KERN_ERR DRV_NAME ": failed to ioremap MAC enable register\n");
+		dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
 		err = -ENXIO;
 		goto err_remap2;
 	}
@@ -1102,8 +1084,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 		if (prom_get_ethernet_addr(ethaddr) == 0)
 			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
 		else {
-			printk(KERN_INFO "%s: No MAC address found\n",
-					 dev->name);
+			netdev_info(dev, "No MAC address found\n");
 				/* Use the hard coded MAC addresses */
 		}
 
@@ -1123,7 +1104,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	pd = pdev->dev.platform_data;
 	if (!pd) {
-		printk(KERN_INFO DRV_NAME ": no platform_data passed, PHY search on MAC0\n");
+		dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n");
 		aup->phy1_search_mac0 = 1;
 	} else {
 		aup->phy_static_config = pd->phy_static_config;
@@ -1135,7 +1116,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	}
 
 	if (aup->phy_busid && aup->phy_busid > 0) {
-		printk(KERN_ERR DRV_NAME ": MAC0-associated PHY attached 2nd MACs MII"
+		dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII"
 				"bus not supported yet\n");
 		err = -ENODEV;
 		goto err_mdiobus_alloc;
@@ -1143,7 +1124,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	aup->mii_bus = mdiobus_alloc();
 	if (aup->mii_bus == NULL) {
-		printk(KERN_ERR DRV_NAME ": failed to allocate mdiobus structure\n");
+		dev_err(&pdev->dev, "failed to allocate mdiobus structure\n");
 		err = -ENOMEM;
 		goto err_mdiobus_alloc;
 	}
@@ -1167,7 +1148,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	err = mdiobus_register(aup->mii_bus);
 	if (err) {
-		printk(KERN_ERR DRV_NAME " failed to register MDIO bus\n");
+		dev_err(&pdev->dev, "failed to register MDIO bus\n");
 		goto err_mdiobus_reg;
 	}
 
@@ -1218,13 +1199,12 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	err = register_netdev(dev);
 	if (err) {
-		printk(KERN_ERR DRV_NAME "%s: Cannot register net device, aborting.\n",
-					dev->name);
+		netdev_err(dev, "Cannot register net device, aborting.\n");
 		goto err_out;
 	}
 
-	printk("%s: Au1xx0 Ethernet found at 0x%lx, irq %d\n",
-			dev->name, (unsigned long)base->start, irq);
+	netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n",
+			(unsigned long)base->start, irq);
 	if (version_printed++ == 0)
 		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
 

^ permalink raw reply related

* [PATCH 5/7] au1000-eth: implement set/get_msglevel
From: Florian Fainelli @ 2010-04-07  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

{set,get}_msglevel is required to use netif_{err,dbg} macros.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 49f56b4..0c59d4c 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -75,6 +75,10 @@ static int au1000_debug = 5;
 static int au1000_debug = 3;
 #endif
 
+#define AU1000_DEF_MSG_ENABLE	(NETIF_MSG_DRV	| \
+				NETIF_MSG_PROBE	| \
+				NETIF_MSG_LINK)
+
 #define DRV_NAME	"au1000_eth"
 #define DRV_VERSION	"1.6"
 #define DRV_AUTHOR	"Pete Popov <ppopov@embeddedalley.com>"
@@ -583,11 +587,25 @@ au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 	info->regdump_len = 0;
 }
 
+static void au1000_set_msglevel(struct net_device *dev, u32 value)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+	aup->msg_enable = value;
+}
+
+static u32 au1000_get_msglevel(struct net_device *dev)
+{
+	struct au1000_private *aup = netdev_priv(dev);
+	return aup->msg_enable;
+}
+
 static const struct ethtool_ops au1000_ethtool_ops = {
 	.get_settings = au1000_get_settings,
 	.set_settings = au1000_set_settings,
 	.get_drvinfo = au1000_get_drvinfo,
 	.get_link = ethtool_op_get_link,
+	.get_msglevel = au1000_get_msglevel,
+	.set_msglevel = au1000_set_msglevel,
 };
 
 
@@ -1050,6 +1068,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	aup = netdev_priv(dev);
 
 	spin_lock_init(&aup->lock);
+	aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug);
 
 	/* Allocate the data buffers */
 	/* Snooping works fine with eth on all au1xxx */
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index 344c600..d06ec00 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -125,4 +125,6 @@ struct au1000_private {
 	dma_addr_t dma_addr;      /* dma address of rx/tx buffers       */
 
 	spinlock_t lock;       /* Serialise access to device */
+
+	u32 msg_enable;
 };

^ permalink raw reply related

* [PATCH 4/7] au1000-eth: fix checkpatch errors.
From: Florian Fainelli @ 2010-04-07  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

This patch fixes multiple errors reported by checkpatch:
- else not on the ending brace of an if { }
- multiple occurences of for( instead of for (
- c99 comments
- assignment and tests on the same line
- test and statements on the same line
- macro with complex value not between parenthesis
- static variable with initialization value

No functionnal change.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 7d40177..49f56b4 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -298,9 +298,9 @@ au1000_adjust_link(struct net_device *dev)
 	spin_lock_irqsave(&aup->lock, flags);
 
 	if (phydev->link && (aup->old_speed != phydev->speed)) {
-		// speed changed
+		/* speed changed */
 
-		switch(phydev->speed) {
+		switch (phydev->speed) {
 		case SPEED_10:
 		case SPEED_100:
 			break;
@@ -317,7 +317,7 @@ au1000_adjust_link(struct net_device *dev)
 	}
 
 	if (phydev->link && (aup->old_duplex != phydev->duplex)) {
-		// duplex mode changed
+		/* duplex mode changed */
 
 		/* switching duplex mode requires to disable rx and tx! */
 		au1000_hard_stop(dev);
@@ -338,8 +338,8 @@ au1000_adjust_link(struct net_device *dev)
 		status_change = 1;
 	}
 
-	if(phydev->link != aup->old_link) {
-		// link state changed
+	if (phydev->link != aup->old_link) {
+		/* link state changed */
 
 		if (!phydev->link) {
 			/* link went down */
@@ -668,8 +668,7 @@ static inline void au1000_update_rx_stats(struct net_device *dev, u32 status)
 			ps->rx_crc_errors++;
 		if (status & RX_COLL)
 			ps->collisions++;
-	}
-	else
+	} else
 		ps->rx_bytes += status & RX_FRAME_LEN_MASK;
 
 }
@@ -714,8 +713,7 @@ static int au1000_rx(struct net_device *dev)
 			skb_put(skb, frmlen);
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);	/* pass the packet to upper layers */
-		}
-		else {
+		} else {
 			if (au1000_debug > 4) {
 				if (status & RX_MISSED_FRAME)
 					printk("rx miss\n");
@@ -761,8 +759,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status)
 				ps->tx_errors++;
 				ps->tx_aborted_errors++;
 			}
-		}
-		else {
+		} else {
 			ps->tx_errors++;
 			ps->tx_aborted_errors++;
 			if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
@@ -821,14 +818,16 @@ static int au1000_open(struct net_device *dev)
 	if (au1000_debug > 4)
 		printk("%s: open: dev=%p\n", dev->name, dev);
 
-	if ((retval = request_irq(dev->irq, au1000_interrupt, 0,
-					dev->name, dev))) {
+	retval = request_irq(dev->irq, au1000_interrupt, 0,
+					dev->name, dev);
+	if (retval) {
 		printk(KERN_ERR "%s: unable to get IRQ %d\n",
 				dev->name, dev->irq);
 		return retval;
 	}
 
-	if ((retval = au1000_init(dev))) {
+	retval = au1000_init(dev);
+	if (retval) {
 		printk(KERN_ERR "%s: error in au1000_init\n", dev->name);
 		free_irq(dev->irq, dev);
 		return retval;
@@ -897,8 +896,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 		aup->tx_full = 1;
 		return NETDEV_TX_BUSY;
-	}
-	else if (buff_stat & TX_T_DONE) {
+	} else if (buff_stat & TX_T_DONE) {
 		au1000_update_tx_stats(dev, ptxd->status);
 		ptxd->len = 0;
 	}
@@ -911,12 +909,11 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 	pDB = aup->tx_db_inuse[aup->tx_head];
 	skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
 	if (skb->len < ETH_ZLEN) {
-		for (i=skb->len; i<ETH_ZLEN; i++) {
+		for (i = skb->len; i < ETH_ZLEN; i++) {
 			((char *)pDB->vaddr)[i] = 0;
 		}
 		ptxd->len = ETH_ZLEN;
-	}
-	else
+	} else
 		ptxd->len = skb->len;
 
 	ps->tx_packets++;
@@ -976,9 +973,11 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
-	if (!netif_running(dev)) return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-	if (!aup->phy_dev) return -EINVAL; // PHY not controllable
+	if (!aup->phy_dev)
+		return -EINVAL; /* PHY not controllable */
 
 	return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
 }
@@ -997,7 +996,7 @@ static const struct net_device_ops au1000_netdev_ops = {
 
 static int __devinit au1000_probe(struct platform_device *pdev)
 {
-	static unsigned version_printed = 0;
+	static unsigned version_printed;
 	struct au1000_private *aup = NULL;
 	struct au1000_eth_platform_data *pd;
 	struct net_device *dev = NULL;
@@ -1140,7 +1139,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	if (aup->mii_bus->irq == NULL)
 		goto err_out;
 
-	for(i = 0; i < PHY_MAX_ADDR; ++i)
+	for (i = 0; i < PHY_MAX_ADDR; ++i)
 		aup->mii_bus->irq[i] = PHY_POLL;
 	/* if known, set corresponding PHY IRQs */
 	if (aup->phy_static_config)
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index f9d29a2..344c600 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -35,7 +35,7 @@
 #define NUM_TX_BUFFS 4
 #define MAX_BUF_SIZE 2048
 
-#define ETH_TX_TIMEOUT HZ/4
+#define ETH_TX_TIMEOUT (HZ/4)
 #define MAC_MIN_PKT_SIZE 64
 
 #define MULTICAST_FILTER_LIMIT 64

^ permalink raw reply related

* [PATCH 3/7] au1000-eth: prefix all functions with au1000_
From: Florian Fainelli @ 2010-04-07  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

In order to avoid namespace clashes, prefix all internal driver functions
with au1000_.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index b96abc5..7d40177 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -149,7 +149,7 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
  * specific irq-map
  */
 
-static void enable_mac(struct net_device *dev, int force_reset)
+static void au1000_enable_mac(struct net_device *dev, int force_reset)
 {
 	unsigned long flags;
 	struct au1000_private *aup = netdev_priv(dev);
@@ -237,7 +237,7 @@ static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
 	 * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
 	struct net_device *const dev = bus->priv;
 
-	enable_mac(dev, 0); /* make sure the MAC associated with this
+	au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
 			     * mii_bus is enabled */
 	return au1000_mdio_read(dev, phy_addr, regnum);
 }
@@ -247,7 +247,7 @@ static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
 {
 	struct net_device *const dev = bus->priv;
 
-	enable_mac(dev, 0); /* make sure the MAC associated with this
+	au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
 			     * mii_bus is enabled */
 	au1000_mdio_write(dev, phy_addr, regnum, value);
 	return 0;
@@ -257,12 +257,12 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
 {
 	struct net_device *const dev = bus->priv;
 
-	enable_mac(dev, 0); /* make sure the MAC associated with this
+	au1000_enable_mac(dev, 0); /* make sure the MAC associated with this
 			     * mii_bus is enabled */
 	return 0;
 }
 
-static void hard_stop(struct net_device *dev)
+static void au1000_hard_stop(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
@@ -273,7 +273,7 @@ static void hard_stop(struct net_device *dev)
 	au_sync_delay(10);
 }
 
-static void enable_rx_tx(struct net_device *dev)
+static void au1000_enable_rx_tx(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
@@ -320,7 +320,7 @@ au1000_adjust_link(struct net_device *dev)
 		// duplex mode changed
 
 		/* switching duplex mode requires to disable rx and tx! */
-		hard_stop(dev);
+		au1000_hard_stop(dev);
 
 		if (DUPLEX_FULL == phydev->duplex)
 			aup->mac->control = ((aup->mac->control
@@ -332,7 +332,7 @@ au1000_adjust_link(struct net_device *dev)
 					     | MAC_DISABLE_RX_OWN);
 		au_sync_delay(1);
 
-		enable_rx_tx(dev);
+		au1000_enable_rx_tx(dev);
 		aup->old_duplex = phydev->duplex;
 
 		status_change = 1;
@@ -363,7 +363,7 @@ au1000_adjust_link(struct net_device *dev)
 	}
 }
 
-static int mii_probe (struct net_device *dev)
+static int au1000_mii_probe (struct net_device *dev)
 {
 	struct au1000_private *const aup = netdev_priv(dev);
 	struct phy_device *phydev = NULL;
@@ -463,7 +463,7 @@ static int mii_probe (struct net_device *dev)
  * has the virtual and dma address of a buffer suitable for
  * both, receive and transmit operations.
  */
-static db_dest_t *GetFreeDB(struct au1000_private *aup)
+static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup)
 {
 	db_dest_t *pDB;
 	pDB = aup->pDBfree;
@@ -474,7 +474,7 @@ static db_dest_t *GetFreeDB(struct au1000_private *aup)
 	return pDB;
 }
 
-void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
+void au1000_ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
 {
 	db_dest_t *pDBfree = aup->pDBfree;
 	if (pDBfree)
@@ -482,12 +482,12 @@ void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
 	aup->pDBfree = pDB;
 }
 
-static void reset_mac_unlocked(struct net_device *dev)
+static void au1000_reset_mac_unlocked(struct net_device *dev)
 {
 	struct au1000_private *const aup = netdev_priv(dev);
 	int i;
 
-	hard_stop(dev);
+	au1000_hard_stop(dev);
 
 	*aup->enable = MAC_EN_CLOCK_ENABLE;
 	au_sync_delay(2);
@@ -508,7 +508,7 @@ static void reset_mac_unlocked(struct net_device *dev)
 
 }
 
-static void reset_mac(struct net_device *dev)
+static void au1000_reset_mac(struct net_device *dev)
 {
 	struct au1000_private *const aup = netdev_priv(dev);
 	unsigned long flags;
@@ -519,7 +519,7 @@ static void reset_mac(struct net_device *dev)
 
 	spin_lock_irqsave(&aup->lock, flags);
 
-	reset_mac_unlocked (dev);
+	au1000_reset_mac_unlocked (dev);
 
 	spin_unlock_irqrestore(&aup->lock, flags);
 }
@@ -530,7 +530,7 @@ static void reset_mac(struct net_device *dev)
  * these are not descriptors sitting in memory.
  */
 static void
-setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
+au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
 {
 	int i;
 
@@ -611,7 +611,7 @@ static int au1000_init(struct net_device *dev)
 		printk("%s: au1000_init\n", dev->name);
 
 	/* bring the device out of reset */
-	enable_mac(dev, 1);
+	au1000_enable_mac(dev, 1);
 
 	spin_lock_irqsave(&aup->lock, flags);
 
@@ -650,7 +650,7 @@ static int au1000_init(struct net_device *dev)
 	return 0;
 }
 
-static inline void update_rx_stats(struct net_device *dev, u32 status)
+static inline void au1000_update_rx_stats(struct net_device *dev, u32 status)
 {
 	struct net_device_stats *ps = &dev->stats;
 
@@ -694,7 +694,7 @@ static int au1000_rx(struct net_device *dev)
 	while (buff_stat & RX_T_DONE)  {
 		status = prxd->status;
 		pDB = aup->rx_db_inuse[aup->rx_head];
-		update_rx_stats(dev, status);
+		au1000_update_rx_stats(dev, status);
 		if (!(status & RX_ERROR))  {
 
 			/* good frame */
@@ -748,7 +748,7 @@ static int au1000_rx(struct net_device *dev)
 	return 0;
 }
 
-static void update_tx_stats(struct net_device *dev, u32 status)
+static void au1000_update_tx_stats(struct net_device *dev, u32 status)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 	struct net_device_stats *ps = &dev->stats;
@@ -784,7 +784,7 @@ static void au1000_tx_ack(struct net_device *dev)
 	ptxd = aup->tx_dma_ring[aup->tx_tail];
 
 	while (ptxd->buff_stat & TX_T_DONE) {
-		update_tx_stats(dev, ptxd->status);
+		au1000_update_tx_stats(dev, ptxd->status);
 		ptxd->buff_stat &= ~TX_T_DONE;
 		ptxd->len = 0;
 		au_sync();
@@ -861,7 +861,7 @@ static int au1000_close(struct net_device *dev)
 
 	spin_lock_irqsave(&aup->lock, flags);
 
-	reset_mac_unlocked (dev);
+	au1000_reset_mac_unlocked (dev);
 
 	/* stop the device */
 	netif_stop_queue(dev);
@@ -899,7 +899,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 	else if (buff_stat & TX_T_DONE) {
-		update_tx_stats(dev, ptxd->status);
+		au1000_update_tx_stats(dev, ptxd->status);
 		ptxd->len = 0;
 	}
 
@@ -937,7 +937,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 static void au1000_tx_timeout(struct net_device *dev)
 {
 	printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev);
-	reset_mac(dev);
+	au1000_reset_mac(dev);
 	au1000_init(dev);
 	dev->trans_start = jiffies;
 	netif_wake_queue(dev);
@@ -1089,9 +1089,9 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 				/* Use the hard coded MAC addresses */
 		}
 
-		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
+		au1000_setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
 	} else if (pdev->id == 1)
-		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
+		au1000_setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
 
 	/*
 	 * Assign to the Ethernet ports two consecutive MAC addresses
@@ -1153,7 +1153,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 		goto err_mdiobus_reg;
 	}
 
-	if (mii_probe(dev) != 0)
+	if (au1000_mii_probe(dev) != 0)
 		goto err_out;
 
 	pDBfree = NULL;
@@ -1169,7 +1169,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	aup->pDBfree = pDBfree;
 
 	for (i = 0; i < NUM_RX_DMA; i++) {
-		pDB = GetFreeDB(aup);
+		pDB = au1000_GetFreeDB(aup);
 		if (!pDB) {
 			goto err_out;
 		}
@@ -1177,7 +1177,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 		aup->rx_db_inuse[i] = pDB;
 	}
 	for (i = 0; i < NUM_TX_DMA; i++) {
-		pDB = GetFreeDB(aup);
+		pDB = au1000_GetFreeDB(aup);
 		if (!pDB) {
 			goto err_out;
 		}
@@ -1196,7 +1196,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	 * The boot code uses the ethernet controller, so reset it to start
 	 * fresh.  au1000_init() expects that the device is in reset state.
 	 */
-	reset_mac(dev);
+	au1000_reset_mac(dev);
 
 	err = register_netdev(dev);
 	if (err) {
@@ -1218,15 +1218,15 @@ err_out:
 
 	/* here we should have a valid dev plus aup-> register addresses
 	 * so we can reset the mac properly.*/
-	reset_mac(dev);
+	au1000_reset_mac(dev);
 
 	for (i = 0; i < NUM_RX_DMA; i++) {
 		if (aup->rx_db_inuse[i])
-			ReleaseDB(aup, aup->rx_db_inuse[i]);
+			au1000_ReleaseDB(aup, aup->rx_db_inuse[i]);
 	}
 	for (i = 0; i < NUM_TX_DMA; i++) {
 		if (aup->tx_db_inuse[i])
-			ReleaseDB(aup, aup->tx_db_inuse[i]);
+			au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
 	}
 err_mdiobus_reg:
 	mdiobus_free(aup->mii_bus);
@@ -1262,11 +1262,11 @@ static int __devexit au1000_remove(struct platform_device *pdev)
 
 	for (i = 0; i < NUM_RX_DMA; i++)
 		if (aup->rx_db_inuse[i])
-			ReleaseDB(aup, aup->rx_db_inuse[i]);
+			au1000_ReleaseDB(aup, aup->rx_db_inuse[i]);
 
 	for (i = 0; i < NUM_TX_DMA; i++)
 		if (aup->tx_db_inuse[i])
-			ReleaseDB(aup, aup->tx_db_inuse[i]);
+			au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
 
 	dma_free_noncoherent(NULL, MAX_BUF_SIZE *
 			(NUM_TX_BUFFS + NUM_RX_BUFFS),

^ permalink raw reply related

* [PATCH 2/7] au1000-eth: set MODULE_VERSION
From: Florian Fainelli @ 2010-04-07  8:08 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 2963159..b96abc5 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -83,6 +83,7 @@ static int au1000_debug = 3;
 MODULE_AUTHOR(DRV_AUTHOR);
 MODULE_DESCRIPTION(DRV_DESC);
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 /*
  * Theory of operation

^ permalink raw reply related

* [PATCH 1/7] au1000-eth: allow driver to be compiled as a module
From: Florian Fainelli @ 2010-04-07  8:08 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

This patch allows the au1000-eth driver to be compiled as a module.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 20e2dec..ac2e364 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -483,7 +483,7 @@ config XTENSA_XT2000_SONIC
 	  This is the driver for the onboard card of the Xtensa XT2000 board.
 
 config MIPS_AU1X00_ENET
-	bool "MIPS AU1000 Ethernet support"
+	tristate "MIPS AU1000 Ethernet support"
 	depends on SOC_AU1X00
 	select PHYLIB
 	select CRC32

^ permalink raw reply related

* [PATCH 0/7] au1000-eth cleanups
From: Florian Fainelli @ 2010-04-07  8:08 UTC (permalink / raw)
  To: netdev, David Miller

Hi David,

Here comes a serie of 7 cleanups and small enhancements for the Au1000 
ethernet driver.

Florian Fainelli (7):
  au1000-eth: allow driver to be compiled as a module
  au1000-eth: set MODULE_VERSION
  au1000-eth: prefix all functions with au1000_
  au1000-eth: fix checkpatch errors.
  au1000-eth: implement set/get_msglevel
  au1000-eth: Use (dev|netdev|netif)_<level> macro helpers
  au1000-eth: bump to 1.7

^ permalink raw reply

* Re: RCU problems in fib_table_insert
From: Paul E. McKenney @ 2010-04-07  6:45 UTC (permalink / raw)
  To: Robert Olsson; +Cc: Andi Kleen, robert.olsson, netdev, Jens.Laas
In-Reply-To: <19388.8645.99295.495371@gargle.gargle.HOWL>

On Wed, Apr 07, 2010 at 08:10:13AM +0200, Robert Olsson wrote:
> 
> Paul E. McKenney writes:
>  > On Mon, Mar 22, 2010 at 07:18:34AM +0100, Robert Olsson wrote:
>  > > 
>  > > Seems like Paul and Eric fixed this problem... We use fib_trie with 
>  > > major infrastructure but always disable preempt. It was unsafe w.
>  > > preempt at least before Jareks P. patches about a year ago. I havn't
>  > > tested w. preempt after that but maybe someone else have...
> 
> 
>  > Though I must admit that I would be surprised if there wasn't
>  > more adjustment required in net/ipv4/fib_trie.c -- lots of
>  > rcu_dereference()s in there.
> 
>  Hi, a follow on this thread. 
> 
>  Maybe I was to pessimistic... we've setup  for stress test running during 
>  easter vacation
> 
>  Testing the fib_trie with preempt enabled. Continuesly loading/flushing  
>  "full BGP" via a test script, while routing without the route cache 
>  to further stress locking. Average load about 300 kpps. Some more test 
>  details below.
> 
>  The test was manually stopped after 6 days. So it seems like preempt/rcu 
>  has been improved with fib_trie.

Always happy to be pleasantly surprised.  ;-)

							Thanx, Paul

>  Thanks
> 					--ro
> 
> HW
> --
> CPU  Opteron 2 * 6174, TYAN S8230. Intel 82599
> 
> Kernel from net-next-2.6
> ------------------------
> Version 2.6.34-rc1bifrost-x86_64 (gcc version 4.3.2 (GCC) ) #4 SMP PREEMPT
> CONFIG_PREEMPT=y
> CONFIG_DEBUG_PREEMPT=y
> CONFIG_IP_FIB_TRIE=y
> CONFIG_FIB_RULES=y
> CONFIG_TREE_RCU=y
> CONFIG_RCU_FANOUT=64
> 
> IP table
> --------
> "BGP" 279 k routes
> 
> Test duration
> -------------
> 09:34:14 up 6 days, 20:57,  4 users,  load average: 5.28, 5.87, 5.53
> 
> Test script
> -----------
> #! /bin/bash
> while(true) do
>   ip -batch /etc/inet_route_add.bat; 
>   ip route list | wc -l;  ( 279 k routes )
>   ifconfig eth1 down 
>   ifconfig eth1 10.10.11.1 netmask 255.255.255.0
>   ip route list | wc -l;  ( 3 routes )
> done;
> 
> /proc/net/softnet_stat
> 
> 0000d503 00000000 00000014 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4cc1ecfb 00000000 02bb1bcb 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4cb95da1 00000000 02cc6574 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4cb17932 00000000 02e1abdf 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4cc40ad9 00000000 02f53db0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4cbfe34f 00000000 0306a88d 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4ccb10e9 00000000 03d3a11d 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4ca84c29 00000000 03be0ca1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 4cb710f8 00000000 04070289 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 0b505d55 00000000 038a9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 0b54a7be 00000000 03a5de6d 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 0b5be81f 00000000 03be018c 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 0b51fdd0 00000000 0559fdd6 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 0b4fa6fd 00000000 056311dc 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 0b4a61d3 00000000 056a9276 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 0b454970 00000000 0572add1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 
> FYI. CPU0 is resvered for BGP/ssh/stats etc

^ permalink raw reply

* Re: hackbench regression due to commit 9dfc6e68bfe6e
From: Eric Dumazet @ 2010-04-07  6:39 UTC (permalink / raw)
  To: Zhang, Yanmin
  Cc: Christoph Lameter, netdev, Tejun Heo, Pekka Enberg, alex.shi,
	linux-kernel@vger.kernel.org, Ma, Ling, Chen, Tim C,
	Andrew Morton
In-Reply-To: <1270607668.2078.259.camel@ymzhang.sh.intel.com>

Le mercredi 07 avril 2010 à 10:34 +0800, Zhang, Yanmin a écrit :

> I collected retired instruction, dtlb miss and LLC miss.
> Below is data of LLC miss.
> 
> Kernel 2.6.33:
> # Samples: 11639436896 LLC-load-misses
> #
> # Overhead          Command                                           Shared Object  Symbol
> # ........  ...............  ......................................................  ......
> #
>     20.94%        hackbench  [kernel.kallsyms]                                       [k] copy_user_generic_string
>     14.56%        hackbench  [kernel.kallsyms]                                       [k] unix_stream_recvmsg
>     12.88%        hackbench  [kernel.kallsyms]                                       [k] kfree
>      7.37%        hackbench  [kernel.kallsyms]                                       [k] kmem_cache_free
>      7.18%        hackbench  [kernel.kallsyms]                                       [k] kmem_cache_alloc_node
>      6.78%        hackbench  [kernel.kallsyms]                                       [k] kfree_skb
>      6.27%        hackbench  [kernel.kallsyms]                                       [k] __kmalloc_node_track_caller
>      2.73%        hackbench  [kernel.kallsyms]                                       [k] __slab_free
>      2.21%        hackbench  [kernel.kallsyms]                                       [k] get_partial_node
>      2.01%        hackbench  [kernel.kallsyms]                                       [k] _raw_spin_lock
>      1.59%        hackbench  [kernel.kallsyms]                                       [k] schedule
>      1.27%        hackbench  hackbench                                               [.] receiver
>      0.99%        hackbench  libpthread-2.9.so                                       [.] __read
>      0.87%        hackbench  [kernel.kallsyms]                                       [k] unix_stream_sendmsg
> 
> 
> 
> 
> Kernel 2.6.34-rc3:
> # Samples: 13079611308 LLC-load-misses
> #
> # Overhead          Command                                                         Shared Object  Symbol
> # ........  ...............  ....................................................................  ......
> #
>     18.55%        hackbench  [kernel.kallsyms]                                                     [k] copy_user_generic_str
> ing
>     13.19%        hackbench  [kernel.kallsyms]                                                     [k] unix_stream_recvmsg
>     11.62%        hackbench  [kernel.kallsyms]                                                     [k] kfree
>      8.54%        hackbench  [kernel.kallsyms]                                                     [k] kmem_cache_free
>      7.88%        hackbench  [kernel.kallsyms]                                                     [k] __kmalloc_node_track_
> caller
>      6.54%        hackbench  [kernel.kallsyms]                                                     [k] kmem_cache_alloc_node
>      5.94%        hackbench  [kernel.kallsyms]                                                     [k] kfree_skb
>      3.48%        hackbench  [kernel.kallsyms]                                                     [k] __slab_free
>      2.15%        hackbench  [kernel.kallsyms]                                                     [k] _raw_spin_lock
>      1.83%        hackbench  [kernel.kallsyms]                                                     [k] schedule
>      1.82%        hackbench  [kernel.kallsyms]                                                     [k] get_partial_node
>      1.59%        hackbench  hackbench                                                             [.] receiver
>      1.37%        hackbench  libpthread-2.9.so                                                     [.] __read
> 
> 

Please check values of /proc/sys/net/core/rmem_default
and /proc/sys/net/core/wmem_default on your machines.

Their values can also change hackbench results, because increasing
wmem_default allows af_unix senders to consume much more skbs and stress
slab allocators (__slab_free), way beyond slub_min_order can tune them.

When 2000 senders are running (and 2000 receivers), we might consume
something like 2000 * 100.000 bytes of kernel memory for skbs. TLB
trashing is expected, because all these skbs can span many 2MB pages.
Maybe some node imbalance happens too.



You could try to boot your machine with less ram per node and check :

# cat /proc/buddyinfo 
Node 0, zone      DMA      2      1      2      2      1      1      1      0      1      1      3 
Node 0, zone    DMA32    219    298    143    584    145     57     44     41     31     26    517 
Node 1, zone    DMA32      4      1     17      1      0      3      2      2      2      2    123 
Node 1, zone   Normal    126    169     83      8      7      5     59     59     49     28    459 


One experiment on your Nehalem machine would be to change hackbench so
that each group (20 senders/ 20 receivers) run on a particular NUMA
node.

x86info -c ->

CPU #1
EFamily: 0 EModel: 1 Family: 6 Model: 26 Stepping: 5
CPU Model: Core i7 (Nehalem)
Processor name string: Intel(R) Xeon(R) CPU           X5570  @ 2.93GHz
Type: 0 (Original OEM)	Brand: 0 (Unsupported)
Number of cores per physical package=8
Number of logical processors per socket=16
Number of logical processors per core=2
APIC ID: 0x10	Package: 0  Core: 1   SMT ID 0
Cache info
 L1 Instruction cache: 32KB, 4-way associative. 64 byte line size.
 L1 Data cache: 32KB, 8-way associative. 64 byte line size.
 L2 (MLC): 256KB, 8-way associative. 64 byte line size.
TLB info
 Data TLB: 4KB pages, 4-way associative, 64 entries
 64 byte prefetching.
Found unknown cache descriptors: 55 5a b2 ca e4 



^ permalink raw reply

* Re: RCU problems in fib_table_insert
From: Robert Olsson @ 2010-04-07  6:10 UTC (permalink / raw)
  To: paulmck; +Cc: Robert Olsson, Andi Kleen, robert.olsson, netdev, Jens.Laas
In-Reply-To: <20100322065133.GG2517@linux.vnet.ibm.com>


Paul E. McKenney writes:
 > On Mon, Mar 22, 2010 at 07:18:34AM +0100, Robert Olsson wrote:
 > > 
 > > Seems like Paul and Eric fixed this problem... We use fib_trie with 
 > > major infrastructure but always disable preempt. It was unsafe w.
 > > preempt at least before Jareks P. patches about a year ago. I havn't
 > > tested w. preempt after that but maybe someone else have...


 > Though I must admit that I would be surprised if there wasn't
 > more adjustment required in net/ipv4/fib_trie.c -- lots of
 > rcu_dereference()s in there.

 Hi, a follow on this thread. 

 Maybe I was to pessimistic... we've setup  for stress test running during 
 easter vacation

 Testing the fib_trie with preempt enabled. Continuesly loading/flushing  
 "full BGP" via a test script, while routing without the route cache 
 to further stress locking. Average load about 300 kpps. Some more test 
 details below.

 The test was manually stopped after 6 days. So it seems like preempt/rcu 
 has been improved with fib_trie.
 
 Thanks
					--ro

HW
--
CPU  Opteron 2 * 6174, TYAN S8230. Intel 82599

Kernel from net-next-2.6
------------------------
Version 2.6.34-rc1bifrost-x86_64 (gcc version 4.3.2 (GCC) ) #4 SMP PREEMPT
CONFIG_PREEMPT=y
CONFIG_DEBUG_PREEMPT=y
CONFIG_IP_FIB_TRIE=y
CONFIG_FIB_RULES=y
CONFIG_TREE_RCU=y
CONFIG_RCU_FANOUT=64

IP table
--------
"BGP" 279 k routes

Test duration
-------------
09:34:14 up 6 days, 20:57,  4 users,  load average: 5.28, 5.87, 5.53

Test script
-----------
#! /bin/bash
while(true) do
  ip -batch /etc/inet_route_add.bat; 
  ip route list | wc -l;  ( 279 k routes )
  ifconfig eth1 down 
  ifconfig eth1 10.10.11.1 netmask 255.255.255.0
  ip route list | wc -l;  ( 3 routes )
done;

/proc/net/softnet_stat

0000d503 00000000 00000014 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4cc1ecfb 00000000 02bb1bcb 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4cb95da1 00000000 02cc6574 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4cb17932 00000000 02e1abdf 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4cc40ad9 00000000 02f53db0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4cbfe34f 00000000 0306a88d 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4ccb10e9 00000000 03d3a11d 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4ca84c29 00000000 03be0ca1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4cb710f8 00000000 04070289 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0b505d55 00000000 038a9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0b54a7be 00000000 03a5de6d 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0b5be81f 00000000 03be018c 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0b51fdd0 00000000 0559fdd6 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0b4fa6fd 00000000 056311dc 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0b4a61d3 00000000 056a9276 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0b454970 00000000 0572add1 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

FYI. CPU0 is resvered for BGP/ssh/stats etc

^ permalink raw reply

* RE: [PATCH 1/1] NET: usb: Adding URB_ZERO_PACKET flag to usbnet.c
From: Maulik @ 2010-04-07  5:46 UTC (permalink / raw)
  To: 'Elina Pasheva', dbrownell; +Cc: rfiler, netdev, linux-usb
In-Reply-To: <1270599787.8900.8.camel@Linuxdev4-laptop>



> -----Original Message-----
> From: linux-usb-owner@vger.kernel.org [mailto:linux-usb-
> owner@vger.kernel.org] On Behalf Of Elina Pasheva
> Sent: Wednesday, April 07, 2010 5:53 AM
> To: dbrownell@users.sourceforge.net
> Cc: epasheva@sierrawireless.com; rfiler@sierrawireless.com;
> netdev@vger.kernel.org; linux-usb@vger.kernel.org
> Subject: [PATCH 1/1] NET: usb: Adding URB_ZERO_PACKET flag to usbnet.c
> 
> Subject: [PATCH 1/1] NET: usb: Adding URB_ZERO_PACKET flag to usbnet.c
> From: Elina Pasheva <epasheva@sierrawireless.com>
> This patch adds setting of the urb transfer flag URB_ZERO_PACKET  before
> submitting an urb for drivers that have requested it (by advertising flag
> FLAG_SEND_ZLP).
> The modification is in usbnet.c function usbnet_start_xmit().
> This patch only adds the zero length flag.
> A subsequent patch will address the buggy code we found when devices do
> not
> advertise FLAG_SEND_ZLP in which case there is a possibility of
> transferring
> packets with non-deterministic length.
> 
> This patch has been tested on kernel-2.6.34-rc3.
> This patch has been checked against net-2.6 tree.
> Signed-off-by: Elina Pasheva <epasheva@sierrawireless.com>
> Signed-off-by: Rory Filer <rfiler@sierrawireless.com>
> ---
> 
>  drivers/net/usb/usbnet.c |   15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> --- a/drivers/net/usb/usbnet.c	2010-04-06 10:52:54.000000000 -0700
> +++ b/drivers/net/usb/usbnet.c	2010-04-06 16:54:44.000000000 -0700
> @@ -1068,12 +1068,15 @@ netdev_tx_t usbnet_start_xmit (struct sk
>  	 * NOTE:  strictly conforming cdc-ether devices should expect
>  	 * the ZLP here, but ignore the one-byte packet.
>  	 */
> -	if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) ==
> 0) {
> -		urb->transfer_buffer_length++;
> -		if (skb_tailroom(skb)) {
> -			skb->data[skb->len] = 0;
> -			__skb_put(skb, 1);
> -		}
> +	if (length % dev->maxpacket == 0) {
> +		if (!(info->flags & FLAG_SEND_ZLP)) {
> +			urb->transfer_buffer_length++;
> +			if (skb_tailroom(skb)) {
> +				skb->data[skb->len] = 0;
> +				__skb_put(skb, 1);
> +			}
> +		} else
> +			urb->transfer_flags |= URB_ZERO_PACKET;

You should place braces for the else case as well. See
Documentation/CodingStyle.

It states to use braces in both the branches since the if() case 
contains multiple statements. 

Maulik


^ permalink raw reply

* Re: linux-next: manual merge of the net tree with Linus' tree
From: Stephen Rothwell @ 2010-04-07  5:28 UTC (permalink / raw)
  To: Cong Wang; +Cc: David Miller, netdev, linux-next, linux-kernel, Jiri Pirko
In-Reply-To: <4BBBF9E9.4080504@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 288 bytes --]

Hi,

On Wed, 07 Apr 2010 11:20:09 +0800 Cong Wang <amwang@redhat.com> wrote:
>
> If I read the combined diff correctly, it looks fine for me.

Thanks for the confirmation.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: linux-next: build failure after merge of the net tree
From: Stephen Rothwell @ 2010-04-07  5:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-next, linux-kernel, dm, jpirko
In-Reply-To: <20100406.201220.195404728.davem@davemloft.net>

[-- Attachment #1: Type: text/plain, Size: 319 bytes --]

Hi Dave,

On Tue, 06 Apr 2010 20:12:20 -0700 (PDT) David Miller <davem@davemloft.net> wrote:
>
> Thanks, I'll merge net-2.6 into net-next-2.6 and fix this build
> failure in the latter.

Thanks for that.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [v2 Patch 3/3] bonding: make bonding support netpoll
From: Cong Wang @ 2010-04-07  4:20 UTC (permalink / raw)
  To: Andy Gospodarek
  Cc: linux-kernel@vger.kernel.org, Matt Mackall,
	netdev@vger.kernel.org, bridge@lists.linux-foundation.org,
	Andy Gospodarek, Neil Horman, Jeff Moyer, Stephen Hemminger,
	bonding-devel@lists.sourceforge.net, Jay Vosburgh, David Miller
In-Reply-To: <70501020920527933@unknownmsgid>

Andy Gospodarek wrote:
> On Apr 6, 2010, at 10:32 PM, Cong Wang <amwang@redhat.com> wrote:
> 
>> Andy Gospodarek wrote:
>>> On Tue, Apr 06, 2010 at 12:38:16PM +0800, Cong Wang wrote:
>>>> Cong Wang wrote:
>>>>> Before I try to reproduce it, could you please try to replace
>>>>> the  'read_lock()'
>>>>> in slaves_support_netpoll() with 'read_lock_bh()'? (read_unlock()
>>>>> too)  Try if this helps.
>>>>>
>>>> Confirmed. Please use the attached patch instead, for your testing.
>>>>
>>>> Thanks!
>>>>
>>> Moving those locks to bh-locks will not resolve this.  I tried that
>>> yesterday and tried your new patch today without success.  That
>>> warning
>>> is a WARN_ON_ONCE so you need to reboot to see that it is still a
>>> problem.  Simply unloading and loading the new module is not an
>>> accurate
>>> test.
>>> Also, my system still hangs when removing the bonding module.  I do
>>> not
>>> think you intended to fix this with the patch, but wanted it to be
>>> clear
>>> to everyone on the list.
>>
>> Actually I did reboot and then tested the module. I didn't get any
>> warning.
>> I just tried again today, and no warnings at all.
>>
>> For removing bonding module, you may need another fix of mine,
>> which is to fix a potential deadlock of workqueue. Try:
>>
>> http://lkml.org/lkml/2010/4/1/58
>>
>>> You should also configure your kernel with a some of the lock
>>> debugging
>>> enabled.  I've been using the following:
>>> CONFIG_DETECT_HUNG_TASK=y
>>> CONFIG_DEBUG_SPINLOCK=y
>>> CONFIG_DEBUG_MUTEXES=y
>>> CONFIG_DEBUG_LOCK_ALLOC=y
>>> CONFIG_PROVE_LOCKING=y
>>> CONFIG_LOCKDEP=y
>>> CONFIG_LOCK_STAT=y
>>> CONFIG_DEBUG_LOCKDEP=y
>>
>> Sure, I always keep these.
>>
>>> Here is the output when I remove a slave from the bond.  My
>>> xmit_roundrobin patch from earlier (replacing read_lock with
>>> read_trylock) was applied.  It might be helpful for you when
>>> debugging
>>> these issues.
>>
>> I don't apply your patch, just tested my patch.
>>
>>> Dead loop on virtual device bond0, fix it urgently!
>> Please provide your bonding configuration and steps to reproduce it.
>>
> 
> My first response in this thread provides the commands and
> configuration needed to reproduce this.


Then I should do the right thing.

> 
>> What I did is:
>>
>> 1. Load bonding module with "mode=0 miimon=100"
>> 2. Enslave eth0 and active bond0
>> 3. Load netconsole and send messages via bond0
>> 4. Remove eth0 from bond0
>> 5. Remove bonding module
>> 6. Remove netconsole module
> 
> Thanks for sending your configuration.
> 
> What values are in /proc/sys/kernel/printk?
> 

I use default values on RHEL5:

6 4 1 7

I don't think this is related with loglevel, what I checked
is dmesg, not just the console screen.

Thanks.

^ permalink raw reply

* linux-next: manual merge of the pcmcia tree with the net tree
From: Stephen Rothwell @ 2010-04-07  4:17 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: linux-next, linux-kernel, Alexander Kurz, David Miller, netdev

Hi Dominik,

Today's linux-next merge of the pcmcia tree got a conflict in
drivers/net/pcmcia/3c589_cs.c between commit
f64e96973a1fa885ce6e4f7e3fdbae83de98fcab ("net/pcmcia/3c589_cs: using
netdev_info and friends where appropriate") from the net tree and commits
cbd8ca0260b78f3b4157dc8ff23edbd211c4eef5 ("pcmcia: re-work
pcmcia_request_irq()") and cc25a704447fad12205ca8c7c42d6bba1c1590b0
("pcmcia: dev_node removal (drivers with unregister_netdev check)") from
the pcmcia tree.

Most of these conflicts are just due to unrelated white space changes in
the net tree commit.  I fixed it up (see below) and can carry the fix as
necessary.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc drivers/net/pcmcia/3c589_cs.c
index 580977f,5ab589d..0000000
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@@ -129,13 -106,12 +129,12 @@@ enum RxFilter 
  
  struct el3_private {
  	struct pcmcia_device	*p_dev;
- 	dev_node_t		node;
 -    /* For transceiver monitoring */
 -    struct timer_list	media;
 -    u16			media_status;
 -    u16			fast_poll;
 -    unsigned long	last_irq;
 -    spinlock_t		lock;
 +	/* For transceiver monitoring */
 +	struct timer_list	media;
 +	u16			media_status;
 +	u16			fast_poll;
 +	unsigned long		last_irq;
 +	spinlock_t		lock;
  };
  
  static const char *if_names[] = { "auto", "10baseT", "10base2", "AUI" };
@@@ -301,8 -274,8 +297,8 @@@ static int tc589_config(struct pcmcia_d
      ret = pcmcia_request_configuration(link, &link->conf);
      if (ret)
  	    goto failed;
 -	
 +
-     dev->irq = link->irq.AssignedIRQ;
+     dev->irq = link->irq;
      dev->base_addr = link->io.BasePort1;
      ioaddr = dev->base_addr;
      EL3WINDOW(0);
@@@ -335,8 -308,7 +331,7 @@@
  	dev->if_port = if_port;
      else
  	printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
 -    
 +
-     link->dev_node = &lp->node;
      SET_NETDEV_DEV(dev, &link->dev);
  
      if (register_netdev(dev) != 0) {
@@@ -344,15 -316,13 +339,12 @@@
  	goto failed;
      }
  
-     strcpy(lp->node.dev_name, dev->name);
- 
 -    printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, "
 -	   "hw_addr %pM\n",
 -	   dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq,
 -	   dev->dev_addr);
 -    printk(KERN_INFO "  %dK FIFO split %s Rx:Tx, %s xcvr\n",
 -	   (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3],
 -	   if_names[dev->if_port]);
 +    netdev_info(dev, "3Com 3c%s, io %#3lx, irq %d, hw_addr %pM\n",
 +		(multi ? "562" : "589"), dev->base_addr, dev->irq,
 +		dev->dev_addr);
 +    netdev_info(dev, "  %dK FIFO split %s Rx:Tx, %s xcvr\n",
 +		(fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3],
 +		if_names[dev->if_port]);
      return 0;
  
  failed:

^ permalink raw reply

* Re: [v2 Patch 3/3] bonding: make bonding support netpoll
From: Andy Gospodarek @ 2010-04-07  4:02 UTC (permalink / raw)
  To: Cong Wang
  Cc: Jay Vosburgh, Neil Horman, netdev@vger.kernel.org, Matt Mackall,
	bridge@lists.linux-foundation.org, linux-kernel@vger.kernel.org,
	David Miller, Jeff Moyer, Andy Gospodarek,
	bonding-devel@lists.sourceforge.net
In-Reply-To: <4BBBEEAA.1050100@redhat.com>

On Apr 6, 2010, at 10:32 PM, Cong Wang <amwang@redhat.com> wrote:

> Andy Gospodarek wrote:
>> On Tue, Apr 06, 2010 at 12:38:16PM +0800, Cong Wang wrote:
>>> Cong Wang wrote:
>>>> Before I try to reproduce it, could you please try to replace
>>>> the  'read_lock()'
>>>> in slaves_support_netpoll() with 'read_lock_bh()'? (read_unlock()
>>>> too)  Try if this helps.
>>>>
>>> Confirmed. Please use the attached patch instead, for your testing.
>>>
>>> Thanks!
>>>
>> Moving those locks to bh-locks will not resolve this.  I tried that
>> yesterday and tried your new patch today without success.  That
>> warning
>> is a WARN_ON_ONCE so you need to reboot to see that it is still a
>> problem.  Simply unloading and loading the new module is not an
>> accurate
>> test.
>> Also, my system still hangs when removing the bonding module.  I do
>> not
>> think you intended to fix this with the patch, but wanted it to be
>> clear
>> to everyone on the list.
>
>
> Actually I did reboot and then tested the module. I didn't get any
> warning.
> I just tried again today, and no warnings at all.
>
> For removing bonding module, you may need another fix of mine,
> which is to fix a potential deadlock of workqueue. Try:
>
> http://lkml.org/lkml/2010/4/1/58
>
>> You should also configure your kernel with a some of the lock
>> debugging
>> enabled.  I've been using the following:
>> CONFIG_DETECT_HUNG_TASK=y
>> CONFIG_DEBUG_SPINLOCK=y
>> CONFIG_DEBUG_MUTEXES=y
>> CONFIG_DEBUG_LOCK_ALLOC=y
>> CONFIG_PROVE_LOCKING=y
>> CONFIG_LOCKDEP=y
>> CONFIG_LOCK_STAT=y
>> CONFIG_DEBUG_LOCKDEP=y
>
>
> Sure, I always keep these.
>
>> Here is the output when I remove a slave from the bond.  My
>> xmit_roundrobin patch from earlier (replacing read_lock with
>> read_trylock) was applied.  It might be helpful for you when
>> debugging
>> these issues.
>
>
> I don't apply your patch, just tested my patch.
>
>> Dead loop on virtual device bond0, fix it urgently!
>
> Please provide your bonding configuration and steps to reproduce it.
>

My first response in this thread provides the commands and
configuration needed to reproduce this.

> What I did is:
>
> 1. Load bonding module with "mode=0 miimon=100"
> 2. Enslave eth0 and active bond0
> 3. Load netconsole and send messages via bond0
> 4. Remove eth0 from bond0
> 5. Remove bonding module
> 6. Remove netconsole module

Thanks for sending your configuration.

What values are in /proc/sys/kernel/printk?

> And no deadlocks, no warnings.
>
> Thanks.

^ permalink raw reply

* linux-next: manual merge of the rr tree with the net tree
From: Stephen Rothwell @ 2010-04-07  3:51 UTC (permalink / raw)
  To: Rusty Russell
  Cc: linux-next, linux-kernel, David Woodhouse, Ben Hutchings,
	David Miller, netdev, Ondrej Zary

Hi Rusty,

Today's linux-next merge of the rr tree got a conflict in
include/linux/mod_devicetable.h scripts/mod/file2alias.c between commit
8626d3b4328061f5b82b11ae1d6918a0c3602f42 ("phylib: Support phy module
autoloading") from the net tree and commits
df73f69d6a29eb5a22327009627f23c7ae4be007
("modules:isapnp-mod_devicetable.h") and a8e67afa03daca8b570115ba9b33f508cc5a9133 ("MODULE_DEVICE_TABLE(isapnp, ...) does nothing") from the rr tree.

Just overlapping additions.  I fixed it up (see below) and can carry the
fix as necessary.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc include/linux/mod_devicetable.h
index 55f1f9c,e69d69f..0000000
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@@ -474,30 -474,11 +474,37 @@@ struct platform_device_id 
  			__attribute__((aligned(sizeof(kernel_ulong_t))));
  };
  
 +#define MDIO_MODULE_PREFIX	"mdio:"
 +
 +#define MDIO_ID_FMT "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d"
 +#define MDIO_ID_ARGS(_id) \
 +	(_id)>>31, ((_id)>>30) & 1, ((_id)>>29) & 1, ((_id)>>28) & 1,	\
 +	((_id)>>27) & 1, ((_id)>>26) & 1, ((_id)>>25) & 1, ((_id)>>24) & 1, \
 +	((_id)>>23) & 1, ((_id)>>22) & 1, ((_id)>>21) & 1, ((_id)>>20) & 1, \
 +	((_id)>>19) & 1, ((_id)>>18) & 1, ((_id)>>17) & 1, ((_id)>>16) & 1, \
 +	((_id)>>15) & 1, ((_id)>>14) & 1, ((_id)>>13) & 1, ((_id)>>12) & 1, \
 +	((_id)>>11) & 1, ((_id)>>10) & 1, ((_id)>>9) & 1, ((_id)>>8) & 1, \
 +	((_id)>>7) & 1, ((_id)>>6) & 1, ((_id)>>5) & 1, ((_id)>>4) & 1, \
 +	((_id)>>3) & 1, ((_id)>>2) & 1, ((_id)>>1) & 1, (_id) & 1
 +
 +/**
 + * struct mdio_device_id - identifies PHY devices on an MDIO/MII bus
 + * @phy_id: The result of
 + *     (mdio_read(&MII_PHYSID1) << 16 | mdio_read(&PHYSID2)) & @phy_id_mask
 + *     for this PHY type
 + * @phy_id_mask: Defines the significant bits of @phy_id.  A value of 0
 + *     is used to terminate an array of struct mdio_device_id.
 + */
 +struct mdio_device_id {
 +	__u32 phy_id;
 +	__u32 phy_id_mask;
 +};
 +
+ #define ISAPNP_ANY_ID		0xffff
+ struct isapnp_device_id {
+ 	unsigned short card_vendor, card_device;
+ 	unsigned short vendor, function;
+ 	kernel_ulong_t driver_data;	/* data private to the driver */
+ };
+ 
  #endif /* LINUX_MOD_DEVICETABLE_H */
diff --cc scripts/mod/file2alias.c
index 36a60a8,6494f5b..0000000
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@@ -796,28 -796,19 +796,41 @@@ static int do_platform_entry(const cha
  	return 1;
  }
  
 +static int do_mdio_entry(const char *filename,
 +			 struct mdio_device_id *id, char *alias)
 +{
 +	int i;
 +
 +	alias += sprintf(alias, MDIO_MODULE_PREFIX);
 +
 +	for (i = 0; i < 32; i++) {
 +		if (!((id->phy_id_mask >> (31-i)) & 1))
 +			*(alias++) = '?';
 +		else if ((id->phy_id >> (31-i)) & 1)
 +			*(alias++) = '1';
 +		else
 +			*(alias++) = '0';
 +	}
 +
 +	/* Terminate the string */
 +	*alias = 0;
 +
 +	return 1;
 +}
 +
+ /* looks like: "pnp:dD" */
+ static int do_isapnp_entry(const char *filename,
+ 			   struct isapnp_device_id *id, char *alias)
+ {
+ 	sprintf(alias, "pnp:d%c%c%c%x%x%x%x*",
+ 		'A' + ((id->vendor >> 2) & 0x3f) - 1,
+ 		'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1,
+ 		'A' + ((id->vendor >> 8) & 0x1f) - 1,
+ 		(id->function >> 4) & 0x0f, id->function & 0x0f,
+ 		(id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
+ 	return 1;
+ }
+ 
  /* Ignore any prefix, eg. some architectures prepend _ */
  static inline int sym_is(const char *symbol, const char *name)
  {
@@@ -965,10 -956,10 +978,14 @@@ void handle_moddevtable(struct module *
  		do_table(symval, sym->st_size,
  			 sizeof(struct platform_device_id), "platform",
  			 do_platform_entry, mod);
 +	else if (sym_is(symname, "__mod_mdio_device_table"))
 +		do_table(symval, sym->st_size,
 +			 sizeof(struct mdio_device_id), "mdio",
 +			 do_mdio_entry, mod);
+ 	else if (sym_is(symname, "__mod_isapnp_device_table"))
+ 		do_table(symval, sym->st_size,
+ 			sizeof(struct isapnp_device_id), "isa",
+ 			do_isapnp_entry, mod);
  	free(zeros);
  }
  

^ permalink raw reply

* Re: linux-next: manual merge of the net tree with Linus' tree
From: Cong Wang @ 2010-04-07  3:20 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: David Miller, netdev, linux-next, linux-kernel, Jiri Pirko
In-Reply-To: <20100407125836.3c7f1095.sfr@canb.auug.org.au>

Stephen Rothwell wrote:
> Hi all,
> 
> Today's linux-next merge of the net tree got a conflict in
> drivers/net/bonding/bond_main.c between commit
> 9e2e61fbf8ad016d24e4af0afff13505f3dd2a2a ("bonding: fix potential
> deadlock in bond_uninit()") from Linus' tree and commit
> 22bedad3ce112d5ca1eaf043d4990fa2ed698c87 ("net: convert multicast list to
> list_head") from the net tree.
> 
> Just context changes.  If fixed it up (see below) and can carry the fix
> for a while.

Hi, Stephen,

If I read the combined diff correctly, it looks fine for me.

Thanks for letting me know!

^ permalink raw reply

* Re: linux-next: build failure after merge of the net tree
From: David Miller @ 2010-04-07  3:12 UTC (permalink / raw)
  To: sfr; +Cc: netdev, linux-next, linux-kernel, dm, jpirko
In-Reply-To: <20100407125817.e8e1d174.sfr@canb.auug.org.au>

From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Wed, 7 Apr 2010 12:58:17 +1000

> After merging the wireless tree, today's linux-next build (x86_64 allmodconfig)
> failed like this:
> 
> drivers/net/cxgb4/cxgb4_main.c: In function 'set_addr_filters':
> drivers/net/cxgb4/cxgb4_main.c:264: error: dereferencing pointer to incomplete type
> drivers/net/cxgb4/cxgb4_main.c:265: error: dereferencing pointer to incomplete type
> 
> Caused by commit b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15 ("cxgb4: Add
> main driver file and driver Makefile") from Linus' tree interacting with
> commit 22bedad3ce112d5ca1eaf043d4990fa2ed698c87 ("net: convert multicast
> list to list_head").  The latter removed struct dev_addr_list.
> 
> I have reverted commit b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15 (and
> 43e9da8d782b8a40d5127fcc59ac2e543cf16d7d ("net: Hook up cxgb4 to Kconfig
> and Makefile") that depended on it) for today.

Thanks, I'll merge net-2.6 into net-next-2.6 and fix this build
failure in the latter.

^ permalink raw reply

* linux-next: manual merge of the net tree with Linus' tree
From: Stephen Rothwell @ 2010-04-07  2:58 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: linux-next, linux-kernel, Francois Romieu

Hi all,

Today's linux-next merge of the net tree got a conflict in
drivers/net/via-velocity.c between commit
bcbe53682f65330bdd9ad7eed9575d2ff536353a ("via-velocity: Fix
FLOW_CNTL_TX_RX handling in set_mii_flow_control()") from Linus' tree and
commit 3a7f8681ffb27bcc540fb74cda15e39c9395737b ("via-velocity: remove
private #define") from the net tree.

I fixed it up (see below) and can carry the fix for a while.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc drivers/net/via-velocity.c
index bc278d4,078903f..0000000
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@@ -811,8 -811,8 +811,8 @@@ static void set_mii_flow_control(struc
  		break;
  
  	case FLOW_CNTL_TX_RX:
- 		MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
- 		MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+ 		MII_REG_BITS_ON(ADVERTISE_PAUSE_CAP, MII_ADVERTISE, vptr->mac_regs);
 -		MII_REG_BITS_ON(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs);
++		MII_REG_BITS_OFF(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs);
  		break;
  
  	case FLOW_CNTL_DISABLE:

^ permalink raw reply

* linux-next: manual merge of the net tree with Linus' tree
From: Stephen Rothwell @ 2010-04-07  2:58 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: linux-next, linux-kernel, Amerigo Wang, Jiri Pirko

Hi all,

Today's linux-next merge of the net tree got a conflict in
drivers/net/bonding/bond_main.c between commit
9e2e61fbf8ad016d24e4af0afff13505f3dd2a2a ("bonding: fix potential
deadlock in bond_uninit()") from Linus' tree and commit
22bedad3ce112d5ca1eaf043d4990fa2ed698c87 ("net: convert multicast list to
list_head") from the net tree.

Just context changes.  If fixed it up (see below) and can carry the fix
for a while.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc drivers/net/bonding/bond_main.c
index 0075514,22682f1..0000000
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@@ -4550,9 -4476,10 +4508,7 @@@ static void bond_uninit(struct net_devi
  
  	bond_remove_proc_entry(bond);
  
- 	netif_addr_lock_bh(bond_dev);
- 	bond_mc_list_destroy(bond);
- 	netif_addr_unlock_bh(bond_dev);
 -	if (bond->wq)
 -		destroy_workqueue(bond->wq);
 -
+ 	__hw_addr_flush(&bond->mc_list);
  }
  
  /*------------------------- Module initialization ---------------------------*/

^ permalink raw reply

* linux-next: build failure after merge of the net tree
From: Stephen Rothwell @ 2010-04-07  2:58 UTC (permalink / raw)
  To: David Miller, netdev
  Cc: linux-next, linux-kernel, Dimitris Michailidis, Jiri Pirko

[-- Attachment #1: Type: text/plain, Size: 938 bytes --]

Hi Dave,

After merging the wireless tree, today's linux-next build (x86_64 allmodconfig)
failed like this:

drivers/net/cxgb4/cxgb4_main.c: In function 'set_addr_filters':
drivers/net/cxgb4/cxgb4_main.c:264: error: dereferencing pointer to incomplete type
drivers/net/cxgb4/cxgb4_main.c:265: error: dereferencing pointer to incomplete type

Caused by commit b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15 ("cxgb4: Add
main driver file and driver Makefile") from Linus' tree interacting with
commit 22bedad3ce112d5ca1eaf043d4990fa2ed698c87 ("net: convert multicast
list to list_head").  The latter removed struct dev_addr_list.

I have reverted commit b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15 (and
43e9da8d782b8a40d5127fcc59ac2e543cf16d7d ("net: Hook up cxgb4 to Kconfig
and Makefile") that depended on it) for today.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox