Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v3 3/6] vbus: add a "vbus-proxy" bus model for vbus_driver objects
From: Gregory Haskins @ 2009-08-17 13:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Gregory Haskins, kvm, Avi Kivity, alacrityvm-devel, linux-kernel,
	netdev
In-Reply-To: <20090815103243.GA26749@elte.hu>

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

Ingo Molnar wrote:
> * Gregory Haskins <ghaskins@novell.com> wrote:
> 
>> This will generally be used for hypervisors to publish any host-side
>> virtual devices up to a guest.  The guest will have the opportunity
>> to consume any devices present on the vbus-proxy as if they were
>> platform devices, similar to existing buses like PCI.
>>
>> Signed-off-by: Gregory Haskins <ghaskins@novell.com>
>> ---
>>
>>  MAINTAINERS                 |    6 ++
>>  arch/x86/Kconfig            |    2 +
>>  drivers/Makefile            |    1 
>>  drivers/vbus/Kconfig        |   14 ++++
>>  drivers/vbus/Makefile       |    3 +
>>  drivers/vbus/bus-proxy.c    |  152 +++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/vbus_driver.h |   73 +++++++++++++++++++++
>>  7 files changed, 251 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/vbus/Kconfig
>>  create mode 100644 drivers/vbus/Makefile
>>  create mode 100644 drivers/vbus/bus-proxy.c
>>  create mode 100644 include/linux/vbus_driver.h
> 
> Is there a consensus on this with the KVM folks? (i've added the KVM 
> list to the Cc:)
> 
> 

Hi Ingo,

Avi can correct me if I am wrong, but the agreement that he and I came
to a few months ago was something to the effect of:

kvm will be neutral towards various external IO subsystems, and instead
provide various hooks (see irqfd, ioeventfd) to permit these IO
subsystems to interface with kvm.

AlacrityVM is one of the first projects to take advantage of that
interface.  AlacrityVM is kvm-core + vbus-core + vbus-kvm-connector +
vbus-enhanced qemu + guest drivers.  This thread is part of the
guest-drivers portion.  Note that it is specific to alacrityvm, not kvm,
which is why the kvm list was not included in the conversation (also an
agreement with Avi: http://lkml.org/lkml/2009/8/6/231).

Kind Regards,
-Greg


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 267 bytes --]

^ permalink raw reply

* Re: Very strange issues with ethernet wake on lan
From: Rafael J. Wysocki @ 2009-08-17 12:02 UTC (permalink / raw)
  To: Maxim Levitsky
  Cc: netdev@vger.kernel.org, linux-pm@lists.linux-foundation.org
In-Reply-To: <1250500588.4301.5.camel@localhost.localdomain>

On Monday 17 August 2009, Maxim Levitsky wrote:
> On Sun, 2009-08-16 at 06:42 +0300, Maxim Levitsky wrote:
> > Hi,
> > 
> > I have recently put back the davicom dm9009 ethernet card into my
> > computer.
> > 
> > Some long time ago, I have written its suspend/resume routines.
> > Now I see that few things have changed, like I need to enable wake in
> > sysfs or better patch the code to do so, some nice helpers like
> > pci_prepare_to_sleep have arrived, etc.
> > 
> > 
> > I narrowed the strange issue down to following situation:
> > 
> > I reload dmfe.ko (and networkmanager is disabled)
> > I don't ifup the device, thus pretty much no hardware initialization
> > takes place (but this appears not to matter anyway)
> > 
> > I then suspend the system, and WOL doesn't work (I have patched the
> > driver to enable WOL automaticly)
> > 
> > I then, suspend again. WOL works, and continues to work as long as I
> > don't reload the driver. If I do, same situation repeats.
> > 
> > Also, after a boot, WOL works, so a reload cycle triggers that issue.
> > 
> > And most importantly, if I don't do a
> > 
> > pci_set_power_state(pci_dev, pci_choose_state (pci_dev, state));
> > 
> > in .suspend, then WOL always works.
> > 
> > and I have even tried to set state manually to PCI_D3hot or PCI_D3cold, 
> > 
> > I also tried to use pci_save_state
> > 
> > 
> > I also have 2 copies of this card, and both have this issue.
> > I also tried 2 pci slots.
> > 
> > Kernel is vanilla 2.6.31-rc5
> 
> 
> Bisect reveals:
> 
> 44e4e66eeae5338b3ca0b28f8352e60bf18d5ba8 is first bad commit
> commit 44e4e66eeae5338b3ca0b28f8352e60bf18d5ba8
> Author: Rafael J. Wysocki <rjw@sisk.pl>
> Date:   Mon Jul 7 03:32:52 2008 +0200
> 
>     PCI: rework pci_set_power_state function to call platform first
>     
>     Rework pci_set_power_state() so that the platform callback is
>     invoked before the native mechanism, if necessary.  Also, make
>     the function check if the device is power manageable by the
>     platform before invoking the platform callback.
>     
>     This may matter if the device dependent on additional power
>     resources controlled by the platform is being put into D0, in which
>     case those power resources must be turned on before we attempt to
>     handle the device itself.
>     
>     Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
>     Acked-by: Pavel Machek <pavel@suse.cz>
>     Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> 
> 
> Note that probably this device has no acpi entries, because it is an
> addon card, bios knows nothing about it

Well, thanks, but I was going to have a look at this issue anyway. :-)

Best,
Rafael

^ permalink raw reply

* Re: [Bonding-devel] [PATCH net-next-2.6] bonding: introduce primary_lazy option
From: Jiri Pirko @ 2009-08-17 11:49 UTC (permalink / raw)
  To: Nicolas de Pesloüan; +Cc: davem, netdev, fubar, bonding-devel
In-Reply-To: <4A859057.3020606@free.fr>

Fri, Aug 14, 2009 at 06:27:03PM CEST, nicolas.2p.debian@free.fr wrote:
> Jiri Pirko wrote:
>> Thu, Aug 13, 2009 at 09:41:02PM CEST, nicolas.2p.debian@free.fr wrote:
>>> Jiri Pirko wrote:
>>>> In some cases there is not desirable to switch back to primary interface when
>>>> it's link recovers and rather stay wiith currently active one. We need to avoid
>>>> packetloss as much as we can in some cases. This is solved by introducing
>>>> primary_lazy option. Note that enslaved primary slave is set as current
>>>> active no matter what.
>>> May I suggest that instead of creating a new option to better define how
>>> the "primary" option is expected to behave for active-backup mode, we 
>>>  try the "weight" slave  option I proposed in the thread "alternative 
>>> to  primary" earlier this year ?
>>>
>>> http://sourceforge.net/mailarchive/forum.php?thread_name=49D5357E.4020201%40free.fr&forum_name=bonding-devel
>>
>> This link does not work for me :(
>
> Nor for me... Sourceforge apparently decided to drop the bonding-devel  
> list archive just now. 'hope the list archive will be back soon.
>
> Originally, the proposed "weight" option for slaves was designed just to  
> provide a way to better define which slave should become active when the  
> active one just went down. As you know, the current "primary" option  
> does not allow for a predictable selection of the new active slave when  
> the primary loose connectivity. The new active slave is chosen "at  
> random" between the remaining slaves.
>
> After a short thread, involving Jay Vosburg and Andy Gospodarek, we end  
> up with a general configuration interface, that provide a way to tune  
> many things in slave management :
>
> - Active slave selection in active/backup mode, even in the presence of  
> more than two slaves.
> - Active aggregator selection in 802.3ad mode.
> - Load balancing tuning for most load balancing modes.
>
> The sysfs interface would be /sys/class/net/eth0/bonding/weight. Writing  
> a number there would give a "user supplied weight" to a slave. The speed  
> and link state of the slave would give a "natural weight" for the slave.  
> And the "effective weight" would be computed every time one of user  
> supplied or natural weight change (upon speed or link state changes) and  
> would be used everywhere we need a slave weight.
>
> I suggest that :
> - slave's natural weight = speed of the slave if link UP, else 0.
> - slave's effective weight = slave's natural weight * slave's user  
> supplied weight.
> - aggregator's effective weight = sum of the effective weights of the  
> slaves inside the aggregator.
>
> For the active/backup mode, the exact behavior would be :
>
> - When the active slave disappear, the new active slave is the one whose  
> effective weight is the highest.
> - When a slave comes back, it only becomes active if its effective  
> weight is strictly higher than the one of the current active slave.  
> (This stop the flip-flop risk you stated).
> - To keep the old "primary" option, we simply give a very high user  
> supplied weight to the primary slave. Jay suggested :
> #define BOND_PRIMARY_PRIO 0x80000000
> user_supplied_weight &= BOND_PRIMARY_PRIO /* to set the primary */
> user_supplied_weight &= ~BOND_PRIMAY_PRIO  /* to clear the primary */
>
> The same apply to aggregator : Every time a slave enter (link UP) or  
> leave (link DOWN) an aggregator, the aggregator effective weight is  
> recomputed. Then, if an aggregator exist with an strictly higher  
> effective weight than the current active one, the new best aggregator  
> becomes active.
>
> For others modes, the weight might be used later to tune the load  
> balancing logic in some way.
>
> A default value of 1 for slave weight would cause slave speed to be used  
> alone, hence the "natural weight".
>

I read your text and also the original list thread and I must say I see no
solution in this "weight" parameter for this issue. Because it's desired for one
link to stay active even if second come up, these 2 must have the same weight.
But imagine 3 links of the same weight. In that case you cannot insure that the
"primary one" will be chosen as active (see my picture in the reply to Jay's
post). Correct me if I'm wrong but for that what I want to fix by primary_lazy
option, your proposed weight option has no effect.

Therefor I still think the primary_lazy is the only solution now.

Jirka

>>> Giving the same "weight" to two different slaves means "chose at random
>>> on startup and keep the active one until it fails". And if the "at
>>> random" behavior is not appropriate, one can force the active slave
>>> using what Jay suggested  (/sys/class/net/bond0/bonding/active).
>>>
>>> The proposed "weight" slave's option is able to prevent the slaves from
>>> flip-flopping, by stating the fact that two slaves share the same   
>>> "primary" level, and may provide several other enhancements as 
>>> described  in the thread.
>>>
>>
>> Although I cannot reach the thread, this looks interesting. But I'm not sure it
>> has real benefits over primary_lazy option (and it doesn't solve initial curr
>> active slave setup)
>
> You are right, it doesn't solve the initial active slave selection. But  
> why would it be so important to properly select the initial active  
> slave, if you feel comfortable with staying with a new active slave,  
> after a failure and return of the original active slave ? This kind of  
> failures may last for only a few seconds (just unplugging and plugging  
> back the wire), and you configuration may then stay with the new active  
> slave "forever". If "forever" is acceptable, may be "at startup" is  
> acceptable too. :-)
>
> From my point of view (and Andy Gospodarek apparently agreed), the real  
> benefits of the weight slave option is that is it more generic and allow  
> for later usage in other modes, that we don't anticipate for now.
>
> Quoted from a mail from Andy Gospodarek in the original thread :
>
> "I really have no objection to that.  Adding this as a base part of
> bonding for a few modes with known features would be a nice start.
> I'm sure others will be kind enough to send suggestions or patches for
> ways this could benefit other modes."
>
> 	Nicolas.

^ permalink raw reply

* Re: AlacrityVM numbers updated for 31-rc4
From: Michael S. Tsirkin @ 2009-08-17 11:06 UTC (permalink / raw)
  To: Gregory Haskins
  Cc: Anthony Liguori, alacrityvm-devel, alacrityvm-users,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org, netdev
In-Reply-To: <4A85BFF8.4050001@gmail.com>

On Fri, Aug 14, 2009 at 03:50:16PM -0400, Gregory Haskins wrote:
> Gregory Haskins wrote:
> > Anthony Liguori wrote:
> >> Gregory Haskins wrote:
> >>> I re-ran the numbers on 10GE against the actual alacrityvm v0.1 release
> >>> available in git on kernel.org.
> >>>
> >>> I tried to include the newly announced "vhost" driver (Michael Tsirkin)
> >>> for virtio acceleration, but ran into issues getting the patches to
> >>> apply.
> >>>
> >>> For now, this includes native, virtio-u (virtio-userspace), and venet
> >>> all running on 31-rc4.  If I can resolve the issue with Michaels
> >>> patches, I will add "virtio-k" (virtio-kernel) to the mix as well.  For
> >>> now, here are the results for 1500mtu:
> >>>
> >>> native:   7388Mb/s,   29.8us rtt (33505 tps udp-rr)
> >>> venet:    3654Mb/s,   56.8us rtt (17600 tps udp-rr)
> >>> virtio-u: 1955Mb/s, 4016.0us rtt (  249 tps udp-rr)
> >>>   
> 
> I re-ran the numbers now that I have the HRT issue straighted out.
> Native and virtio stayed level, venet recovered from the 3.6Gb/s
> quagmire it was in, back up to ~4.5Gb/s.
> 
> native (hw):        7388Mb/s,  29.8us rtt (33500 tps udp-rr)
> venet (alacrityvm): 4560Mb/s,  56.8us rtt (17600 tps udp-rr)
> virtio-u (kvm):	    2670Mb/s, 265.7us rtt ( 3764 tps udp-rr)
> virtio-k (kvm):     d-n-f
> 
> (still having problems getting vhost to run).  Will try again next week.)
> 
> I have updated the graphs on the wiki:
> 
> http://developer.novell.com/wiki/index.php/AlacrityVM
> 
> Have a nice weekend, all.
> 
> -Greg
> 
> 

Hi Greg,
could you check what does disabling tx timer completely do to virtio-u
performance?  Here's a patch from Mark McLoughlin do this this:
it works and seems to improve latency for me.


From: Mark McLoughlin <markmc@redhat.com>
Subject: virtio_net: remove the tx mitigation timer
    
The tx mitigation timer is designed to reduce the rate of guest exits
thereby improving throughput. However, we have identified a number of
cases where mitigation hurts throughput and benchmarking has shown that
it only helps throughput in a very limited number of cases.

This patch firstly removes the timer and replaces it with a bottom half.
When the host is notified of a packet on the tx queue, it schedules a
bottom half in the I/O thread in order to flush the queue.

Next, it disables enabling notifications until it has flushed the queue.
In order to avoid a race condition with this, it flushes the queue a
second time when notifications are re-enabled.

Finally, if it successfully flushed a number of packets in the bottom
half, it disables notifications re-schedules the bottom half to quickly
flush the queue again.

Migration is handled by equating the tx_timer_active savevm field to
tx_bh_scheduled.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>

---

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 95d9f93..835f4e1 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -37,8 +37,8 @@ typedef struct VirtIONet
     VirtQueue *tx_vq;
     VirtQueue *ctrl_vq;
     VLANClientState *vc;
-    QEMUTimer *tx_timer;
-    int tx_timer_active;
+    QEMUBH *tx_bh;
+    int tx_bh_scheduled;
     struct {
         VirtQueueElement elem;
         ssize_t len;
@@ -591,7 +591,7 @@ static ssize_t virtio_net_receive2(VLANClientState *vc, const uint8_t *buf, size
     return size;
 }
 
-static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq);
+static int virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq, int enable_notify);
 
 static void virtio_net_tx_complete(VLANClientState *vc, ssize_t len)
 {
@@ -603,7 +603,7 @@ static void virtio_net_tx_complete(VLANClientState *vc, ssize_t len)
     n->async_tx.elem.out_num = n->async_tx.len = 0;
 
     virtio_queue_set_notification(n->tx_vq, 1);
-    virtio_net_flush_tx(n, n->tx_vq);
+    virtio_net_flush_tx(n, n->tx_vq, 0);
 }
 
 static ssize_t virtio_net_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
@@ -617,9 +617,10 @@ static ssize_t virtio_net_receive_raw(VLANClientState *vc, const uint8_t *buf, s
 }
 
 /* TX */
-static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
+static int virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq, int enable_notify)
 {
     VirtQueueElement elem;
+    int num_packets = 0;
 #ifdef TAP_VNET_HDR
     int has_vnet_hdr = tap_has_vnet_hdr(n->vc->vlan->first_client);
 #else
@@ -629,11 +630,11 @@ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
 	    return;
 
     if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
-        return;
+        return num_packets;
 
     if (n->async_tx.elem.out_num) {
         virtio_queue_set_notification(n->tx_vq, 0);
-        return;
+        return num_packets;
     }
 
     while (virtqueue_pop(vq, &elem)) {
@@ -670,45 +671,48 @@ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
             virtio_queue_set_notification(n->tx_vq, 0);
             n->async_tx.elem = elem;
             n->async_tx.len  = len;
-            return;
+            return num_packets;
         }
 
         len += ret;
 
         virtqueue_push(vq, &elem, len);
         virtio_notify(&n->vdev, vq);
+
+        num_packets++;
+    }
+
+    if (enable_notify) {
+        virtio_queue_set_notification(vq, 1);
+        num_packets += virtio_net_flush_tx(n, vq, 0);
     }
+
+    return num_packets;
 }
 
 static void virtio_net_handle_tx(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIONet *n = to_virtio_net(vdev);
 
-    if (n->tx_timer_active) {
-        virtio_queue_set_notification(vq, 1);
-        qemu_del_timer(n->tx_timer);
-        n->tx_timer_active = 0;
-        virtio_net_flush_tx(n, vq);
-    } else {
-        qemu_mod_timer(n->tx_timer,
-                       qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL);
-        n->tx_timer_active = 1;
-        virtio_queue_set_notification(vq, 0);
-    }
+    if (n->tx_bh_scheduled)
+        return;
+
+    virtio_queue_set_notification(n->tx_vq, 0);
+    qemu_bh_schedule(n->tx_bh);
+    n->tx_bh_scheduled = 1;
 }
 
-static void virtio_net_tx_timer(void *opaque)
+static void virtio_net_tx_bh(void *opaque)
 {
     VirtIONet *n = opaque;
 
-    n->tx_timer_active = 0;
-
-    /* Just in case the driver is not ready on more */
-    if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
-        return;
+    n->tx_bh_scheduled = 0;
 
-    virtio_queue_set_notification(n->tx_vq, 1);
-    virtio_net_flush_tx(n, n->tx_vq);
+    if (virtio_net_flush_tx(n, n->tx_vq, 1)) {
+        virtio_queue_set_notification(n->tx_vq, 0);
+        qemu_bh_schedule(n->tx_bh);
+        n->tx_bh_scheduled = 1;
+    }
 }
 
 static void virtio_net_save(QEMUFile *f, void *opaque)
@@ -718,7 +722,7 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
     virtio_save(&n->vdev, f);
 
     qemu_put_buffer(f, n->mac, ETH_ALEN);
-    qemu_put_be32(f, n->tx_timer_active);
+    qemu_put_be32(f, n->tx_bh_scheduled);
     qemu_put_be32(f, n->mergeable_rx_bufs);
     qemu_put_be16(f, n->status);
     qemu_put_byte(f, n->promisc);
@@ -752,7 +756,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
     virtio_load(&n->vdev, f);
 
     qemu_get_buffer(f, n->mac, ETH_ALEN);
-    n->tx_timer_active = qemu_get_be32(f);
+    n->tx_bh_scheduled = qemu_get_be32(f);
     n->mergeable_rx_bufs = qemu_get_be32(f);
 
     if (version_id >= 3)
@@ -814,9 +818,8 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
     }
     n->mac_table.first_multi = i;
 
-    if (n->tx_timer_active) {
-        qemu_mod_timer(n->tx_timer,
-                       qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL);
+    if (n->tx_bh_scheduled) {
+        qemu_bh_schedule(n->tx_bh);
     }
 
     return 0;
@@ -833,9 +836,6 @@ static void virtio_net_cleanup(VLANClientState *vc)
     qemu_free(n->mac_table.macs);
     qemu_free(n->vlans);
 
-    qemu_del_timer(n->tx_timer);
-    qemu_free_timer(n->tx_timer);
-
     virtio_cleanup(&n->vdev);
 }
 
@@ -881,8 +881,8 @@ VirtIODevice *virtio_net_init(DeviceState *dev)
 
     qemu_format_nic_info_str(n->vc, n->mac);
 
-    n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n);
-    n->tx_timer_active = 0;
+    n->tx_bh = qemu_bh_new(virtio_net_tx_bh, n);
+    n->tx_bh_scheduled = 0;
     n->mergeable_rx_bufs = 0;
     n->promisc = 1; /* for compatibility */
 
diff --git a/hw/virtio-net.h b/hw/virtio-net.h
index 2085181..add7815 100644
--- a/hw/virtio-net.h
+++ b/hw/virtio-net.h
@@ -47,8 +47,6 @@
 
 #define VIRTIO_NET_S_LINK_UP    1       /* Link is up */
 
-#define TX_TIMER_INTERVAL 150000 /* 150 us */
-
 /* Maximum packet size we can receive from tap device: header + 64k */
 #define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10))
 

^ permalink raw reply related

* [net-next-2.6 PATCH 3/3] be2net: destroy mcc queue before tx queues
From: Sathya Perla @ 2009-08-17 10:58 UTC (permalink / raw)
  To: netdev

As mcc queue uses the tx event queue.

Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
 drivers/net/benet/be_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 010175f..7b9efee 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1655,12 +1655,12 @@ do_none:
 
 static int be_clear(struct be_adapter *adapter)
 {
+	be_mcc_queues_destroy(adapter);
 	be_rx_queues_destroy(adapter);
 	be_tx_queues_destroy(adapter);
 
 	be_cmd_if_destroy(adapter, adapter->if_handle);
 
-	be_mcc_queues_destroy(adapter);
 	return 0;
 }
 
-- 
1.6.0.4


^ permalink raw reply related

* [net-next-2.6 PATCH 2/3] be2net: refactor be_msix_(un)register() code.
From: Sathya Perla @ 2009-08-17 10:58 UTC (permalink / raw)
  To: netdev

Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
 drivers/net/benet/be_main.c |   58 +++++++++++++++++++++++++++---------------
 1 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 3623460..010175f 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1303,6 +1303,12 @@ rx_eq_free:
 	return rc;
 }
 
+/* There are 8 evt ids per func. Retruns the evt id's bit number */
+static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
+{
+	return eq_id - 8 * be_pci_func(adapter);
+}
+
 static irqreturn_t be_intx(int irq, void *dev)
 {
 	struct be_adapter *adapter = dev;
@@ -1476,31 +1482,44 @@ static void be_msix_enable(struct be_adapter *adapter)
 
 static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
 {
-	return adapter->msix_entries[eq_id - 8 * be_pci_func(adapter)].vector;
+	return adapter->msix_entries[
+			be_evt_bit_get(adapter, eq_id)].vector;
 }
 
-static int be_msix_register(struct be_adapter *adapter)
+static int be_request_irq(struct be_adapter *adapter,
+		struct be_eq_obj *eq_obj,
+		void *handler, char *desc)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
-	int status, vec;
+	int vec;
+
+	sprintf(eq_obj->desc, "%s-%s", netdev->name, desc);
+	vec = be_msix_vec_get(adapter, eq_obj->q.id);
+	return request_irq(vec, handler, 0, eq_obj->desc, adapter);
+}
+
+static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj)
+{
+	int vec = be_msix_vec_get(adapter, eq_obj->q.id);
+	free_irq(vec, adapter);
+}
 
-	sprintf(tx_eq->desc, "%s-tx", netdev->name);
-	vec = be_msix_vec_get(adapter, tx_eq->q.id);
-	status = request_irq(vec, be_msix_tx_mcc, 0, tx_eq->desc, adapter);
+static int be_msix_register(struct be_adapter *adapter)
+{
+	int status;
+
+	status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx");
 	if (status)
 		goto err;
 
-	sprintf(rx_eq->desc, "%s-rx", netdev->name);
-	vec = be_msix_vec_get(adapter, rx_eq->q.id);
-	status = request_irq(vec, be_msix_rx, 0, rx_eq->desc, adapter);
-	if (status) { /* Free TX IRQ */
-		vec = be_msix_vec_get(adapter, tx_eq->q.id);
-		free_irq(vec, adapter);
-		goto err;
-	}
+	status = be_request_irq(adapter, &adapter->rx_eq, be_msix_rx, "rx");
+	if (status)
+		goto free_tx_irq;
+
 	return 0;
+
+free_tx_irq:
+	be_free_irq(adapter, &adapter->tx_eq);
 err:
 	dev_warn(&adapter->pdev->dev,
 		"MSIX Request IRQ failed - err %d\n", status);
@@ -1537,7 +1556,6 @@ done:
 static void be_irq_unregister(struct be_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	int vec;
 
 	if (!adapter->isr_registered)
 		return;
@@ -1549,10 +1567,8 @@ static void be_irq_unregister(struct be_adapter *adapter)
 	}
 
 	/* MSIx */
-	vec = be_msix_vec_get(adapter, adapter->tx_eq.q.id);
-	free_irq(vec, adapter);
-	vec = be_msix_vec_get(adapter, adapter->rx_eq.q.id);
-	free_irq(vec, adapter);
+	be_free_irq(adapter, &adapter->tx_eq);
+	be_free_irq(adapter, &adapter->rx_eq);
 done:
 	adapter->isr_registered = false;
 	return;
-- 
1.6.0.4


^ permalink raw reply related

* [net-next-2.6 PATCH 1/3] be2net: Set mac addr in hw regardless of netif_running()
From: Sathya Perla @ 2009-08-17 10:58 UTC (permalink / raw)
  To: netdev

be_mac_addr_set() currently is broken when netif_running() is false.

Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
 drivers/net/benet/be_main.c |   15 +++++----------
 1 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 45507d8..3623460 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -117,23 +117,18 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
 	iowrite32(val, adapter->db + DB_CQ_OFFSET);
 }
 
-
 static int be_mac_addr_set(struct net_device *netdev, void *p)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 	struct sockaddr *addr = p;
 	int status = 0;
 
-	if (netif_running(netdev)) {
-		status = be_cmd_pmac_del(adapter, adapter->if_handle,
-				adapter->pmac_id);
-		if (status)
-			return status;
-
-		status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
-				adapter->if_handle, &adapter->pmac_id);
-	}
+	status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id);
+	if (status)
+		return status;
 
+	status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
+			adapter->if_handle, &adapter->pmac_id);
 	if (!status)
 		memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 
-- 
1.6.0.4


^ permalink raw reply related

* Re: Very strange issues with ethernet wake on lan
From: Maxim Levitsky @ 2009-08-17  9:16 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-pm@lists.linux-foundation.org, Rafael J. Wysocki
In-Reply-To: <1250394174.32268.13.camel@localhost.localdomain>

On Sun, 2009-08-16 at 06:42 +0300, Maxim Levitsky wrote:
> Hi,
> 
> I have recently put back the davicom dm9009 ethernet card into my
> computer.
> 
> Some long time ago, I have written its suspend/resume routines.
> Now I see that few things have changed, like I need to enable wake in
> sysfs or better patch the code to do so, some nice helpers like
> pci_prepare_to_sleep have arrived, etc.
> 
> 
> I narrowed the strange issue down to following situation:
> 
> I reload dmfe.ko (and networkmanager is disabled)
> I don't ifup the device, thus pretty much no hardware initialization
> takes place (but this appears not to matter anyway)
> 
> I then suspend the system, and WOL doesn't work (I have patched the
> driver to enable WOL automaticly)
> 
> I then, suspend again. WOL works, and continues to work as long as I
> don't reload the driver. If I do, same situation repeats.
> 
> Also, after a boot, WOL works, so a reload cycle triggers that issue.
> 
> And most importantly, if I don't do a
> 
> pci_set_power_state(pci_dev, pci_choose_state (pci_dev, state));
> 
> in .suspend, then WOL always works.
> 
> and I have even tried to set state manually to PCI_D3hot or PCI_D3cold, 
> 
> I also tried to use pci_save_state
> 
> 
> I also have 2 copies of this card, and both have this issue.
> I also tried 2 pci slots.
> 
> Kernel is vanilla 2.6.31-rc5


Bisect reveals:

44e4e66eeae5338b3ca0b28f8352e60bf18d5ba8 is first bad commit
commit 44e4e66eeae5338b3ca0b28f8352e60bf18d5ba8
Author: Rafael J. Wysocki <rjw@sisk.pl>
Date:   Mon Jul 7 03:32:52 2008 +0200

    PCI: rework pci_set_power_state function to call platform first
    
    Rework pci_set_power_state() so that the platform callback is
    invoked before the native mechanism, if necessary.  Also, make
    the function check if the device is power manageable by the
    platform before invoking the platform callback.
    
    This may matter if the device dependent on additional power
    resources controlled by the platform is being put into D0, in which
    case those power resources must be turned on before we attempt to
    handle the device itself.
    
    Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
    Acked-by: Pavel Machek <pavel@suse.cz>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>


Note that probably this device has no acpi entries, because it is an
addon card, bios knows nothing about it


Best regards,
	Maxim Levitsky



^ permalink raw reply

* Re: TX on r8169 causes latency and messes up real-time apps, on some boards
From: Andrew Lutomirski @ 2009-08-17  5:31 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev
In-Reply-To: <20090817051926.GA10370@electric-eye.fr.zoreil.com>

This might be a false alarm -- it's possible I'm just trying to exceed
available PCI bandwidth.  I'll email back if I find any more
convincing evidence it's a problem with r8169.

Thanks,
Andy

On Mon, Aug 17, 2009 at 1:19 AM, Francois Romieu<romieu@fr.zoreil.com> wrote:
> Andrew Lutomirski <luto@mit.edu> :
> [...]
>> @@ -125,6 +125,11 @@
>>  ACPI: No dock devices found.
>>  ACPI: PCI Root Bridge [PCI0] (0000:00)
>>  pci 0000:00:00.0: reg 10 32bit mmio: [0x48000000-0x49ffffff]
>> +pci 0000:00:02.7: reg 10 io port: [0x2200-0x22ff]
>> +pci 0000:00:02.7: reg 14 io port: [0x2300-0x237f]
>> +pci 0000:00:02.7: supports D1 D2
>> +pci 0000:00:02.7: PME# supported from D3hot D3cold
>> +pci 0000:00:02.7: PME# disabled
> [...]
>> @@ -157,34 +162,34 @@
>>  ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
>>  ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.P0P1._PRT]
>>  ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 7 *10 11 12 14 15)
>> -ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 7 10 *11 12 14 15)
>> -ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 7 10 11 12 14 15) *0, disabled.
>> -ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 7 *10 11 12 14 15)
>> +ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 7 *10 11 12 14 15)
>> +ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 7 10 *11 12 14 15)
>> +ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 7 10 *11 12 14 15)
>
> There is some difference. Either the kernel, the board or the bios
> revision. I'd be surprized if the /proc/interrupts looked the same.
>
> --
> Ueimor
>

^ permalink raw reply

* Re: TX on r8169 causes latency and messes up real-time apps, on some boards
From: Francois Romieu @ 2009-08-17  5:19 UTC (permalink / raw)
  To: Andrew Lutomirski; +Cc: netdev
In-Reply-To: <cb0375e10908160339i4526b957nf73b0576f19da2bd@mail.gmail.com>

Andrew Lutomirski <luto@mit.edu> :
[...]
> @@ -125,6 +125,11 @@
>  ACPI: No dock devices found.
>  ACPI: PCI Root Bridge [PCI0] (0000:00)
>  pci 0000:00:00.0: reg 10 32bit mmio: [0x48000000-0x49ffffff]
> +pci 0000:00:02.7: reg 10 io port: [0x2200-0x22ff]
> +pci 0000:00:02.7: reg 14 io port: [0x2300-0x237f]
> +pci 0000:00:02.7: supports D1 D2
> +pci 0000:00:02.7: PME# supported from D3hot D3cold
> +pci 0000:00:02.7: PME# disabled
[...]
> @@ -157,34 +162,34 @@
>  ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
>  ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.P0P1._PRT]
>  ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 7 *10 11 12 14 15)
> -ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 7 10 *11 12 14 15)
> -ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 7 10 11 12 14 15) *0, disabled.
> -ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 7 *10 11 12 14 15)
> +ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 7 *10 11 12 14 15)
> +ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 7 10 *11 12 14 15)
> +ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 7 10 *11 12 14 15)

There is some difference. Either the kernel, the board or the bios
revision. I'd be surprized if the /proc/interrupts looked the same.

-- 
Ueimor

^ permalink raw reply

* [PATCH] net: Rename MAC platform driver for w90p910 platform
From: Wan ZongShun @ 2009-08-17  4:00 UTC (permalink / raw)
  To: David S. Miller; +Cc: linux-arm-kernel, linux-netdev

Dear David,

Due to I modified the corresponding platform device name, 
so I make the patch to rename MAC platform driver
for w90p910 platform.

Signed-off-by: Wan ZongShun <mcuos.com@gmail.com>

---
 drivers/net/arm/w90p910_ether.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c
index 890716f..3a0948f 100644
--- a/drivers/net/arm/w90p910_ether.c
+++ b/drivers/net/arm/w90p910_ether.c
@@ -1098,7 +1098,7 @@ static struct platform_driver w90p910_ether_driver = {
 	.probe		= w90p910_ether_probe,
 	.remove		= __devexit_p(w90p910_ether_remove),
 	.driver		= {
-		.name	= "w90p910-emc",
+		.name	= "nuc900-emc",
 		.owner	= THIS_MODULE,
 	},
 };
@@ -1119,5 +1119,5 @@ module_exit(w90p910_ether_exit);
 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
 MODULE_DESCRIPTION("w90p910 MAC driver!");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:w90p910-emc");
+MODULE_ALIAS("platform:nuc900-emc");
 
-- 
1.5.6.3

^ permalink raw reply related

* PROBLEM: kernel freezes, possibly via velocity-related
From: Arvid Brodin @ 2009-08-17  1:54 UTC (permalink / raw)
  To: netdev

[I sent this to lkml a few days ago; sending it to netdev (being the
maillist for the via velocity driver) now after Alan Cox responded
thinking that might be a good idea.]

Hi,

Since I started running deluged (a bittorrent daemon) on my file server,
I've started getting sporadic kernel freezes, a few times a week or so.

Symptoms:
* Keyboard stops responding (SysRq combos does not work),
* No panic/oops message on the console; the screen displays the normal
login prompt with a blinking cursor,
* The network activity LED flashes steadily at 1-2 Hz. The corresponding
LED on my switch blinks too, but the traffic does not seem to get
forwarded to any other port on the switch (no other lights blinking),
* The machine does not respond to pings or ssh logins,
* Nothing in var/log/messages or kern.log that I can relate to the
freeze (I have gotten some "UDP: short packet" and "eth0: excessive work
at interrupt" messages a few hours before the freezes a few times, but
that's all).

I've never gotten a freeze with the deluge daemon stopped (which it has
been for many weeks sometimes), but consistently get freezes, often
within a day or two, when it is started and have active torrents.

In addition to the kernel I currently run (2.6.29.4), the freezes also
occured with gentoo kernels 2.6.23-gentoo-r8 and 2.6.27-gentoo-r10.

# uname -a
Linux sv1 2.6.29.4 #1 Thu May 21 03:26:33 CEST 2009 i686 VIA Esther
processor 1200MHz CentaurHauls GNU/Linux

# lspci -vvv
See http://pastebin.com/f21145883

# cat /proc/cpuinfo
processor	: 0
vendor_id	: CentaurHauls
cpu family	: 6
model		: 10
model name	: VIA Esther processor 1200MHz
stepping	: 9
cpu MHz		: 1199.496
cache size	: 128 KB
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 1
wp		: yes
flags		: fpu vme de pse tsc msr pae mce apic sep mtrr pge cmov pat
clflush acpi mmx fxsr sse sse2 tm nx pni est tm2 rng rng_en ace ace_en
ace2 ace2_en phe phe_en pmm pmm_en
bogomips	: 2399.95
clflush size	: 64
power management:


Should I report this to the maintainer of my network driver? I'm not
sure the symptoms are clear enough to directly blame the network driver,
but I do suspect it. Is there some way I can debug a frozen kernel to
zoom in on the problem?

-- 
Arvid


^ permalink raw reply

* [PATCH 2/2] au1000-eth: convert to a platform driver
From: Florian Fainelli @ 2009-08-16 23:05 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: linux-mips, Manuel Lauss, David Miller, netdev, Sergei Shtylyov

This patch converts the au1000-eth driver to become a full
platform-driver as it ought to be. We now pass PHY-speficic
configurations through platform_data but for compatibility
the driver still assumes the default settings (search for PHY1 on
MAC0) when no platform_data is passed. Tested on my MTX-1 board.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 2aab1eb..57cc4f6 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -54,6 +54,7 @@
 #include <linux/delay.h>
 #include <linux/crc32.h>
 #include <linux/phy.h>
+#include <linux/platform_device.h>
 
 #include <asm/cpu.h>
 #include <asm/mipsregs.h>
@@ -62,6 +63,7 @@
 #include <asm/processor.h>
 
 #include <au1000.h>
+#include <au1xxx_eth.h>
 #include <prom.h>
 
 #include "au1000_eth.h"
@@ -111,15 +113,15 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
  *
  * PHY detection algorithm
  *
- * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is
+ * If phy_static_config is undefined, the PHY setup is
  * autodetected:
  *
  * mii_probe() first searches the current MAC's MII bus for a PHY,
- * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is
+ * selecting the first (or last, if phy_search_highest_addr is
  * defined) PHY address not already claimed by another netdev.
  *
  * If nothing was found that way when searching for the 2nd ethernet
- * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then
+ * controller's PHY and phy1_search_mac0 is defined, then
  * the first MII bus is searched as well for an unclaimed PHY; this is
  * needed in case of a dual-PHY accessible only through the MAC0's MII
  * bus.
@@ -128,9 +130,7 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
  * controller is not registered to the network subsystem.
  */
 
-/* autodetection defaults */
-#undef  AU1XXX_PHY_SEARCH_HIGHEST_ADDR
-#define AU1XXX_PHY1_SEARCH_ON_MAC0
+/* autodetection defaults: phy1_search_mac0 */
 
 /* static PHY setup
  *
@@ -147,29 +147,6 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
  * specific irq-map
  */
 
-#if defined(CONFIG_MIPS_BOSPORUS)
-/*
- * Micrel/Kendin 5 port switch attached to MAC0,
- * MAC0 is associated with PHY address 5 (== WAN port)
- * MAC1 is not associated with any PHY, since it's connected directly
- * to the switch.
- * no interrupts are used
- */
-# define AU1XXX_PHY_STATIC_CONFIG
-
-# define AU1XXX_PHY0_ADDR  5
-# define AU1XXX_PHY0_BUSID 0
-#  undef AU1XXX_PHY0_IRQ
-
-#  undef AU1XXX_PHY1_ADDR
-#  undef AU1XXX_PHY1_BUSID
-#  undef AU1XXX_PHY1_IRQ
-#endif
-
-#if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0)
-# error MAC0-associated PHY attached 2nd MACs MII bus not supported yet
-#endif
-
 static void enable_mac(struct net_device *dev, int force_reset)
 {
 	unsigned long flags;
@@ -389,67 +366,54 @@ static int mii_probe (struct net_device *dev)
 	struct au1000_private *const aup = netdev_priv(dev);
 	struct phy_device *phydev = NULL;
 
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
-	BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
+	if (aup->phy_static_config) {
+		BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
 
-	if(aup->mac_id == 0) { /* get PHY0 */
-# if defined(AU1XXX_PHY0_ADDR)
-		phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus->phy_map[AU1XXX_PHY0_ADDR];
-# else
-		printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
-			dev->name);
-		return 0;
-# endif /* defined(AU1XXX_PHY0_ADDR) */
-	} else if (aup->mac_id == 1) { /* get PHY1 */
-# if defined(AU1XXX_PHY1_ADDR)
-		phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus->phy_map[AU1XXX_PHY1_ADDR];
-# else
-		printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
-			dev->name);
+		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);
 		return 0;
-# endif /* defined(AU1XXX_PHY1_ADDR) */
-	}
-
-#else /* defined(AU1XXX_PHY_STATIC_CONFIG) */
-	int phy_addr;
-
-	/* find the first (lowest address) PHY on the current MAC's MII bus */
-	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
-		if (aup->mii_bus->phy_map[phy_addr]) {
-			phydev = aup->mii_bus->phy_map[phy_addr];
-# if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR)
-			break; /* break out with first one found */
-# endif
-		}
-
-# if defined(AU1XXX_PHY1_SEARCH_ON_MAC0)
-	/* 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, "
-			"let's see if it's attached to MAC0...\n");
-
-		BUG_ON(!au_macs[0]);
-
-		/* find the first (lowest address) non-attached PHY on
-		 * the MAC0 MII bus */
-		for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
-			struct phy_device *const tmp_phydev =
-				au_macs[0]->mii_bus->phy_map[phy_addr];
-
-			if (!tmp_phydev)
-				continue; /* no PHY here... */
-
-			if (tmp_phydev->attached_dev)
-				continue; /* already claimed by MAC0 */
+	} else {
+		int phy_addr;
+
+		/* find the first (lowest address) PHY on the current MAC's MII bus */
+		for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+			if (aup->mii_bus->phy_map[phy_addr]) {
+				phydev = aup->mii_bus->phy_map[phy_addr];
+				if (!aup->phy_search_highest_addr)
+					break; /* break out with first one found */
+			}
 
-			phydev = tmp_phydev;
-			break; /* found it */
+		if (aup->phy1_search_mac0) {
+			/* 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, "
+					"let's see if it's attached to MAC0...\n");
+
+				/* find the first (lowest address) non-attached PHY on
+		 		* the MAC0 MII bus */
+				for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+					if (aup->mac_id == 1)
+						break;
+					struct phy_device *const tmp_phydev =
+							aup->mii_bus->phy_map[phy_addr];
+
+					if (!tmp_phydev)
+						continue; /* no PHY here... */
+
+					if (tmp_phydev->attached_dev)
+						continue; /* already claimed by MAC0 */
+
+					phydev = tmp_phydev;
+					break; /* found it */
+				}
+			}
 		}
 	}
-# endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */
 
-#endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */
 	if (!phydev) {
 		printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name);
 		return -1;
@@ -577,31 +541,6 @@ setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
 	}
 }
 
-static struct {
-	u32 base_addr;
-	u32 macen_addr;
-	int irq;
-	struct net_device *dev;
-} iflist[2] = {
-#ifdef CONFIG_SOC_AU1000
-	{AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT},
-	{AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1100
-	{AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1500
-	{AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT},
-	{AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1550
-	{AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT},
-	{AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT}
-#endif
-};
-
-static int num_ifs;
-
 /*
  * ethtool operations
  */
@@ -1059,46 +998,59 @@ static const struct net_device_ops au1000_netdev_ops = {
 	.ndo_change_mtu		= eth_change_mtu,
 };
 
-static struct net_device * au1000_probe(int port_num)
+static int __devinit au1000_probe(struct platform_device *pdev)
 {
 	static unsigned version_printed = 0;
 	struct au1000_private *aup = NULL;
+	struct au1000_eth_platform_data *pd;
 	struct net_device *dev = NULL;
 	db_dest_t *pDB, *pDBfree;
-	char ethaddr[6];
-	int irq, i, err;
-	u32 base, macen;
-
-	if (port_num >= NUM_ETH_INTERFACES)
-		return NULL;
+	int irq, i, err = 0;
+	struct resource *base, *macen;
+	DECLARE_MAC_BUF(ethaddr);
+
+	base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!base) {
+		printk(KERN_ERR DRV_NAME ": failed to retrieve base register\n");
+		err = -ENODEV;
+		goto out;
+	}
 
-	base  = CPHYSADDR(iflist[port_num].base_addr );
-	macen = CPHYSADDR(iflist[port_num].macen_addr);
-	irq = iflist[port_num].irq;
+	macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!macen) {
+		printk(KERN_ERR DRV_NAME ": failed to retrieve MAC Enable register\n");
+		err = -ENODEV;
+		goto out;
+	}
 
-	if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
-	    !request_mem_region(macen, 4, "Au1x00 ENET"))
-		return NULL;
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n");
+		err = -ENODEV;
+		goto out;
+	}
 
-	if (version_printed++ == 0)
-		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+	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");
+		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");
+		err = -ENXIO;
+		goto err_request;
+	}
 
 	dev = alloc_etherdev(sizeof(struct au1000_private));
 	if (!dev) {
 		printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
-		return NULL;
-	}
-
-	if ((err = register_netdev(dev)) != 0) {
-		printk(KERN_ERR "%s: Cannot register net device, error %d\n",
-				DRV_NAME, err);
-		free_netdev(dev);
-		return NULL;
+		err = -ENOMEM;
+		goto err_alloc;
 	}
 
-	printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
-		dev->name, base, irq);
-
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	platform_set_drvdata(pdev, dev);
 	aup = netdev_priv(dev);
 
 	spin_lock_init(&aup->lock);
@@ -1109,21 +1061,29 @@ static struct net_device * au1000_probe(int port_num)
 						(NUM_TX_BUFFS + NUM_RX_BUFFS),
 						&aup->dma_addr,	0);
 	if (!aup->vaddr) {
-		free_netdev(dev);
-		release_mem_region( base, MAC_IOSIZE);
-		release_mem_region(macen, 4);
-		return NULL;
+		printk(KERN_ERR DRV_NAME ": failed to allocate data buffers\n");
+		err = -ENOMEM;
+		goto err_vaddr;
 	}
 
 	/* aup->mac is the base address of the MAC's registers */
-	aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
+	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");
+		err = -ENXIO;
+		goto err_remap1;
+	}
 
-	/* Setup some variables for quick register address access */
-	aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
-	aup->mac_id = port_num;
-	au_macs[port_num] = aup;
+        /* 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");
+		err = -ENXIO;
+		goto err_remap2;
+	}
+	aup->mac_id = pdev->id;
 
-	if (port_num == 0) {
+	if (pdev->id == 0) {
 		if (prom_get_ethernet_addr(ethaddr) == 0)
 			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
 		else {
@@ -1133,7 +1093,7 @@ static struct net_device * au1000_probe(int port_num)
 		}
 
 		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
-	} else if (port_num == 1)
+	} else if (pdev->id == 1)
 		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
 
 	/*
@@ -1141,14 +1101,37 @@ static struct net_device * au1000_probe(int port_num)
 	 * to match those that are printed on their stickers
 	 */
 	memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
-	dev->dev_addr[5] += port_num;
+	dev->dev_addr[5] += pdev->id;
 
 	*aup->enable = 0;
 	aup->mac_enabled = 0;
 
+	pd = pdev->dev.platform_data;
+	if (!pd) {
+		printk(KERN_INFO DRV_NAME ": no platform_data passed, PHY search on MAC0\n");
+		aup->phy1_search_mac0 = 1;
+	} else {
+		aup->phy_static_config = pd->phy_static_config;
+		aup->phy_search_highest_addr = pd->phy_search_highest_addr;
+		aup->phy1_search_mac0 = pd->phy1_search_mac0;
+		aup->phy_addr = pd->phy_addr;
+		aup->phy_busid = pd->phy_busid;
+		aup->phy_irq = pd->phy_irq;
+	}
+
+	if (aup->phy_busid && aup->phy_busid > 0) {
+		printk(KERN_ERR DRV_NAME ": MAC0-associated PHY attached 2nd MACs MII"
+				"bus not supported yet\n");
+		err = -ENODEV;
+		goto err_mdiobus_alloc;
+	}
+
 	aup->mii_bus = mdiobus_alloc();
