Message ID | 20091229093023.3ad24786@nehalam |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
Ok - I can also try with VT-D disabled for another data point. On 12/29/2009 12:30 PM, Stephen Hemminger wrote: > There could be DMA problems, either because chip isn't remembering > upper address, or because of lack of wires from chip to memory controller; > there have been problems on motherboards where I/O devices couldn't access > all of memory. > > Try this, it forces each transmit to have full 64 bit address. It drops an > optimization that was done to reduce the number of transmit descriptors > used. > > --- a/drivers/net/sky2.c 2009-12-29 09:23:37.114074275 -0800 > +++ b/drivers/net/sky2.c 2009-12-29 09:26:38.699912035 -0800 > @@ -1038,10 +1038,11 @@ static void tx_init(struct sky2_port *sk > sky2->tx_tcpsum = 0; > sky2->tx_last_mss = 0; > > - le = get_tx_le(sky2,&sky2->tx_prod); > - le->addr = 0; > - le->opcode = OP_ADDR64 | HW_OWNER; > - sky2->tx_last_upper = 0; > + if (sizeof(dma_addr_t) == sizeof(u32)) { > + le = get_tx_le(sky2,&sky2->tx_prod); > + le->addr = 0; > + le->opcode = OP_ADDR64 | HW_OWNER; > + } > } > > /* Update chip's next pointer */ > @@ -1669,10 +1670,9 @@ static netdev_tx_t sky2_xmit_frame(struc > > /* Send high bits if needed */ > upper = upper_32_bits(mapping); > - if (upper != sky2->tx_last_upper) { > + if (sizeof(mapping)> sizeof(u32)) { > le = get_tx_le(sky2,&slot); > le->addr = cpu_to_le32(upper); > - sky2->tx_last_upper = upper; > le->opcode = OP_ADDR64 | HW_OWNER; > } > > @@ -1762,10 +1762,9 @@ static netdev_tx_t sky2_xmit_frame(struc > goto mapping_unwind; > > upper = upper_32_bits(mapping); > - if (upper != sky2->tx_last_upper) { > + if (sizeof(mapping)> sizeof(u32)) { > le = get_tx_le(sky2,&slot); > le->addr = cpu_to_le32(upper); > - sky2->tx_last_upper = upper; > le->opcode = OP_ADDR64 | HW_OWNER; > } > > --- a/drivers/net/sky2.h 2009-12-29 09:23:37.164072886 -0800 > +++ b/drivers/net/sky2.h 2009-12-29 09:25:15.302197993 -0800 > @@ -2191,7 +2191,6 @@ struct sky2_port { > > u16 tx_pending; > u16 tx_last_mss; > - u32 tx_last_upper; > u32 tx_tcpsum; > > struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp; > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
The frequency of the errors is reduced, but in place I'm seeing a large number of DHCPINFORM/DHCPACK to/from the system from which I'm generating load. It appears that it's now taking a higher throughput to cause the interrupt status errors than without this patch, but they're still occurring. Just for fun, I'll try without this patch and with VT-D disabled later today. On 12/29/2009 12:30 PM, Stephen Hemminger wrote: > There could be DMA problems, either because chip isn't remembering > upper address, or because of lack of wires from chip to memory controller; > there have been problems on motherboards where I/O devices couldn't access > all of memory. > > Try this, it forces each transmit to have full 64 bit address. It drops an > optimization that was done to reduce the number of transmit descriptors > used. > > --- a/drivers/net/sky2.c 2009-12-29 09:23:37.114074275 -0800 > +++ b/drivers/net/sky2.c 2009-12-29 09:26:38.699912035 -0800 > @@ -1038,10 +1038,11 @@ static void tx_init(struct sky2_port *sk > sky2->tx_tcpsum = 0; > sky2->tx_last_mss = 0; > > - le = get_tx_le(sky2,&sky2->tx_prod); > - le->addr = 0; > - le->opcode = OP_ADDR64 | HW_OWNER; > - sky2->tx_last_upper = 0; > + if (sizeof(dma_addr_t) == sizeof(u32)) { > + le = get_tx_le(sky2,&sky2->tx_prod); > + le->addr = 0; > + le->opcode = OP_ADDR64 | HW_OWNER; > + } > } > > /* Update chip's next pointer */ > @@ -1669,10 +1670,9 @@ static netdev_tx_t sky2_xmit_frame(struc > > /* Send high bits if needed */ > upper = upper_32_bits(mapping); > - if (upper != sky2->tx_last_upper) { > + if (sizeof(mapping)> sizeof(u32)) { > le = get_tx_le(sky2,&slot); > le->addr = cpu_to_le32(upper); > - sky2->tx_last_upper = upper; > le->opcode = OP_ADDR64 | HW_OWNER; > } > > @@ -1762,10 +1762,9 @@ static netdev_tx_t sky2_xmit_frame(struc > goto mapping_unwind; > > upper = upper_32_bits(mapping); > - if (upper != sky2->tx_last_upper) { > + if (sizeof(mapping)> sizeof(u32)) { > le = get_tx_le(sky2,&slot); > le->addr = cpu_to_le32(upper); > - sky2->tx_last_upper = upper; > le->opcode = OP_ADDR64 | HW_OWNER; > } > > --- a/drivers/net/sky2.h 2009-12-29 09:23:37.164072886 -0800 > +++ b/drivers/net/sky2.h 2009-12-29 09:25:15.302197993 -0800 > @@ -2191,7 +2191,6 @@ struct sky2_port { > > u16 tx_pending; > u16 tx_last_mss; > - u32 tx_last_upper; > u32 tx_tcpsum; > > struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp; > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
One more data point - it appears that the errors are occurring when the interface is under load AND there is ipv6 dns activity. As this only happens when under load I can't prove it, but it seems there is a correlation. > There could be DMA problems, either because chip isn't remembering > upper address, or because of lack of wires from chip to memory controller; > there have been problems on motherboards where I/O devices couldn't access > all of memory. > > Try this, it forces each transmit to have full 64 bit address. It drops an > optimization that was done to reduce the number of transmit descriptors > used. > > --- a/drivers/net/sky2.c 2009-12-29 09:23:37.114074275 -0800 > +++ b/drivers/net/sky2.c 2009-12-29 09:26:38.699912035 -0800 > @@ -1038,10 +1038,11 @@ static void tx_init(struct sky2_port *sk > sky2->tx_tcpsum = 0; > sky2->tx_last_mss = 0; > > - le = get_tx_le(sky2,&sky2->tx_prod); > - le->addr = 0; > - le->opcode = OP_ADDR64 | HW_OWNER; > - sky2->tx_last_upper = 0; > + if (sizeof(dma_addr_t) == sizeof(u32)) { > + le = get_tx_le(sky2,&sky2->tx_prod); > + le->addr = 0; > + le->opcode = OP_ADDR64 | HW_OWNER; > + } > } > > /* Update chip's next pointer */ > @@ -1669,10 +1670,9 @@ static netdev_tx_t sky2_xmit_frame(struc > > /* Send high bits if needed */ > upper = upper_32_bits(mapping); > - if (upper != sky2->tx_last_upper) { > + if (sizeof(mapping)> sizeof(u32)) { > le = get_tx_le(sky2,&slot); > le->addr = cpu_to_le32(upper); > - sky2->tx_last_upper = upper; > le->opcode = OP_ADDR64 | HW_OWNER; > } > > @@ -1762,10 +1762,9 @@ static netdev_tx_t sky2_xmit_frame(struc > goto mapping_unwind; > > upper = upper_32_bits(mapping); > - if (upper != sky2->tx_last_upper) { > + if (sizeof(mapping)> sizeof(u32)) { > le = get_tx_le(sky2,&slot); > le->addr = cpu_to_le32(upper); > - sky2->tx_last_upper = upper; > le->opcode = OP_ADDR64 | HW_OWNER; > } > > --- a/drivers/net/sky2.h 2009-12-29 09:23:37.164072886 -0800 > +++ b/drivers/net/sky2.h 2009-12-29 09:25:15.302197993 -0800 > @@ -2191,7 +2191,6 @@ struct sky2_port { > > u16 tx_pending; > u16 tx_last_mss; > - u32 tx_last_upper; > u32 tx_tcpsum; > > struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp; > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
--- a/drivers/net/sky2.c 2009-12-29 09:23:37.114074275 -0800 +++ b/drivers/net/sky2.c 2009-12-29 09:26:38.699912035 -0800 @@ -1038,10 +1038,11 @@ static void tx_init(struct sky2_port *sk sky2->tx_tcpsum = 0; sky2->tx_last_mss = 0; - le = get_tx_le(sky2, &sky2->tx_prod); - le->addr = 0; - le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_last_upper = 0; + if (sizeof(dma_addr_t) == sizeof(u32)) { + le = get_tx_le(sky2, &sky2->tx_prod); + le->addr = 0; + le->opcode = OP_ADDR64 | HW_OWNER; + } } /* Update chip's next pointer */ @@ -1669,10 +1670,9 @@ static netdev_tx_t sky2_xmit_frame(struc /* Send high bits if needed */ upper = upper_32_bits(mapping); - if (upper != sky2->tx_last_upper) { + if (sizeof(mapping) > sizeof(u32)) { le = get_tx_le(sky2, &slot); le->addr = cpu_to_le32(upper); - sky2->tx_last_upper = upper; le->opcode = OP_ADDR64 | HW_OWNER; } @@ -1762,10 +1762,9 @@ static netdev_tx_t sky2_xmit_frame(struc goto mapping_unwind; upper = upper_32_bits(mapping); - if (upper != sky2->tx_last_upper) { + if (sizeof(mapping) > sizeof(u32)) { le = get_tx_le(sky2, &slot); le->addr = cpu_to_le32(upper); - sky2->tx_last_upper = upper; le->opcode = OP_ADDR64 | HW_OWNER; } --- a/drivers/net/sky2.h 2009-12-29 09:23:37.164072886 -0800 +++ b/drivers/net/sky2.h 2009-12-29 09:25:15.302197993 -0800 @@ -2191,7 +2191,6 @@ struct sky2_port { u16 tx_pending; u16 tx_last_mss; - u32 tx_last_upper; u32 tx_tcpsum; struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp;