diff mbox

drivers/net/enic/vnic_cq.c

Message ID 20081009.221426.120533568.davem@davemloft.net
State Accepted, archived
Headers show

Commit Message

David Miller Oct. 10, 2008, 5:14 a.m. UTC
I just pushed the following into net-next-2.6:

enic: Attempt to fix build in 32-bit such as i386.

Such platforms lack readq/writeq but this driver want to call them.

Noticed by Andrew Morton.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/enic/vnic_dev.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

Comments

Roland Dreier Oct. 10, 2008, 5:10 p.m. UTC | #1
cc'ing Scott so we can make sure that this actually is atomic enough to
work with the enic hardware... (Scott, the context is that enic won't
build on any architecture that doesn't define writeq and readq, such as
32-bit x86; however the definitions below make it possible that multiple
32-bit writes will be interleaved, eg if an interrupt occurs between the
first writel and the second writel)

 > I just pushed the following into net-next-2.6:
 > 
 > enic: Attempt to fix build in 32-bit such as i386.
 > 
 > Such platforms lack readq/writeq but this driver want to call them.
 > 
 > Noticed by Andrew Morton.
 > 
 > Signed-off-by: David S. Miller <davem@davemloft.net>
 > ---
 >  drivers/net/enic/vnic_dev.h |   14 ++++++++++++++
 >  1 files changed, 14 insertions(+), 0 deletions(-)
 > 
 > diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
 > index 2dcffd3..b9dc182 100644
 > --- a/drivers/net/enic/vnic_dev.h
 > +++ b/drivers/net/enic/vnic_dev.h
 > @@ -27,6 +27,20 @@
 >  #define VNIC_PADDR_TARGET	0x0000000000000000ULL
 >  #endif
 >  
 > +#ifndef readq
 > +static inline u64 readq(void __iomem *reg)
 > +{
 > +	return (((u64)readl(reg + 0x4UL) << 32) |
 > +		(u64)readl(reg));
 > +}
 > +
 > +static inline void writeq(u64 val, void __iomem *reg)
 > +{
 > +	writel(val & 0xffffffff, reg);
 > +	writel(val >> 32, reg + 0x4UL);
 > +}
 > +#endif
 > +
 >  enum vnic_dev_intr_mode {
 >  	VNIC_DEV_INTR_MODE_UNKNOWN,
 >  	VNIC_DEV_INTR_MODE_INTX,
 > -- 
 > 1.5.6.5
 > 
 > --
 > 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
 > 
--
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
Scott Feldman Oct. 10, 2008, 6:29 p.m. UTC | #2
On 10/10/08 10:10 AM, "Roland Dreier" <rdreier@cisco.com> wrote:

> cc'ing Scott so we can make sure that this actually is atomic enough to
> work with the enic hardware... (Scott, the context is that enic won't
> build on any architecture that doesn't define writeq and readq, such as
> 32-bit x86; however the definitions below make it possible that multiple
> 32-bit writes will be interleaved, eg if an interrupt occurs between the
> first writel and the second writel)

Yes, enic hw provides atomic read/write for 64-bit regs even if register is
accessed with 32-bit read/writes.

-scott

--
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
David Miller Oct. 10, 2008, 6:58 p.m. UTC | #3
From: Scott Feldman <sfeldma@nuovasystems.com>
Date: Fri, 10 Oct 2008 11:29:23 -0700

> On 10/10/08 10:10 AM, "Roland Dreier" <rdreier@cisco.com> wrote:
> 
> > cc'ing Scott so we can make sure that this actually is atomic enough to
> > work with the enic hardware... (Scott, the context is that enic won't
> > build on any architecture that doesn't define writeq and readq, such as
> > 32-bit x86; however the definitions below make it possible that multiple
> > 32-bit writes will be interleaved, eg if an interrupt occurs between the
> > first writel and the second writel)
> 
> Yes, enic hw provides atomic read/write for 64-bit regs even if register is
> accessed with 32-bit read/writes.

Sure, and this is why 32-bit arch's don't provide readq/writeq implementations,
things are much more subtle here.

The hardware may allow 2 32-bit writes to a 64-bit register, but...

Are there potential problems when the register is half-way updated?

For example, consider a ring index where the upper and lower 32-bits
are actually significant.  If you change the top part and then the
bottom part, in the intermediate step there is an invalid state and
the card might try to access an invalid ring index.

Then also, of course, the driver itself has to make sure it does
enough locking to make sure a partial 64-bit update isn't interrupted
by a parallel one on another cpu to the same register but I'll assume
the driver takes care of that here :-)
--
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
Scott Feldman Oct. 10, 2008, 10:34 p.m. UTC | #4
On 10/10/08 11:58 AM, "David Miller" <davem@davemloft.net> wrote:

> From: Scott Feldman <sfeldma@nuovasystems.com>
> Date: Fri, 10 Oct 2008 11:29:23 -0700
>> Yes, enic hw provides atomic read/write for 64-bit regs even if register is
>> accessed with 32-bit read/writes.
> 
> Sure, and this is why 32-bit arch's don't provide readq/writeq
> implementations,
> things are much more subtle here.
> 
> The hardware may allow 2 32-bit writes to a 64-bit register, but...
> 
> Are there potential problems when the register is half-way updated?
> 
> For example, consider a ring index where the upper and lower 32-bits
> are actually significant.  If you change the top part and then the
> bottom part, in the intermediate step there is an invalid state and
> the card might try to access an invalid ring index.

Yes, I'd like to retract my original remark.  :(  There is a mechanism for
atomic access to a wide register, but it's not enabled for the register
cases in question, and even if it was, an intermediate access to another
address would invalidate the mechanism, as you point out.  So...
 
> Then also, of course, the driver itself has to make sure it does
> enough locking to make sure a partial 64-bit update isn't interrupted
> by a parallel one on another cpu to the same register but I'll assume
> the driver takes care of that here :-)

...There is enough locking.

-scott

--
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
diff mbox

Patch

diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 2dcffd3..b9dc182 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -27,6 +27,20 @@ 
 #define VNIC_PADDR_TARGET	0x0000000000000000ULL
 #endif
 
+#ifndef readq
+static inline u64 readq(void __iomem *reg)
+{
+	return (((u64)readl(reg + 0x4UL) << 32) |
+		(u64)readl(reg));
+}
+
+static inline void writeq(u64 val, void __iomem *reg)
+{
+	writel(val & 0xffffffff, reg);
+	writel(val >> 32, reg + 0x4UL);
+}
+#endif
+
 enum vnic_dev_intr_mode {
 	VNIC_DEV_INTR_MODE_UNKNOWN,
 	VNIC_DEV_INTR_MODE_INTX,