-	if (aup->mii_bus == NULL)
-		goto err_out;
+	if (aup->mii_bus == NULL) {
+		printk(KERN_ERR DRV_NAME ": failed to allocate mdiobus structure\n");
+		err = -ENOMEM;
+		goto err_mdiobus_alloc;
+	}
 
 	aup->mii_bus->priv = dev;
 	aup->mii_bus->read = au1000_mdiobus_read;
@@ -1159,23 +1142,19 @@ static struct net_device * au1000_probe(int port_num)
 	aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
 	for(i = 0; i < PHY_MAX_ADDR; ++i)
 		aup->mii_bus->irq[i] = PHY_POLL;
-
 	/* if known, set corresponding PHY IRQs */
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
-# if defined(AU1XXX_PHY0_IRQ)
-	if (AU1XXX_PHY0_BUSID == aup->mac_id)
-		aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
-# endif
-# if defined(AU1XXX_PHY1_IRQ)
-	if (AU1XXX_PHY1_BUSID == aup->mac_id)
-		aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
-# endif
-#endif
-	mdiobus_register(aup->mii_bus);
+	if (aup->phy_static_config)
+		if (aup->phy_irq && aup->phy_busid == aup->mac_id)
+			aup->mii_bus->irq[aup->phy_addr] = aup->phy_irq;
+	
+	err = mdiobus_register(aup->mii_bus);
+	if (err) {
+		printk(KERN_ERR DRV_NAME " failed to register MDIO bus\n");
+		goto err_mdiobus_reg;
+	}
 
-	if (mii_probe(dev) != 0) {
+	if (mii_probe(dev) != 0)
 		goto err_out;
-	}
 
 	pDBfree = NULL;
 	/* setup the data buffer descriptors and attach a buffer to each one */
@@ -1207,7 +1186,7 @@ static struct net_device * au1000_probe(int port_num)
 		aup->tx_db_inuse[i] = pDB;
 	}
 
-	dev->base_addr = base;
+	dev->base_addr = base->start;
 	dev->irq = irq;
 	dev->netdev_ops = &au1000_netdev_ops;
 	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
@@ -1219,14 +1198,24 @@ static struct net_device * au1000_probe(int port_num)
 	 */
 	reset_mac(dev);
 
-	return dev;
+	err = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR DRV_NAME "%s: Cannot register net device, aborting.\n",
+					dev->name);
+		goto err_out;
+	}
+	
+	printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
+					dev->name, base->start, irq);
+	if (version_printed++ == 0)
+		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+
+	return 0;
 
 err_out:
-	if (aup->mii_bus != NULL) {
+	if (aup->mii_bus != NULL)
 		mdiobus_unregister(aup->mii_bus);
-		mdiobus_free(aup->mii_bus);
-	}
-
+	
 	/* here we should have a valid dev plus aup-> register addresses
 	 * so we can reset the mac properly.*/
 	reset_mac(dev);
@@ -1239,67 +1228,84 @@ err_out:
 		if (aup->tx_db_inuse[i])
 			ReleaseDB(aup, aup->tx_db_inuse[i]);
 	}
+err_mdiobus_reg:
+	mdiobus_free(aup->mii_bus);
+err_mdiobus_alloc:
+	iounmap(aup->enable);
+err_remap2:
+	iounmap(aup->mac);
+err_remap1:
 	dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
 			     (void *)aup->vaddr, aup->dma_addr);
-	unregister_netdev(dev);
+err_vaddr:
 	free_netdev(dev);
-	release_mem_region( base, MAC_IOSIZE);
-	release_mem_region(macen, 4);
-	return NULL;
+err_alloc:
+	release_mem_region(macen->start, resource_size(macen));
+err_request:
+	release_mem_region(base->start, resource_size(base));
+out:
+	return err;
 }
 
-/*
- * Setup the base address and interrupt of the Au1xxx ethernet macs
- * based on cpu type and whether the interface is enabled in sys_pinfunc
- * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
- */
-static int __init au1000_init_module(void)
+static int __devexit au1000_remove(struct platform_device *pdev)
 {
-	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
-	struct net_device *dev;
-	int i, found_one = 0;
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct au1000_private *aup = netdev_priv(dev);
+	int i;
+	struct resource *base, *macen;
 
-	num_ifs = NUM_ETH_INTERFACES - ni;
+	platform_set_drvdata(pdev, NULL);
+
+	unregister_netdev(dev);
+	mdiobus_unregister(aup->mii_bus);
+	mdiobus_free(aup->mii_bus);
+
+	for (i = 0; i < NUM_RX_DMA; i++)
+		if (aup->rx_db_inuse[i])
+			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]);
+
+	dma_free_noncoherent(NULL, MAX_BUF_SIZE *
+			(NUM_TX_BUFFS + NUM_RX_BUFFS),
+			(void *)aup->vaddr, aup->dma_addr);
+
+	iounmap(aup->mac);
+	iounmap(aup->enable);
+
+	base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(base->start, resource_size(base));
+
+	macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	release_mem_region(macen->start, resource_size(macen));
+	
+	free_netdev(dev);
 
-	for(i = 0; i < num_ifs; i++) {
-		dev = au1000_probe(i);
-		iflist[i].dev = dev;
-		if (dev)
-			found_one++;
-	}
-	if (!found_one)
-		return -ENODEV;
 	return 0;
 }
 
-static void __exit au1000_cleanup_module(void)
+static struct platform_driver au1000_eth_driver = {
+	.probe  = au1000_probe,
+	.remove = __devexit_p(au1000_remove),
+	.driver = {
+		.name   = "au1000-eth",
+		.owner  = THIS_MODULE,
+	},
+};
+MODULE_ALIAS("platform:au1000-eth");
+
+
+static int __init au1000_init_module(void)
 {
-	int i, j;
-	struct net_device *dev;
-	struct au1000_private *aup;
-
-	for (i = 0; i < num_ifs; i++) {
-		dev = iflist[i].dev;
-		if (dev) {
-			aup = netdev_priv(dev);
-			unregister_netdev(dev);
-			mdiobus_unregister(aup->mii_bus);
-			mdiobus_free(aup->mii_bus);
-			for (j = 0; j < NUM_RX_DMA; j++)
-				if (aup->rx_db_inuse[j])
-					ReleaseDB(aup, aup->rx_db_inuse[j]);
-			for (j = 0; j < NUM_TX_DMA; j++)
-				if (aup->tx_db_inuse[j])
-					ReleaseDB(aup, aup->tx_db_inuse[j]);
-			dma_free_noncoherent(NULL, MAX_BUF_SIZE *
-					     (NUM_TX_BUFFS + NUM_RX_BUFFS),
-					     (void *)aup->vaddr, aup->dma_addr);
-			release_mem_region(dev->base_addr, MAC_IOSIZE);
-			release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
-			free_netdev(dev);
-		}
-	}
+	return platform_driver_register(&au1000_eth_driver);
+}
+
+static void __exit au1000_exit_module(void)
+{
+	platform_driver_unregister(&au1000_eth_driver);
 }
 
 module_init(au1000_init_module);
-module_exit(au1000_cleanup_module);
+module_exit(au1000_exit_module);
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index 824ecd5..f9d29a2 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -108,6 +108,15 @@ struct au1000_private {
 	struct phy_device *phy_dev;
 	struct mii_bus *mii_bus;
 
+	/* PHY configuration */
+	int phy_static_config;
+	int phy_search_highest_addr;
+	int phy1_search_mac0;
+
+	int phy_addr;
+	int phy_busid;
+	int phy_irq;
+
 	/* These variables are just for quick access to certain regs addresses. */
 	volatile mac_reg_t *mac;  /* mac registers                      */
 	volatile u32 *enable;     /* address of MAC Enable Register     */

^ permalink raw reply related

* [PATCH 1/2] alchemy: add au1000-eth platform device
From: Florian Fainelli @ 2009-08-16 23:05 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: linux-mips, Manuel Lauss, David Miller, netdev, Sergei Shtylyov

This patch adds the board code to register a per-board au1000-eth
platform device to be used wit the au1000-eth platform driver in a
subsequent patch. Note that the au1000-eth driver knows about the
default driver settings such that we do not need to pass any
platform_data informations in most cases except db1x00.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/arch/mips/alchemy/devboards/db1x00/Makefile b/arch/mips/alchemy/devboards/db1x00/Makefile
index 432241a..532a214 100644
--- a/arch/mips/alchemy/devboards/db1x00/Makefile
+++ b/arch/mips/alchemy/devboards/db1x00/Makefile
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
 #
 
-obj-y := board_setup.o irqmap.o
+obj-y := board_setup.o irqmap.o platform.o
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c
new file mode 100644
index 0000000..df0d68a
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1x00/platform.c
@@ -0,0 +1,101 @@
+/*
+ * Db1x00 platform devices registration
+ *
+ * Copyright (C) 2009, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+static struct resource au1xxx_eth0_resources[] = {
+#if defined(CONFIG_SOC_AU1000)
+	MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT),
+#elif defined(CONFIG_SOC_AU1100)
+	MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT),
+#elif defined(CONFIG_SOC_AU1550)
+	MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT),
+#elif defined(CONFIG_SOC_AU1500)
+	MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
+#endif
+};
+
+static struct resource au1xxx_eth1_resources[] = {
+#if defined(CONFIG_SOC_AU1000)
+	MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT),
+#elif defined(CONFIG_SOC_AU1550)
+	MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT),
+#elif defined(CONFIG_SOC_AU1500)
+	MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
+#endif
+};
+
+/* Except for Bosporus, default is to search for a PHY on MAC0 */
+static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
+	.phy1_search_mac0 = 1,
+};
+
+static struct platform_device db1x00_eth0 = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth0_resources,
+.	.dev.platform_data = &au1xxx_eth0_platform_data,
+};
+
+#ifndef CONFIG_SOC_AU1100
+static struct platform_device db1x00_eth1 = {
+	.name		= "au1000-eth",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
+	.resource	= au1xxx_eth1_resources,
+};
+#endif
+
+static struct platform_device *db1x00_devs[] = {
+	&db1x00_eth0,
+};
+
+static int __init db1x00_register_devices(void)
+{
+#ifdef CONFIG_MIPS_BOSPORUS
+	/*
+	 * Micrel/Kendin 5 port switch attached to MAC0,
+	 * MAC0 is associated with PHY address 5 (== WAN port)
+	 * MAC1 is not associated with any PHY, since it's connected directly
+	 * to the switch.
+	 * no interrupts are used
+	 */
+	au1xxx_eth0_platform_data.phy1_search_mac0 = 0;
+	au1xxx_eth0_platform_data.phy_static_config = 1;
+	au1xxx_eth0_platform_data.phy_addr = 5;
+	au1xxx_eth0_platform_data.phy_busid = 0;
+#endif
+
+#ifndef CONFIG_SOC_AU1100
+	int ni;
+
+	ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
+	if (!(ni + 1))
+		platform_device_register(&db1x00_eth1);
+#endif
+
+	return platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs));
+}
+arch_initcall(db1x00_register_devices);
diff --git a/arch/mips/alchemy/devboards/pb1000/Makefile b/arch/mips/alchemy/devboards/pb1000/Makefile
index 97c6615..38d11bb 100644
--- a/arch/mips/alchemy/devboards/pb1000/Makefile
+++ b/arch/mips/alchemy/devboards/pb1000/Makefile
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor Pb1000 board.
 #
 
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1000/platform.c b/arch/mips/alchemy/devboards/pb1000/platform.c
new file mode 100644
index 0000000..621e71c
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1000/platform.c
@@ -0,0 +1,58 @@
+/*
+ * PB1000 platform devices registration
+ *
+ * Copyright (C) 2009, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+static struct resource au1xxx_eth0_resources[] = {
+	MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT),
+};
+
+static struct resource au1xxx_eth1_resources[] = {
+	MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT),
+};
+
+static struct platform_device pb1000_eth0 = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth1_resources,
+};
+
+static struct platform_device pb1000_eth1 = {
+	.name		= "au1000-eth",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
+	.resource	= au1xxx_eth1_resources,
+};
+
+static struct platform_device *pb1000_devs[] = {
+	&pb1000_eth0,
+	&pb1000_eth1,
+};
+
+static int __init pb1000_register_devices(void)
+{
+	return platform_add_devices(pb1000_devs, ARRAY_SIZE(pb1000_devs));
+}
+arch_initcall(pb1000_register_devices);
diff --git a/arch/mips/alchemy/devboards/pb1100/Makefile b/arch/mips/alchemy/devboards/pb1100/Makefile
index c586dd7..7e3756c 100644
--- a/arch/mips/alchemy/devboards/pb1100/Makefile
+++ b/arch/mips/alchemy/devboards/pb1100/Makefile
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor Pb1100 board.
 #
 
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1100/platform.c b/arch/mips/alchemy/devboards/pb1100/platform.c
new file mode 100644
index 0000000..9ff939c
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1100/platform.c
@@ -0,0 +1,47 @@
+/*
+ * PB1100 platform devices registration
+ *
+ * Copyright (C) 2009, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+static struct resource au1xxx_eth0_resources[] = {
+	MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT),
+};
+
+static struct platform_device pb1100_eth0 = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth0_resources,
+};
+
+static struct platform_device *pb1100_devs[] = {
+	&pb1100_eth0,
+};
+
+static int __init pb1100_register_devices(void)
+{
+	return platform_add_devices(pb1100_devs, ARRAY_SIZE(pb1100_devs));
+}
+
+arch_initcall(pb1100_register_devices);
diff --git a/arch/mips/alchemy/devboards/pb1500/Makefile b/arch/mips/alchemy/devboards/pb1500/Makefile
index 173b419..e83b151 100644
--- a/arch/mips/alchemy/devboards/pb1500/Makefile
+++ b/arch/mips/alchemy/devboards/pb1500/Makefile
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor Pb1500 board.
 #
 
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1500/platform.c b/arch/mips/alchemy/devboards/pb1500/platform.c
new file mode 100644
index 0000000..98dbe8f
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1500/platform.c
@@ -0,0 +1,59 @@
+/*
+ * PB1500 platform devices registration
+ *
+ * Copyright (C) 2009, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+static struct resource au1xxx_eth0_resources[] = {
+	MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
+};
+
+static struct resource au1xxx_eth1_resources[] = {
+	MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
+};
+
+static struct platform_device pb1500_eth0 = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth0_resources,
+};
+
+static struct platform_device pb1500_eth1 = {
+	.name		= "au1000-eth",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
+	.resource	= au1xxx_eth1_resources,
+};
+
+static struct platform_device *pb1500_devs[] = {
+	&pb1500_eth0,
+	&pb1500_eth1,
+};
+
+static int __init pb1500_register_devices(void)
+{
+	return platform_add_devices(pb1500_devs, ARRAY_SIZE(pb1500_devs));
+}
+
+arch_initcall(pb1500_register_devices);
diff --git a/arch/mips/alchemy/devboards/pb1550/Makefile b/arch/mips/alchemy/devboards/pb1550/Makefile
index cff95bc..9661b6e 100644
--- a/arch/mips/alchemy/devboards/pb1550/Makefile
+++ b/arch/mips/alchemy/devboards/pb1550/Makefile
@@ -5,4 +5,4 @@
 # Makefile for the Alchemy Semiconductor Pb1550 board.
 #
 
-obj-y := board_setup.o
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1550/platform.c b/arch/mips/alchemy/devboards/pb1550/platform.c
new file mode 100644
index 0000000..c46f4ef
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1550/platform.c
@@ -0,0 +1,59 @@
+/*
+ * PB1550 platform devices registration
+ *
+ * Copyright (C) 2009, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+static struct resource au1xxx_eth0_resources[] = {
+	MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT),
+};
+
+static struct resource au1xxx_eth1_resources[] = {
+	MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT),
+};
+
+static struct platform_device pb1550_eth0 = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth0_resources,
+};
+
+static struct platform_device pb1550_eth1 = {
+	.name		= "au1000-eth",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
+	.resource	= au1xxx_eth1_resources,
+};
+
+static struct platform_device *pb1550_devs[] = {
+	&pb1550_eth0,
+	&pb1550_eth1,
+};
+
+static int __init pb1550_register_devices(void)
+{
+	return platform_add_devices(pb1550_devs, ARRAY_SIZE(pb1550_devs));
+}
+
+arch_initcall(pb1550_register_devices);
diff --git a/arch/mips/alchemy/mtx-1/platform.c b/arch/mips/alchemy/mtx-1/platform.c
index e30e42a..30a7a56 100644
--- a/arch/mips/alchemy/mtx-1/platform.c
+++ b/arch/mips/alchemy/mtx-1/platform.c
@@ -28,6 +28,9 @@
 #include <linux/mtd/physmap.h>
 #include <mtd/mtd-abi.h>
 
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
 static struct gpio_keys_button mtx1_gpio_button[] = {
 	{
 		.gpio = 207,
@@ -133,11 +136,23 @@ static struct platform_device mtx1_mtd = {
 	.resource	= &mtx1_mtd_resource,
 };
 
+static struct resource au1xxx_eth0_resources[] = {
+	MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
+};
+
+static struct platform_device mtx1_eth = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth0_resources,
+};
+
 static struct __initdata platform_device * mtx1_devs[] = {
 	&mtx1_gpio_leds,
 	&mtx1_wdt,
 	&mtx1_button,
 	&mtx1_mtd,
+	&mtx1_eth,
 };
 
 static int __init mtx1_register_devices(void)
diff --git a/arch/mips/alchemy/xxs1500/Makefile b/arch/mips/alchemy/xxs1500/Makefile
index db3c526..375748f 100644
--- a/arch/mips/alchemy/xxs1500/Makefile
+++ b/arch/mips/alchemy/xxs1500/Makefile
@@ -6,3 +6,4 @@
 #
 
 lib-y := init.o board_setup.o irqmap.o
+obj-y := platform.o
diff --git a/arch/mips/alchemy/xxs1500/platform.c b/arch/mips/alchemy/xxs1500/platform.c
new file mode 100644
index 0000000..ef7f7b7
--- /dev/null
+++ b/arch/mips/alchemy/xxs1500/platform.c
@@ -0,0 +1,59 @@
+/*
+ * XXS1500 platform devices registration
+ *
+ * Copyright (C) 2009, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+static struct resource au1xxx_eth0_resources[] = {
+	MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
+};
+
+static struct resource au1xxx_eth1_resources[] = {
+	MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
+};
+
+static struct platform_device xxs1500_eth0 = {
+	.name		= "au1000-eth",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
+	.resource	= au1xxx_eth0_resources,
+};
+
+static struct platform_device xxs1500_eth1 = {
+	.name		= "au1000-eth",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
+	.resource	= au1xxx_eth1_resources,
+};
+
+static struct platform_device *xxs1500_devs[] = {
+	&xxs1500_eth0,
+	&xxs1500_eth1,
+};
+
+static int __init xxs1500_register_devices(void)
+{
+	return platform_add_devices(xxs1500_devs, ARRAY_SIZE(xxs1500_devs));
+}
+
+arch_initcall(xxs1500_register_devices);
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
new file mode 100644
index 0000000..6d1543e
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
@@ -0,0 +1,33 @@
+#ifndef __AU1X00_ETH_DATA_H
+#define __AU1X00_ETH_DATA_H
+
+/* Macro to help defining the Ethernet MAC resources */
+#define MAC_RES(_base, _enable, _irq)			\
+	{						\
+		.start	= CPHYSADDR(_base),		\
+		.end	= CPHYSADDR(_base + 0xffff),	\
+		.flags	= IORESOURCE_MEM,		\
+	},						\
+	{						\
+		.start	= CPHYSADDR(_enable),		\
+		.end	= CPHYSADDR(_enable + 0x4),	\
+		.flags	= IORESOURCE_MEM,		\
+	},						\
+	{						\
+		.start	= _irq,				\
+		.end	= _irq,				\
+		.flags	= IORESOURCE_IRQ		\
+	}
+
+/* Platform specific PHY configuration passed to the MAC driver */
+struct au1000_eth_platform_data {
+	int phy_static_config;
+	int phy_search_highest_addr;
+	int phy1_search_mac0;
+	int phy_addr;
+	int phy_busid;
+	int phy_irq;
+};
+
+#endif /* __AU1X00_ETH_DATA_H */
+

