diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-09-01 11:29:06 +1000 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-31 22:39:43 -0400 |
commit | b08bd5c0a3110f143faeef9cd057d9d8ff2f0714 (patch) | |
tree | ee9e8d2e5457a2bb06d301b528203fca2c4db18e /drivers/net/iseries_veth.c | |
parent | d7893ddd1b2110a54a5b1773a405748172ba1fe5 (diff) | |
download | lwn-b08bd5c0a3110f143faeef9cd057d9d8ff2f0714.tar.gz lwn-b08bd5c0a3110f143faeef9cd057d9d8ff2f0714.zip |
[PATCH] iseries_veth: Replace lock-protected atomic with an ordinary variable
The iseries_veth driver uses atomic ops to manipulate the in_use field of
one of its per-connection structures. However all references to the
flag occur while the connection's lock is held, so the atomic ops aren't
necessary.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/iseries_veth.c')
-rw-r--r-- | drivers/net/iseries_veth.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 231b2d2d3264..427ac8cc56be 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -117,7 +117,7 @@ struct veth_msg { struct veth_msg *next; struct VethFramesData data; int token; - unsigned long in_use; + int in_use; struct sk_buff *skb; struct device *dev; }; @@ -957,6 +957,8 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, goto drop; } + msg->in_use = 1; + dma_length = skb->len; dma_address = dma_map_single(port->dev, skb->data, dma_length, DMA_TO_DEVICE); @@ -971,7 +973,6 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, msg->data.addr[0] = dma_address; msg->data.len[0] = dma_length; msg->data.eofmask = 1 << VETH_EOF_SHIFT; - set_bit(0, &(msg->in_use)); rc = veth_signaldata(cnx, VethEventTypeFrames, msg->token, &msg->data); if (rc != HvLpEvent_Rc_Good) @@ -981,10 +982,8 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, return 0; recycle_and_drop: + /* we free the skb below, so tell veth_recycle_msg() not to. */ msg->skb = NULL; - /* need to set in use to make veth_recycle_msg in case this - * was a mapping failure */ - set_bit(0, &msg->in_use); veth_recycle_msg(cnx, msg); drop: port->stats.tx_errors++; @@ -1066,12 +1065,14 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } +/* You must hold the connection's lock when you call this function. */ static void veth_recycle_msg(struct veth_lpar_connection *cnx, struct veth_msg *msg) { u32 dma_address, dma_length; - if (test_and_clear_bit(0, &msg->in_use)) { + if (msg->in_use) { + msg->in_use = 0; dma_address = msg->data.addr[0]; dma_length = msg->data.len[0]; |