Re: [2.3.99-pre3] via-rhine.o and gcc 2.95.2 doesn't get along

From: Urban Widmark (urban@svenskatest.se)
Date: Tue Mar 28 2000 - 04:49:56 EST


On Mon, 27 Mar 2000, Jean-Luc Pedneault wrote:

> I'd like to point out that egcs-1.1.2 executed the code fine even with #if
> 0 (ie. without compiling the additional code). GCC 2.95.2's optimizations
> breaks the code, at least that's what I think.

Me too. But reading all that assembly code makes my head hurt. So instead
of trying to figure out why/where/if gcc 2.95.2 get's the loop wrong,
maybe you could try this patch which should be just a different way of
doing the same thing. Maybe this code is simpler to compile ...

I have not had chance to test this myself, but will this evening (after
installing gcc 2.95.2 to play with). Patch vs 2.3.99-pre3.

Also, generating a smaller (non-kernel) testcase for reporting this to the
gcc people might be a good thing to do, after checking if this is already
known of course. If someone wants to do that let me know, else I'll try
that later ...

/Urban

--- linux/drivers/net/via-rhine.c.orig Tue Mar 28 11:31:03 2000
+++ linux/drivers/net/via-rhine.c Tue Mar 28 11:40:32 2000
@@ -774,6 +774,7 @@
 {
         struct netdev_private *np = (struct netdev_private *)dev->priv;
         int i;
+ dma_addr_t next = np->rx_ring_dma;
 
         np->cur_rx = np->cur_tx = 0;
         np->dirty_rx = np->dirty_tx = 0;
@@ -784,8 +785,8 @@
         for (i = 0; i < RX_RING_SIZE; i++) {
                 np->rx_ring[i].rx_status = 0;
                 np->rx_ring[i].desc_length = cpu_to_le32(np->rx_buf_sz);
- np->rx_ring[i].next_desc =
- cpu_to_le32(np->rx_ring_dma + sizeof(struct rx_desc)*(i+1));
+ next += sizeof(struct rx_desc);
+ np->rx_ring[i].next_desc = cpu_to_le32(next);
                 np->rx_skbuff[i] = 0;
         }
         /* Mark the last entry as wrapping the ring. */
@@ -806,13 +807,15 @@
                 np->rx_ring[i].addr = cpu_to_le32(np->rx_skbuff_dma[i]);
                 np->rx_ring[i].rx_status = cpu_to_le32(DescOwn);
         }
+ np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
+ next = np->tx_ring_dma;
         for (i = 0; i < TX_RING_SIZE; i++) {
                 np->tx_skbuff[i] = 0;
                 np->tx_ring[i].tx_status = 0;
                 np->tx_ring[i].desc_length = cpu_to_le32(0x00e08000);
- np->tx_ring[i].next_desc =
- cpu_to_le32(np->tx_ring_dma + sizeof(struct tx_desc)*(i+1));
+ next += sizeof(struct tx_desc);
+ np->tx_ring[i].next_desc = cpu_to_le32(next);
                 np->tx_buf[i] = kmalloc(PKT_BUF_SZ, GFP_KERNEL);
         }
         np->tx_ring[i-1].next_desc = cpu_to_le32(np->tx_ring_dma);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Mar 31 2000 - 21:00:21 EST