^ permalink raw reply related

* Re: [PATCH] Revert netlink ABI change to gnet_stats_basic
From: Michael Spang @ 2009-08-16 20:10 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David S. Miller, LKML, Linux Netdev List
In-Reply-To: <4A885FD1.4030105@gmail.com>

On Sun, Aug 16, 2009 at 3:36 PM, Eric Dumazet<eric.dumazet@gmail.com> wrote:
> Michael Spang a écrit :
>
> OK, then we are stuck to use a separate definition for user land
> and kernel land, or risk various side effects, like performance hit
> and security risk.
>
> Thanks a lot Michael
>
> [PATCH] net: restore gnet_stats_basic to previous definition

Applied it and it works for me, thanks.

Michael

^ permalink raw reply

* Re: [PATCH] Revert netlink ABI change to gnet_stats_basic
From: Eric Dumazet @ 2009-08-16 19:36 UTC (permalink / raw)
  To: Michael Spang; +Cc: David S. Miller, LKML, Linux Netdev List
In-Reply-To: <118a63b80908160642j73568637n2f3fa97fc33d8e57@mail.gmail.com>

Michael Spang a écrit :
> On Sun, Aug 16, 2009 at 8:33 AM, Eric Dumazet<eric.dumazet@gmail.com> wrote:
>> What exactly broke after patch was pushed ?
> 
> The libnl library refuses to initialize with 2.6.30 with pre-2.6.30
> headers. With 2.6.30 I get
> 
>   $ libnl-1.1/src/nl-qdisc-dump brief
>   Unable to retrieve qdisc cache
> 
> whereas previously I would get
> 
>   $ libnl-1.1/src/nl-qdisc-dump brief
>   htb qdisc dev eth0 handle 01: parent root r2q 10000 default :02
> 
> It works fine if I use the headers from 2.6.30, but then I don't
> believe it would work with older kernels.
> 

OK, then we are stuck to use a separate definition for user land
and kernel land, or risk various side effects, like performance hit
and security risk.

Thanks a lot Michael

[PATCH] net: restore gnet_stats_basic to previous definition

In 5e140dfc1fe87eae27846f193086724806b33c7d "net: reorder struct Qdisc
for better SMP performance" the definition of struct gnet_stats_basic
changed incompatibly, as copies of this struct are shipped to
userland via netlink.

Restoring old behavior is not welcome, for performance reason.

Fix is to use a private structure for kernel, and
teach gnet_stats_copy_basic() to convert from kernel to user land,
using legacy structure (struct gnet_stats_basic)

Based on a report and initial patch from Michael Spang.

Reported-by: Michael Spang <mspang@csclub.uwaterloo.ca>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/gen_stats.h          |    5 +++++
 include/net/act_api.h              |    2 +-
 include/net/gen_stats.h            |   10 +++++-----
 include/net/netfilter/xt_rateest.h |    2 +-
 include/net/sch_generic.h          |    2 +-
 net/core/gen_estimator.c           |   12 ++++++------
 net/core/gen_stats.c               |   11 ++++++++---
 net/netfilter/xt_RATEEST.c         |    2 +-
 net/sched/sch_atm.c                |    2 +-
 net/sched/sch_cbq.c                |    2 +-
 net/sched/sch_drr.c                |    2 +-
 net/sched/sch_hfsc.c               |    2 +-
 net/sched/sch_htb.c                |    2 +-
 13 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/include/linux/gen_stats.h b/include/linux/gen_stats.h
index 0ffa41d..710e901 100644
--- a/include/linux/gen_stats.h
+++ b/include/linux/gen_stats.h
@@ -22,6 +22,11 @@ struct gnet_stats_basic
 {
 	__u64	bytes;
 	__u32	packets;
+};
+struct gnet_stats_basic_packed
+{
+	__u64	bytes;
+	__u32	packets;
 } __attribute__ ((packed));
 
 /**
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 565eed8..c05fd71 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -16,7 +16,7 @@ struct tcf_common {
 	u32				tcfc_capab;
 	int				tcfc_action;
 	struct tcf_t			tcfc_tm;
-	struct gnet_stats_basic		tcfc_bstats;
+	struct gnet_stats_basic_packed	tcfc_bstats;
 	struct gnet_stats_queue		tcfc_qstats;
 	struct gnet_stats_rate_est	tcfc_rate_est;
 	spinlock_t			tcfc_lock;
diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h
index d136b52..c148855 100644
--- a/include/net/gen_stats.h
+++ b/include/net/gen_stats.h
@@ -28,7 +28,7 @@ extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type,
 					spinlock_t *lock, struct gnet_dump *d);
 
 extern int gnet_stats_copy_basic(struct gnet_dump *d,
-				 struct gnet_stats_basic *b);
+				 struct gnet_stats_basic_packed *b);
 extern int gnet_stats_copy_rate_est(struct gnet_dump *d,
 				    struct gnet_stats_rate_est *r);
 extern int gnet_stats_copy_queue(struct gnet_dump *d,
@@ -37,14 +37,14 @@ extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
 
 extern int gnet_stats_finish_copy(struct gnet_dump *d);
 
-extern int gen_new_estimator(struct gnet_stats_basic *bstats,
+extern int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
 			     struct gnet_stats_rate_est *rate_est,
 			     spinlock_t *stats_lock, struct nlattr *opt);
-extern void gen_kill_estimator(struct gnet_stats_basic *bstats,
+extern void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
 			       struct gnet_stats_rate_est *rate_est);
-extern int gen_replace_estimator(struct gnet_stats_basic *bstats,
+extern int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,
 				 struct gnet_stats_rate_est *rate_est,
 				 spinlock_t *stats_lock, struct nlattr *opt);
-extern bool gen_estimator_active(const struct gnet_stats_basic *bstats,
+extern bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
 				 const struct gnet_stats_rate_est *rate_est);
 #endif
diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h
index 65d594d..ddbf37e 100644
--- a/include/net/netfilter/xt_rateest.h
+++ b/include/net/netfilter/xt_rateest.h
@@ -8,7 +8,7 @@ struct xt_rateest {
 	spinlock_t			lock;
 	struct gnet_estimator		params;
 	struct gnet_stats_rate_est	rstats;
-	struct gnet_stats_basic		bstats;
+	struct gnet_stats_basic_packed	bstats;
 };
 
 extern struct xt_rateest *xt_rateest_lookup(const char *name);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 964ffa0..5482e95 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -72,7 +72,7 @@ struct Qdisc
 	 */
 	unsigned long		state;
 	struct sk_buff_head	q;
-	struct gnet_stats_basic bstats;
+	struct gnet_stats_basic_packed bstats;
 	struct gnet_stats_queue	qstats;
 };
 
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 78e5bfc..493775f 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -81,7 +81,7 @@
 struct gen_estimator
 {
 	struct list_head	list;
-	struct gnet_stats_basic	*bstats;
+	struct gnet_stats_basic_packed	*bstats;
 	struct gnet_stats_rate_est	*rate_est;
 	spinlock_t		*stats_lock;
 	int			ewma_log;
@@ -165,7 +165,7 @@ static void gen_add_node(struct gen_estimator *est)
 }
 
 static
-struct gen_estimator *gen_find_node(const struct gnet_stats_basic *bstats,
+struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats,
 				    const struct gnet_stats_rate_est *rate_est)
 {
 	struct rb_node *p = est_root.rb_node;
@@ -202,7 +202,7 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic *bstats,
  *
  * NOTE: Called under rtnl_mutex
  */
-int gen_new_estimator(struct gnet_stats_basic *bstats,
+int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
 		      struct gnet_stats_rate_est *rate_est,
 		      spinlock_t *stats_lock,
 		      struct nlattr *opt)
@@ -262,7 +262,7 @@ static void __gen_kill_estimator(struct rcu_head *head)
  *
  * NOTE: Called under rtnl_mutex
  */
-void gen_kill_estimator(struct gnet_stats_basic *bstats,
+void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
 			struct gnet_stats_rate_est *rate_est)
 {
 	struct gen_estimator *e;
@@ -292,7 +292,7 @@ EXPORT_SYMBOL(gen_kill_estimator);
  *
  * Returns 0 on success or a negative error code.
  */
-int gen_replace_estimator(struct gnet_stats_basic *bstats,
+int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,
 			  struct gnet_stats_rate_est *rate_est,
 			  spinlock_t *stats_lock, struct nlattr *opt)
 {
@@ -308,7 +308,7 @@ EXPORT_SYMBOL(gen_replace_estimator);
  *
  * Returns true if estimator is active, and false if not.
  */
-bool gen_estimator_active(const struct gnet_stats_basic *bstats,
+bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
 			  const struct gnet_stats_rate_est *rate_est)
 {
 	ASSERT_RTNL();
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c
index c3d0ffe..8569310 100644
--- a/net/core/gen_stats.c
+++ b/net/core/gen_stats.c
@@ -106,16 +106,21 @@ gnet_stats_start_copy(struct sk_buff *skb, int type, spinlock_t *lock,
  * if the room in the socket buffer was not sufficient.
  */
 int
-gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic *b)
+gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic_packed *b)
 {
 	if (d->compat_tc_stats) {
 		d->tc_stats.bytes = b->bytes;
 		d->tc_stats.packets = b->packets;
 	}
 
-	if (d->tail)
-		return gnet_stats_copy(d, TCA_STATS_BASIC, b, sizeof(*b));
+	if (d->tail) {
+		struct gnet_stats_basic sb;
 
+		memset(&sb, 0, sizeof(sb));
+		sb.bytes = b->bytes;
+		sb.packets = b->packets;
+		return gnet_stats_copy(d, TCA_STATS_BASIC, &sb, sizeof(sb));
+	}
 	return 0;
 }
 
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
index 43f5676..d80b819 100644
--- a/net/netfilter/xt_RATEEST.c
+++ b/net/netfilter/xt_RATEEST.c
@@ -74,7 +74,7 @@ static unsigned int
 xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 	const struct xt_rateest_target_info *info = par->targinfo;
-	struct gnet_stats_basic *stats = &info->est->bstats;
+	struct gnet_stats_basic_packed *stats = &info->est->bstats;
 
 	spin_lock_bh(&info->est->lock);
 	stats->bytes += skb->len;
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 2a8b83a..ab82f14 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -49,7 +49,7 @@ struct atm_flow_data {
 	struct socket		*sock;		/* for closing */
 	u32			classid;	/* x:y type ID */
 	int			ref;		/* reference count */
-	struct gnet_stats_basic	bstats;
+	struct gnet_stats_basic_packed	bstats;
 	struct gnet_stats_queue	qstats;
 	struct atm_flow_data	*next;
 	struct atm_flow_data	*excess;	/* flow for excess traffic;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 23a1676..d5798e1 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -128,7 +128,7 @@ struct cbq_class
 	long			avgidle;
 	long			deficit;	/* Saved deficit for WRR */
 	psched_time_t		penalized;
-	struct gnet_stats_basic bstats;
+	struct gnet_stats_basic_packed bstats;
 	struct gnet_stats_queue qstats;
 	struct gnet_stats_rate_est rate_est;
 	struct tc_cbq_xstats	xstats;
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 7597fe1..12b2fb0 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -22,7 +22,7 @@ struct drr_class {
 	unsigned int			refcnt;
 	unsigned int			filter_cnt;
 
-	struct gnet_stats_basic		bstats;
+	struct gnet_stats_basic_packed		bstats;
 	struct gnet_stats_queue		qstats;
 	struct gnet_stats_rate_est	rate_est;
 	struct list_head		alist;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 362c281..dad0144 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -116,7 +116,7 @@ struct hfsc_class
 	struct Qdisc_class_common cl_common;
 	unsigned int	refcnt;		/* usage count */
 
-	struct gnet_stats_basic bstats;
+	struct gnet_stats_basic_packed bstats;
 	struct gnet_stats_queue qstats;
 	struct gnet_stats_rate_est rate_est;
 	unsigned int	level;		/* class level in hierarchy */
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 88cd026..ec4d463 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -74,7 +74,7 @@ enum htb_cmode {
 struct htb_class {
 	struct Qdisc_class_common common;
 	/* general class parameters */
-	struct gnet_stats_basic bstats;
+	struct gnet_stats_basic_packed bstats;
 	struct gnet_stats_queue qstats;
 	struct gnet_stats_rate_est rate_est;
 	struct tc_htb_xstats xstats;	/* our special stats */

^ permalink raw reply related

* Re: [PATCH] Revert netlink ABI change to gnet_stats_basic
From: Michael Spang @ 2009-08-16 13:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David S. Miller, LKML, Linux Netdev List
In-Reply-To: <4A87FCAC.5070705@gmail.com>

On Sun, Aug 16, 2009 at 8:33 AM, Eric Dumazet<eric.dumazet@gmail.com> wrote:
>
> What exactly broke after patch was pushed ?

The libnl library refuses to initialize with 2.6.30 with pre-2.6.30
headers. With 2.6.30 I get

  $ libnl-1.1/src/nl-qdisc-dump brief
  Unable to retrieve qdisc cache

whereas previously I would get

  $ libnl-1.1/src/nl-qdisc-dump brief
  htb qdisc dev eth0 handle 01: parent root r2q 10000 default :02

It works fine if I use the headers from 2.6.30, but then I don't
believe it would work with older kernels.

Michael

^ permalink raw reply

* Re: [RFC] defer skb allocation in virtio_net -- mergable buff part
From: Avi Kivity @ 2009-08-16 13:47 UTC (permalink / raw)
  To: Shirley Ma; +Cc: netdev, kvm, linux-kernel
In-Reply-To: <1250145231.6653.29.camel@localhost.localdomain>

On 08/13/2009 09:33 AM, Shirley Ma wrote:
> Guest virtio_net receives packets from its pre-allocated vring
> buffers, then it delivers these packets to upper layer protocols
> as skb buffs. So it's not necessary to pre-allocate skb for each
> mergable buffer, then frees it when it's useless.
>
> This patch has deferred skb allocation to when receiving packets,
> it reduces skb pre-allocations and skb_frees. And it induces two
> page list: freed_pages and used_page list, used_pages is used to
> track pages pre-allocated, it is only useful when removing virtio_net.
>
> This patch has tested and measured against 2.6.31-rc4 git,
> I thought this patch will improve large packet performance, but I saw
> netperf TCP_STREAM performance improved for small packet for both
> local guest to host and host to local guest cases. It also reduces
> UDP packets drop rate from host to local guest. I am not fully understand
> why.
>
> The netperf results from my laptop are:
>
> mtu=1500
> netperf -H xxx -l 120
>
> 		w/o patch	w/i patch (two runs)	
> guest to host:  3336.84Mb/s   3730.14Mb/s ~ 3582.88Mb/s
>
> host to guest:  3165.10Mb/s   3370.39Mb/s ~ 3407.96Mb/s
>
> Here is the patch for your review. The same approach can apply to non-mergable
> buffs too, so we can use code in common. If there is no objection, I will
> submit the non-mergable buffs patch later.
>
>
> Signed-off-by: Shirley Ma<xma@us.ibm.com>
> ---
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 2a6e81d..e31ebc9 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -17,6 +17,7 @@
>    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>    */
>   //#define DEBUG
> +#include<linux/list.h>
>   #include<linux/netdevice.h>
>   #include<linux/etherdevice.h>
>   #include<linux/ethtool.h>
> @@ -39,6 +40,12 @@ module_param(gso, bool, 0444);
>
>   #define VIRTNET_SEND_COMMAND_SG_MAX    2
>
> +struct page_list
> +{
> +	struct page *page;
> +	struct list_head list;
> +};
>    

This is an inefficient way to store a list of pages.  Each page requires 
an allocation and a cache line.

Alternatives include:
- store the link in the page itself
- have an array of pages per list element instead of just one pointer
- combine the two, store an array of page pointers in one of the free pages
- use the struct page::lru member

The last is the most traditional and easiest so I'd recommend it (though 
it still takes the cacheline hit).

> +static struct page_list *get_a_free_page(struct virtnet_info *vi, gfp_t gfp_mask)
> +{
> +	struct page_list *plist;
> +
> +	if (list_empty(&vi->freed_pages)) {
> +		plist = kmalloc(sizeof(struct page_list), gfp_mask);
> +		if (!plist)
> +			return NULL;
> +		list_add_tail(&plist->list,&vi->freed_pages);
> +		plist->page = alloc_page(gfp_mask);
>    

What if the allocation fails here?

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply

* Re: [PATCH] Revert netlink ABI change to gnet_stats_basic
From: Eric Dumazet @ 2009-08-16 12:33 UTC (permalink / raw)
  To: Michael Spang; +Cc: David S. Miller, LKML, Linux Netdev List
In-Reply-To: <1250002683-28554-1-git-send-email-mspang@csclub.uwaterloo.ca>

Michael Spang a écrit :
> In 5e140dfc1fe87eae27846f193086724806b33c7d "net: reorder struct Qdisc
> for better SMP performance" the definition of struct gnet_stats_basic
> changed incompatibly, and as copies of this struct may be shipped to
> userland via netlink. This reverts back to the old ABI.

So userland expects to get exactly 16 bytes instead of 12 ?

iproute2 has no problem :

void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats)
{
        SPRINT_BUF(b1);
        struct rtattr *tbs[TCA_STATS_MAX + 1];

        parse_rtattr_nested(tbs, TCA_STATS_MAX, rta);

        if (tbs[TCA_STATS_BASIC]) {
                struct gnet_stats_basic bs = {0};
                memcpy(&bs, RTA_DATA(tbs[TCA_STATS_BASIC]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC]), sizeof(bs)));
                fprintf(fp, "%sSent %llu bytes %u pkt",
                        prefix, (unsigned long long) bs.bytes, bs.packets);
        }


What exactly broke after patch was pushed ?

It would be better to fix gnet_stats_copy_basic() if necessary...


> 
> Signed-off-by: Michael Spang <mspang@csclub.uwaterloo.ca>
> ---
>  include/linux/gen_stats.h |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/include/linux/gen_stats.h b/include/linux/gen_stats.h
> index 0ffa41d..13f4e74 100644
> --- a/include/linux/gen_stats.h
> +++ b/include/linux/gen_stats.h
> @@ -22,7 +22,7 @@ struct gnet_stats_basic
>  {
>  	__u64	bytes;
>  	__u32	packets;
> -} __attribute__ ((packed));
> +};
>  
>  /**
>   * struct gnet_stats_rate_est - rate estimator

^ permalink raw reply

* Re: [PATCH] Pegasus: Add MAC programmability
From: Petko Manolov @ 2009-08-16 12:04 UTC (permalink / raw)
  To: Davide Rizzo; +Cc: linux-usb, netdev, petkan
In-Reply-To: <8447d6730908142318i2a3b8b2fx828e9601f4faea15@mail.gmail.com>

Nope, i don't recall having the eeprom data.  It is not that important 
anyway.  Apart from permanently storing the MAC address in the eeprom, 
write to it should be avoided.

There's no API i know of.  The easiest way to change driver's behavior is 
using driver parameters via modprobe.


 		Petko


On Sat, 15 Aug 2009, Davide Rizzo wrote:

> You're correct.
> Because I produce embedded boards with ADM8515 controller, my purpose
> was to program eeprom in full, without need to pre-program it before
> assemblying the boards.
> Writing MAC in eeprom is already protectected by a #ifdef
> PEGASUS_WRITE_EEPROM (that should be normally disabled, I agree).
> What about protecting the writing of other data with a nested #ifdef
> PEGASUS_WRITE_EEPROM_HEADER ? Do you have eeprom datas for other
> Pegasus chipsets to include in the source ? Or is there any dedicated
> API I don't know about to make this job ?
>
> 2009/8/14  <petkan@nucleusys.com>:
>> Why do you have to write def_eeprom[] to the eeprom along with the new MAC
>> address?  This may work for 8515 based controllers, but will most likely
>> break everything else that antedates it.
>>
>> The set address function should be much smaller/simpler and not writing to
>> the eeprom in general.
>>
>>
>>                  Petko
>>
>>
>>> Added capability to set mac address and to program it into EEPROM
>>>
>>> Signed-off-by: Davide Rizzo <elpa.rizzo@gmail.com>
>>> ---
>>> diff -urNp linux-2.6.30.4/drivers/net/usb/pegasus.c
>>> linux-2.6.30.4.elpa/drivers/net/usb/pegasus.c
>>> --- linux-2.6.30.4/drivers/net/usb/pegasus.c  2009-08-13 07:14:57.000000000
>>> +0200
>>> +++ linux-2.6.30.4.elpa/drivers/net/usb/pegasus.c     2009-08-13
>>> 08:39:01.000000000 +0200
>>> @@ -469,8 +467,49 @@ fail:
>>>               dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
>>>       return -ETIMEDOUT;
>>>  }
>>> +
>>> +/* Got from adm 8515 starter kit */
>>> +static const __u16 def_eeprom[] = {
>>> +                       0x8515, 0x0170, 0x0082, 0x0409, 0x0000,
>>> +     0x07a6, 0x8515, 0x100e, 0x202a, 0x380a, 0x0000, 0x0000, 0x0000,
>>> +     0x030e, 0x0041, 0x0044, 0x004d, 0x0074, 0x0065, 0x006b, 0x0000,
>>> +     0x001e, 0x0055, 0x0053, 0x0042, 0x0020, 0x0031, 0x0030, 0x002f,
>>> +     0x032a, 0x0055, 0x0053, 0x0042, 0x0020, 0x0054, 0x006f, 0x0020,
>>> +     0x004c, 0x0041, 0x004e, 0x0020, 0x0043, 0x006f, 0x006e, 0x0076,
>>> +     0x0065, 0x0072, 0x0074, 0x0065, 0x0072, 0x0000, 0x0000, 0x0000,
>>> +     0x030a, 0x0030, 0x0030, 0x0030, 0x0031, 0x0000, 0x0000, 0x0000,
>>> +};
>>>  #endif                               /* PEGASUS_WRITE_EEPROM */
>>>
>>> +static int pegasus_set_mac_address(struct net_device *netdev, void *p)
>>> +{
>>> +     struct sockaddr *addr = p;
>>> +     pegasus_t *pegasus = (pegasus_t *) netdev_priv(netdev);
>>> +     int i;
>>> +
>>> +     if (netif_running(netdev))
>>> +             return -EBUSY;
>>> +     memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
>>> +     dbg("%s: Setting MAC address to ", netdev->name);
>>> +     for (i = 0; i < 5; i++)
>>> +             dbg("%02X:", netdev->dev_addr[i]);
>>> +     dbg("%02X\n", netdev->dev_addr[i]);
>>> +     /* Set the IDR registers. */
>>> +     set_registers(pegasus, EthID, 6, netdev->dev_addr);
>>> +#ifdef PEGASUS_WRITE_EEPROM
>>> +     write_eprom_word(pegasus, 0,
>>> +             (netdev->dev_addr[1] << 8) + netdev->dev_addr[0]);
>>> +     write_eprom_word(pegasus, 1,
>>> +             (netdev->dev_addr[3] << 8) + netdev->dev_addr[2]);
>>> +     write_eprom_word(pegasus, 2,
>>> +             (netdev->dev_addr[5] << 8) + netdev->dev_addr[4]);
>>> +     for (i = 0; i < ARRAY_SIZE(def_eeprom); i++)
>>> +             write_eprom_word(pegasus, i + 3, def_eeprom[i]);
>>> +
>>> +#endif                         /* PEGASUS_WRITE_EEPROM */
>>> +     return 0;
>>> +}
>>> +
>>>  static inline void get_node_id(pegasus_t * pegasus, __u8 * id)
>>>  {
>>>       int i;
>>> @@ -1492,6 +1531,7 @@ static const struct net_device_ops pegas
>>>       .ndo_start_xmit =               pegasus_start_xmit,
>>>       .ndo_set_multicast_list =       pegasus_set_multicast,
>>>       .ndo_get_stats =                pegasus_netdev_stats,
>>> +     .ndo_set_mac_address =  pegasus_set_mac_address,
>>>       .ndo_tx_timeout =               pegasus_tx_timeout,
>>>       .ndo_change_mtu =               eth_change_mtu,
>>>       .ndo_set_mac_address =          eth_mac_addr,
>>>
>>
>>
>>
>

^ permalink raw reply

* TX on r8169 causes latency and messes up real-time apps, on some boards
From: Andrew Lutomirski @ 2009-08-16 10:39 UTC (permalink / raw)
  To: romieu; +Cc: netdev

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

Hi-

I'm having a bit of a mystery problem.  I have a bunch of identical
machines (Intel D201GLY2A + Trendnet TEG-PCITXR) which all work
wonderfully.

I have four brand-new machines that should be basically identical,
except that they are Intel D201GLY2 boards to which I have attached
fans myself (that's supposed to be the only difference), and for which
I bought the Trendnet TEG-PCITXR cards much later.  On those four new
machines, transmitting with the Trendnet card breaks my real-time app.

These are 2.6.30.1, although I've reproduced the behavior on
2.6.29.something.  All machines in question are running bitwise
identical kernels and userspace.

I've diffed the dmesg results.  The good machines differ only in
BogoMIPS (tiny difference), MAC addresses (obviously), and RTC time.
The difference from good to bad is attached and also shows which r8169
device I have.  (The USB stuff at the bottom is the real-time device
in question.)

The working machines do have a newer BIOS, and the only difference I
see that might make a difference is that the PWM fan control changed,
which might affect SMI latency, but I don't see why this should only
matter when sending data over the network.

Any ideas?  I'm happy to test things.

Thanks,
Andy

[-- Attachment #2: dmesg_diff.txt --]
[-- Type: text/plain, Size: 12991 bytes --]

--- /tmp/c1	2009-08-16 06:28:22.000000000 -0400
+++ /tmp/c16	2009-08-16 06:33:56.000000000 -0400
@@ -6,9 +6,9 @@
  BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
  BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
  BIOS-e820: 00000000000e0000 - 0000000000100000 (reserved)
- BIOS-e820: 0000000000100000 - 000000003ce34000 (usable)
- BIOS-e820: 000000003ce34000 - 000000003d235000 (ACPI NVS)
- BIOS-e820: 000000003d235000 - 000000003ddf2000 (usable)
+ BIOS-e820: 0000000000100000 - 000000003d135000 (usable)
+ BIOS-e820: 000000003d135000 - 000000003d236000 (ACPI NVS)
+ BIOS-e820: 000000003d236000 - 000000003ddf2000 (usable)
  BIOS-e820: 000000003ddf2000 - 000000003ddf4000 (reserved)
  BIOS-e820: 000000003ddf4000 - 000000003de71000 (usable)
  BIOS-e820: 000000003de71000 - 000000003def7000 (ACPI NVS)
@@ -36,18 +36,18 @@
  0000000000 - 003de00000 page 2M
  003de00000 - 003df00000 page 4k
 kernel direct mapping tables up to 3df00000 @ 8000-b000
-RAMDISK: 3c009000 - 3ce13a2d
+RAMDISK: 3c30a000 - 3d114a2d
 ACPI: RSDP 00000000000fe020 00014 (v00 INTEL )
-ACPI: RSDT 000000003defe038 0002C (v01 INTEL  DG965CO  00000086      01000013)
-ACPI: FACP 000000003defd000 00074 (v01 INTEL  DG965CO  00000086 MSFT 01000013)
-ACPI: DSDT 000000003def9000 030F6 (v01 INTEL  DG965CO  00000086 MSFT 01000013)
+ACPI: RSDT 000000003defe038 0002C (v01 INTEL  DG965CO  0000007A      01000013)
+ACPI: FACP 000000003defd000 00074 (v01 INTEL  DG965CO  0000007A MSFT 01000013)
+ACPI: DSDT 000000003def9000 030F6 (v01 INTEL  DG965CO  0000007A MSFT 01000013)
 ACPI: FACS 000000003debc000 00040
-ACPI: APIC 000000003def8000 0006C (v01 INTEL  DG965CO  00000086 MSFT 01000013)
+ACPI: APIC 000000003def8000 0006C (v01 INTEL  DG965CO  0000007A MSFT 01000013)
 ACPI: Local APIC address 0xfee00000
 (6 early reservations) ==> bootmem [0000000000 - 003df00000]
   #0 [0000000000 - 0000001000]   BIOS data page ==> [0000000000 - 0000001000]
   #1 [0000200000 - 0000609808]    TEXT DATA BSS ==> [0000200000 - 0000609808]
-  #2 [003c009000 - 003ce13a2d]          RAMDISK ==> [003c009000 - 003ce13a2d]
+  #2 [003c30a000 - 003d114a2d]          RAMDISK ==> [003c30a000 - 003d114a2d]
   #3 [000009f800 - 0000100000]    BIOS reserved ==> [000009f800 - 0000100000]
   #4 [000060a000 - 000060a140]              BRK ==> [000060a000 - 000060a140]
   #5 [0000008000 - 0000009000]          PGTABLE ==> [0000008000 - 0000009000]
@@ -60,17 +60,17 @@
 Movable zone start PFN for each node
 early_node_map[6] active PFN ranges
     0: 0x00000000 -> 0x0000009f
-    0: 0x00000100 -> 0x0003ce34
-    0: 0x0003d235 -> 0x0003ddf2
+    0: 0x00000100 -> 0x0003d135
+    0: 0x0003d236 -> 0x0003ddf2
     0: 0x0003ddf4 -> 0x0003de71
     0: 0x0003def7 -> 0x0003def8
     0: 0x0003deff -> 0x0003df00
-On node 0 totalpages: 252431
+On node 0 totalpages: 253199
   DMA zone: 56 pages used for memmap
   DMA zone: 1131 pages reserved
   DMA zone: 2812 pages, LIFO batch:0
   DMA32 zone: 3413 pages used for memmap
-  DMA32 zone: 245019 pages, LIFO batch:31
+  DMA32 zone: 245787 pages, LIFO batch:31
 ACPI: PM-Timer IO Port: 0x808
 ACPI: Local APIC address 0xfee00000
 ACPI: LAPIC (acpi_id[0x01] lapic_id[0x00] enabled)
@@ -87,13 +87,13 @@
 Using ACPI (MADT) for SMP configuration information
 nr_irqs_gsi: 24
 Allocating PCI resources starting at 40000000 (gap: 3df00000:c2080000)
-Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 247831
+Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 248599
 Kernel command line: noacpi initrd=cluster-img.gz BOOT_IMAGE=cluster-kernel 
 Initializing CPU#0
 NR_IRQS:288
 PID hash table entries: 4096 (order: 12, 32768 bytes)
 Fast TSC calibration using PIT
-Detected 1200.183 MHz processor.
+Detected 1200.006 MHz processor.
 Console: colour VGA+ 80x25
 console [tty0] enabled
 Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes)
@@ -102,9 +102,9 @@
 AGP bridge at 00:00:00
 Aperture from AGP @ 48000000 old size 32 MB
 Aperture from AGP @ 48000000 size 32 MB (APSIZE f38)
-Memory: 974524k/1014784k available (2251k kernel code, 5060k absent, 34480k reserved, 1026k data, 276k init)
+Memory: 977596k/1014784k available (2251k kernel code, 1988k absent, 34480k reserved, 1026k data, 276k init)
 SLUB: Genslabs=13, HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
-Calibrating delay loop (skipped), value calculated using timer frequency.. 2400.36 BogoMIPS (lpj=4800732)
+Calibrating delay loop (skipped), value calculated using timer frequency.. 2400.01 BogoMIPS (lpj=4800024)
 Mount-cache hash table entries: 256
 CPU: L1 I cache: 32K, L1 D cache: 32K
 CPU: L2 cache: 512K
@@ -125,6 +125,11 @@
 ACPI: No dock devices found.
 ACPI: PCI Root Bridge [PCI0] (0000:00)
 pci 0000:00:00.0: reg 10 32bit mmio: [0x48000000-0x49ffffff]
+pci 0000:00:02.7: reg 10 io port: [0x2200-0x22ff]
+pci 0000:00:02.7: reg 14 io port: [0x2300-0x237f]
+pci 0000:00:02.7: supports D1 D2
+pci 0000:00:02.7: PME# supported from D3hot D3cold
+pci 0000:00:02.7: PME# disabled
 pci 0000:00:03.0: reg 10 32bit mmio: [0x4a104000-0x4a104fff]
 pci 0000:00:03.1: reg 10 32bit mmio: [0x4a103000-0x4a103fff]
 pci 0000:00:03.2: reg 10 32bit mmio: [0x4a102000-0x4a102fff]
@@ -157,34 +162,34 @@
 ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
 ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.P0P1._PRT]
 ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 7 *10 11 12 14 15)
-ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 7 10 *11 12 14 15)
-ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 7 10 11 12 14 15) *0, disabled.
-ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 7 *10 11 12 14 15)
+ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 7 *10 11 12 14 15)
+ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 7 10 *11 12 14 15)
+ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 7 10 *11 12 14 15)
 ACPI: PCI Interrupt Link [LNKE] (IRQs 3 4 5 7 10 *11 12 14 15)
-ACPI: PCI Interrupt Link [LNKF] (IRQs 3 4 5 7 10 *11 12 14 15)
-ACPI: PCI Interrupt Link [LNKG] (IRQs 3 4 5 7 *10 11 12 14 15)
-ACPI: PCI Interrupt Link [LNKH] (IRQs 3 4 5 7 10 *11 12 14 15)
+ACPI: PCI Interrupt Link [LNKF] (IRQs 3 4 5 7 *10 11 12 14 15)
+ACPI: PCI Interrupt Link [LNKG] (IRQs 3 4 5 7 10 *11 12 14 15)
+ACPI: PCI Interrupt Link [LNKH] (IRQs 3 4 5 7 *10 11 12 14 15)
 usbcore: registered new interface driver usbfs
 usbcore: registered new interface driver hub
 usbcore: registered new device driver usb
 PCI: Using ACPI for IRQ routing
 pnp: PnP ACPI init
 ACPI: bus type pnp registered
-pnp: PnP ACPI: found 10 devices
+pnp: PnP ACPI: found 11 devices
 ACPI: ACPI bus type pnp unregistered
-system 00:07: ioport range 0x800-0x8fe has been reserved
-system 00:07: ioport range 0x8ff-0x8ff has been reserved
-system 00:07: ioport range 0x4d0-0x4d1 has been reserved
-system 00:07: ioport range 0x4d6-0x4d6 has been reserved
-system 00:07: ioport range 0x295-0x29e has been reserved
-system 00:07: ioport range 0x2e8-0x2ef has been reserved
-system 00:07: ioport range 0x481-0x48f has been reserved
-system 00:08: iomem range 0x0-0x9ffff could not be reserved
-system 00:08: iomem range 0xec000-0xfffff could not be reserved
-system 00:08: iomem range 0x100000-0x3dffffff could not be reserved
-system 00:08: iomem range 0xe0000000-0xefffffff has been reserved
-system 00:08: iomem range 0xfec00000-0xfec00fff has been reserved
-system 00:08: iomem range 0xfee00000-0xfee00fff has been reserved
+system 00:08: ioport range 0x800-0x8fe has been reserved
+system 00:08: ioport range 0x8ff-0x8ff has been reserved
+system 00:08: ioport range 0x4d0-0x4d1 has been reserved
+system 00:08: ioport range 0x4d6-0x4d6 has been reserved
+system 00:08: ioport range 0x295-0x29e has been reserved
+system 00:08: ioport range 0x2e8-0x2ef has been reserved
+system 00:08: ioport range 0x481-0x48f has been reserved
+system 00:09: iomem range 0x0-0x9ffff could not be reserved
+system 00:09: iomem range 0xec000-0xfffff could not be reserved
+system 00:09: iomem range 0x100000-0x3dffffff could not be reserved
+system 00:09: iomem range 0xe0000000-0xefffffff has been reserved
+system 00:09: iomem range 0xfec00000-0xfec00fff has been reserved
+system 00:09: iomem range 0xfee00000-0xfee00fff has been reserved
 pci 0000:00:01.0: PCI bridge, secondary bus 0000:01
 pci 0000:00:01.0:   IO window: 0x1000-0x1fff
 pci 0000:00:01.0:   MEM window: 0x4a000000-0x4a0fffff
@@ -213,7 +218,7 @@
 Switched to high resolution mode on CPU 0
 Freeing initrd memory: 14378k freed
 HugeTLB registered 2 MB page size, pre-allocated 0 pages
-msgmni has been set to 1932
+msgmni has been set to 1938
 pci 0000:01:00.0: Boot video device
 pcieport-driver 0000:00:1f.0: irq 24 for MSI/MSI-X
 pcieport-driver 0000:00:1f.0: setting latency timer to 64
@@ -230,19 +235,19 @@
 Hangcheck: Using get_cycles().
 Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
 serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
-00:09: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
+00:0a: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
 hwlat_detector: version 1.0.0
 sis900.c: v1.08.10 Apr. 2 2006
 sis900 0000:00:04.0: PCI INT A -> GSI 19 (level, low) -> IRQ 19
 0000:00:04.0: SiS 900 on Foxconn 661 7MI transceiver found at address 1.
 0000:00:04.0: Using transceiver found at address 1 as default
-eth0: SiS 900 PCI Fast Ethernet at 0x2100, IRQ 19, 00:1c:c0:4b:5e:88
+eth0: SiS 900 PCI Fast Ethernet at 0x2100, IRQ 19, 00:1c:c0:6e:11:34
 r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
 r8169 0000:00:06.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
 r8169 0000:00:06.0: no PCI Express capability
-eth1: RTL8169sb/8110sb at 0xffffc2000001a000, 00:14:d1:15:43:37, XID 10000000 IRQ 17
+eth1: RTL8169sb/8110sb at 0xffffc2000001a000, 00:14:d1:17:25:e5, XID 10000000 IRQ 17
 ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
-ehci_hcd 0000:00:03.3: enabling device (0100 -> 0102)
+ehci_hcd 0000:00:03.3: enabling device (0000 -> 0002)
 ehci_hcd 0000:00:03.3: PCI INT D -> GSI 23 (level, low) -> IRQ 23
 ehci_hcd 0000:00:03.3: EHCI Host Controller
 ehci_hcd 0000:00:03.3: new USB bus registered, assigned bus number 1
@@ -257,7 +262,7 @@
 hub 1-0:1.0: USB hub found
 hub 1-0:1.0: 8 ports detected
 ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
-ohci_hcd 0000:00:03.0: enabling device (0100 -> 0102)
+ohci_hcd 0000:00:03.0: enabling device (0000 -> 0002)
 ohci_hcd 0000:00:03.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20
 ohci_hcd 0000:00:03.0: OHCI Host Controller
 ohci_hcd 0000:00:03.0: new USB bus registered, assigned bus number 2
@@ -270,7 +275,7 @@
 usb usb2: configuration #1 chosen from 1 choice
 hub 2-0:1.0: USB hub found
 hub 2-0:1.0: 3 ports detected
-ohci_hcd 0000:00:03.1: enabling device (0100 -> 0102)
+ohci_hcd 0000:00:03.1: enabling device (0000 -> 0002)
 ohci_hcd 0000:00:03.1: PCI INT B -> GSI 21 (level, low) -> IRQ 21
 ohci_hcd 0000:00:03.1: OHCI Host Controller
 ohci_hcd 0000:00:03.1: new USB bus registered, assigned bus number 3
@@ -283,7 +288,7 @@
 usb usb3: configuration #1 chosen from 1 choice
 hub 3-0:1.0: USB hub found
 hub 3-0:1.0: 3 ports detected
-ohci_hcd 0000:00:03.2: enabling device (0100 -> 0102)
+ohci_hcd 0000:00:03.2: enabling device (0000 -> 0002)
 ohci_hcd 0000:00:03.2: PCI INT C -> GSI 22 (level, low) -> IRQ 22
 ohci_hcd 0000:00:03.2: OHCI Host Controller
 ohci_hcd 0000:00:03.2: new USB bus registered, assigned bus number 4
@@ -330,20 +335,21 @@
 NET: Registered protocol family 17
 RPC: Registered udp transport module.
 RPC: Registered tcp transport module.
-rtc_cmos 00:02: setting system clock to 2009-08-16 10:14:59 UTC (1250417699)
+rtc_cmos 00:02: setting system clock to 2009-08-16 18:08:33 UTC (1250446113)
 Freeing unused kernel memory: 276k freed
-usb 1-5: new high speed USB device using ehci_hcd and address 2
-usb 1-5: New USB device found, idVendor=fffe, idProduct=0002
-usb 1-5: New USB device strings: Mfr=0, Product=0, SerialNumber=0
-usb 1-5: configuration #1 chosen from 1 choice
+usb 1-6: new high speed USB device using ehci_hcd and address 2
+usb 1-6: New USB device found, idVendor=fffe, idProduct=0002
+usb 1-6: New USB device strings: Mfr=0, Product=0, SerialNumber=0
+usb 1-6: configuration #1 chosen from 1 choice
 r8169: eth1: link down
 r8169: eth1: link up
 eth0: Media Link On 100mbps full-duplex 
-usb 1-5: USB disconnect, address 2
-usb 1-5: new high speed USB device using ehci_hcd and address 3
-usb 1-5: New USB device found, idVendor=fffe, idProduct=0002
-usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=6
-usb 1-5: Product: USRP Rev 4
-usb 1-5: Manufacturer: Free Software Folks
-usb 1-5: SerialNumber: 48b9995a
-usb 1-5: configuration #1 chosen from 1 choice
+usb 1-6: USB disconnect, address 2
+usb 1-6: new high speed USB device using ehci_hcd and address 3
+usb 1-6: New USB device found, idVendor=fffe, idProduct=0002
+usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=6
+usb 1-6: Product: USRP Rev 4
+usb 1-6: Manufacturer: Free Software Folks
+usb 1-6: SerialNumber: 48b99588
+usb 1-6: configuration #1 chosen from 1 choice
+r8169: eth1: link up

^ permalink raw reply

* Re: System freeze on reboot - general protection fault
From: Eric Dumazet @ 2009-08-16  9:16 UTC (permalink / raw)
  To: Zdenek Kabelac
  Cc: Christoph Lameter, Robin Holt, Linux Kernel Mailing List,
	Pekka Enberg, Jesper Dangaard Brouer, Linux Netdev List,
	Netfilter Developers, Patrick McHardy
In-Reply-To: <c4e36d110908140233v59421ba6y82192b858210370d@mail.gmail.com>

Zdenek Kabelac a écrit :
> 2009/8/13 Zdenek Kabelac <zdenek.kabelac@gmail.com>:
>> 2009/8/13 Christoph Lameter <cl@linux-foundation.org>:
>>> On Thu, 13 Aug 2009, Zdenek Kabelac wrote:
>>>
>>>>> I've added authors of some recent conntrack commits to Cc: - maybe
>>>>> they might know?
>>>> I've tested v2.6.30 - and it's crashing in the same way - so any other
>>>> starting point where slub has the same detection mechanism and
>>>> conntrack module should be working reliable ?
>>> Next point is 2.6.29.
>>>
>> Ok  - played lengthy game between 2.6.29 which appeared to be ok and 2.6.30
>>
>> And the winner is: ea781f197d6a835cbb93a0bf88ee1696296ed8aa
>> netfilter: nf_conntrack: use SLAB_DESTROY_BY_RCU and get rid of call_rcu()
>>
>> The error is actually being hit by  libvirtd networking rules added
>> during boot for my kvm usage.
>> (Which I noticed after some time...  leading my game into wrong
>> direction ;))....
>>
>> Here are the some last bisect entries:
>>
>> git bisect bad 54dc79fe0d895758bdaa1dcf8512d3d21263d105
>> # bad: [5c0de29d06318ec8f6e3ba0d17d62529dbbdc1e8] netfilter:
>> nf_conntrack: add generic function to get len of generic policy
>> git bisect bad 5c0de29d06318ec8f6e3ba0d17d62529dbbdc1e8
>> # good: [e487eb99cf9381a4f8254fa01747a85818da612b] netlink: add nla_policy_len()
>> git bisect good e487eb99cf9381a4f8254fa01747a85818da612b
>> # good: [1f9352ae2253a97b07b34dcf16ffa3b4ca12c558] netfilter:
>> {ip,ip6,arp}_tables: fix incorrect loop detection
>> git bisect good 1f9352ae2253a97b07b34dcf16ffa3b4ca12c558
>> # bad: [2732c4e45bb67006fdc9ae6669be866762711ab5] netfilter:
>> ctnetlink: allocate right-sized ctnetlink skb
>> git bisect bad 2732c4e45bb67006fdc9ae6669be866762711ab5
>>
>>
>> Unfortunately the commit cannot be reverted with current tree - thus I
>> cannot easily check if it's the only problem.
>> (warning: too many files (created: 3096 deleted: 1096), skipping
>> inexact rename detection
>> Automatic revert failed.  After resolving the conflicts,)
> 
> Hmm after checking today with serial cable attached - it looks like
> I've tracked the problem but to the wrong commit - my original 'slub'
> error was now actually something else - so there are most probably two
> kinds of problem - as with this kernel the nf_conntrack_ipv4 fails to
> register tcp so it's not loaded at all.
> This might get fixed later, but different error was there.
> 
> I'll need to play the game again and check when I'll start to get the
> same slub oops/
> 
> Here is the second oops I've got with 2.6.29-rc5 kernel:
> 
> IP: [<ffffffffa02b2c2c>] nf_conntrack_helper_unregister+0x16c/0x320
> [nf_conntrack]
> PGD 13bfb1067 PUD 1384c8067 PMD 0
> Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
> last sysfs file: /sys/module/nf_conntrack_ftp/refcnt
> CPU 0
> Modules linked in: sit tunnel4 nf_defrag_ipv4 bridge stp llc autofs4
> ipv6 nf_conntrack_ftp(-) nf_conntrack binfmt_misc loop dm_mirror
> dm_region_hash dm_log dm_mod kvm_intel kvm i915 drm i2c_algo_bit
> uinput i2c_i801 arc4 ecb cryptomgr aead crypto_blkcipher crypto_hash
> crypto_algapi iwl3945 iwlcore mac80211 video thinkpad_acpi i2c_core
> sr_mod rfkill led_class evdev iTCO_wdt backlight usbhid hid cfg80211
> iTCO_vendor_support e1000e psmouse serio_raw cdrom output rtc_cmos
> rtc_core battery intel_agp nvram rtc_lib button ac uhci_hcd ohci_hcd
> ehci_hcd usbcore [last unloaded: x_tables]
> Pid: 2824, comm: modprobe Not tainted 2.6.29-rc5-00889-gea781f1 #25 6464CTO
> RIP: 0010:[<ffffffffa02b2c2c>]  [<ffffffffa02b2c2c>]
> nf_conntrack_helper_unregister+0x16c/0x320 [nf_conntrack]
> RSP: 0018:ffff88013982fe68  EFLAGS: 00010202
> RAX: 0000000000000200 RBX: 0000000000000001 RCX: ffffffffa02b2b31
> RDX: 00000000000001ff RSI: 8f5c28f5c28f5c29 RDI: 0000000000000001
> RBP: ffff88013982feb8 R08: 0000000000000000 R09: 0000000000000000
> R10: 000000000000006d R11: 0000000000000000 R12: ffffffffa02c6a00
> R13: ffffffffa02c71a0 R14: ffffffff81188e20 R15: ffff88013982fe78
> FS:  00007ffbd4984700(0000) GS:ffffffff8092e040(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> CR2: 0000000000000038 CR3: 000000013779b000 CR4: 00000000000026e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process modprobe (pid: 2824, threadinfo ffff88013982e000, task ffff880138710000)
> Stack:
>  ffff88013982fe88 0000020080271bf2 ffffffff806a47c0 0000000000000246
>  ffff88013982fe98 ffffffffa02c6a00 0000000000000000 ffffffffa02c71a0
>  0000000000000000 000000000040f510 ffff88013982fed8 ffffffffa02c502f
> Call Trace:
>  [<ffffffffa02c502f>] nf_conntrack_ftp_fini+0x2f/0x70 [nf_conntrack_ftp]
>  [<ffffffff8027bcc5>] sys_delete_module+0x1a5/0x270
>  [<ffffffff8020d329>] ? retint_swapgs+0xe/0x13
>  [<ffffffff80271bf2>] ? trace_hardirqs_on_caller+0x162/0x1b0
>  [<ffffffff80292121>] ? audit_syscall_entry+0x191/0x1c0
>  [<ffffffff80526dae>] ? trace_hardirqs_on_thunk+0x3a/0x3f
>  [<ffffffff8020c84b>] system_call_fastpath+0x16/0x1b
> Code: c6 00 00 0f 82 66 ff ff ff 49 8b 9e d8 05 00 00 48 85 db 75 16
> e9 8e 00 00 00 0f 1f 44 00 00 48 85 c0 0f 84 80 00 00 00 48 89 c3 <0f>
> b6 4b 37 48 8b 03 48 8d 14 cd 00 00 00 00 0f 18 08 48 29 ca
> RIP  [<ffffffffa02b2c2c>] nf_conntrack_helper_unregister+0x16c/0x320
> [nf_conntrack]
>  RSP <ffff88013982fe68>
> CR2: 0000000000000038
> ---[ end trace bc3a0ede3d0084db ]---
> 
> Zdenek

Hello Zdenek

I am currently traveling and wont be able to help you before next week.

I added netdev, Patrick, and netfilter-devel in CC so that more eyes can take a look.

Thank you

^ permalink raw reply

* Re: [PATCH v3 3/6] vbus: add a "vbus-proxy" bus model for vbus_driver objects
From: Avi Kivity @ 2009-08-16  8:30 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Gregory Haskins, kvm, alacrityvm-devel, linux-kernel, netdev
In-Reply-To: <20090815103243.GA26749@elte.hu>

On 08/15/2009 01:32 PM, Ingo Molnar wrote:
>> This will generally be used for hypervisors to publish any host-side
>> virtual devices up to a guest.  The guest will have the opportunity
>> to consume any devices present on the vbus-proxy as if they were
>> platform devices, similar to existing buses like PCI.
>>
>>      
> Is there a consensus on this with the KVM folks? (i've added the KVM
> list to the Cc:)
>    

My opinion is that this is a duplication of effort and we'd be better 
off if everyone contributed to enhancing virtio, which already has 
widely deployed guest drivers and non-Linux guest support.

It may have merit if it is proven that it is technically superior to 
virtio (and I don't mean some benchmark in some point in time; I mean 
design wise).  So far I haven't seen any indications that it is.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply

* Re: [PATCH v3 3/6] vbus: add a "vbus-proxy" bus model for vbus_driver objects
From: Ingo Molnar @ 2009-08-16  7:16 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Gregory Haskins, kvm, Avi Kivity, alacrityvm-devel, linux-kernel,
	netdev, Michael S. Tsirkin
In-Reply-To: <4A870964.9090408@codemonkey.ws>


* Anthony Liguori <anthony@codemonkey.ws> wrote:

> Ingo Molnar wrote:
>> * Gregory Haskins <ghaskins@novell.com> wrote:
>>
>>   
>>> This will generally be used for hypervisors to publish any host-side
>>> virtual devices up to a guest.  The guest will have the opportunity
>>> to consume any devices present on the vbus-proxy as if they were
>>> platform devices, similar to existing buses like PCI.
>>>
>>> Signed-off-by: Gregory Haskins <ghaskins@novell.com>
>>> ---
>>>
>>>  MAINTAINERS                 |    6 ++
>>>  arch/x86/Kconfig            |    2 +
>>>  drivers/Makefile            |    1  drivers/vbus/Kconfig        |   
>>> 14 ++++
>>>  drivers/vbus/Makefile       |    3 +
>>>  drivers/vbus/bus-proxy.c    |  152 +++++++++++++++++++++++++++++++++++++++++++
>>>  include/linux/vbus_driver.h |   73 +++++++++++++++++++++
>>>  7 files changed, 251 insertions(+), 0 deletions(-)
>>>  create mode 100644 drivers/vbus/Kconfig
>>>  create mode 100644 drivers/vbus/Makefile
>>>  create mode 100644 drivers/vbus/bus-proxy.c
>>>  create mode 100644 include/linux/vbus_driver.h
>>>     
>>
>> Is there a consensus on this with the KVM folks? (i've added the KVM  
>> list to the Cc:)
>   
> I'll let Avi comment about it from a KVM perspective but from a 
> QEMU perspective, I don't think we want to support two paravirtual 
> IO frameworks.  I'd like to see them converge.  Since there's an 
> install base of guests today with virtio drivers, there really 
> ought to be a compelling reason to change the virtio ABI in a 
> non-backwards compatible way.  This means convergence really ought 
> to be adding features to virtio.

I agree.

While different paravirt drivers are inevitable for things that are 
externally constrained (say support different hypervisors), doing 
different _Linux internal_ paravirt drivers looks plain stupid and 
counter-productive. It splits testing and development.

So either the vbus code replaces virtio (for technical merits such 
as performance and other details), or virtio is enhanced with the 
vbus performance enhancements.

> On paper, I don't think vbus really has any features over virtio.  
> vbus does things in different ways (paravirtual bus vs. pci for 
> discovery) but I think we're happy with how virtio does things 
> today.
>
> I think the reason vbus gets better performance for networking 
> today is that vbus' backends are in the kernel while virtio's 
> backends are currently in userspace.  Since Michael has a 
> functioning in-kernel backend for virtio-net now, I suspect we're 
> weeks (maybe days) away from performance results.  My expectation 
> is that vhost + virtio-net will be as good as venet + vbus.  If 
> that's the case, then I don't see any reason to adopt vbus unless 
> Greg things there are other compelling features over virtio.

Keeping virtio's backend in user-space was rather stupid IMHO. 

Having the _option_ to piggyback to user-space (for flexibility, 
extensibility, etc.) is OK, but not having kernel acceleration is 
bad.

	Ingo

^ permalink raw reply

* Re: [PATCHv3 2/2] vhost_net: a kernel-level virtio server
From: Michael S. Tsirkin @ 2009-08-16  6:51 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: virtualization, netdev, kvm, linux-kernel, mingo, linux-mm, akpm,
	hpa, gregory.haskins
In-Reply-To: <200908141340.36176.arnd@arndb.de>

On Fri, Aug 14, 2009 at 01:40:36PM +0200, Arnd Bergmann wrote:
> On Thursday 13 August 2009, Michael S. Tsirkin wrote:
> > What it is: vhost net is a character device that can be used to reduce
> > the number of system calls involved in virtio networking.
> > Existing virtio net code is used in the guest without modification.
> 
> AFAICT, you have addressed all my comments, mostly by convincing me
> that you got it right anyway ;-).
> 
> I hope this gets into 2.6.32, good work!
> 
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> 
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> 
> One idea though:
> 
> > +	/* Parameter checking */
> > +	if (sock->sk->sk_type != SOCK_RAW) {
> > +		r = -ESOCKTNOSUPPORT;
> > +		goto done;
> > +	}
> > +
> > +	r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa,
> > +			       &uaddr_len, 0);
> > +	if (r)
> > +		goto done;
> > +
> > +	if (uaddr.sa.sll_family != AF_PACKET) {
> > +		r = -EPFNOSUPPORT;
> > +		goto done;
> > +	}
> 
> You currently limit the scope of the driver by only allowing raw packet
> sockets to be passed into the network driver. In qemu, we currently support
> some very similar transports:
> 
> * raw packet (not in a release yet)
> * tcp connection
> * UDP multicast
> * tap character device
> * VDE with Unix local sockets
> 
> My primary interest right now is the tap support, but I think it would
> be interesting in general to allow different file descriptor types
> in vhost_net_set_socket. AFAICT, there are two major differences
> that we need to handle for this:
> 
> * most of the transports are sockets, tap uses a character device.
>   This could be dealt with by having both a struct socket * in
>   struct vhost_net *and* a struct file *, or by always keeping the
>   struct file and calling vfs_readv/vfs_writev for the data transport
>   in both cases.

I am concerned that character devices might have weird side effects with
read/write operations and that calling them from kernel thread the way I
do might have security implications. Can't point at anything specific
though at the moment.
I wonder - can we expose the underlying socket used by tap, or will that
create complex lifetime issues?

> * Each transport has a slightly different header, we have
>   - raw ethernet frames (raw, udp multicast, tap)
>   - 32-bit length + raw frames, possibly fragmented (tcp)
>   - 80-bit header + raw frames, possibly fragmented (tap with vnet_hdr)
>   To handle these three cases, we need either different ioctl numbers
>   so that vhost_net can choose the right one, or a flags field in
>   VHOST_NET_SET_SOCKET, like
> 
>   #define VHOST_NET_RAW		1
>   #define VHOST_NET_LEN_HDR	2
>   #define VHOST_NET_VNET_HDR	4
> 
>   struct vhost_net_socket {
> 	unsigned int flags;
> 	int fd;
>   };
>   #define VHOST_NET_SET_SOCKET _IOW(VHOST_VIRTIO, 0x30, struct vhost_net_socket)

It seems we can query the socket to find out the type, or use the
features ioctl.

> If both of those are addressed, we can treat vhost_net as a generic
> way to do network handling in the kernel independent of the qemu
> model (raw, tap, ...) for it. 
> 
> Your qemu patch would have to work differently, so instead of 
> 
> qemu -net nic,vhost=eth0
> 
> you would do the same as today with the raw packet socket extension
> 
> qemu -net nic -net raw,ifname=eth0 
> 
> Qemu could then automatically try to use vhost_net, if it's available
> in the kernel, or just fall back on software vlan otherwise.
> Does that make sense?
> 
> 	Arnd <>

I agree, long term it should be enabled automatically when possible.

-- 
MST

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ 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