summaryrefslogtreecommitdiff
path: root/drivers/net/iseries_veth.c
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-09-01 11:29:06 +1000
committerJeff Garzik <jgarzik@pobox.com>2005-08-31 22:39:43 -0400
commitb08bd5c0a3110f143faeef9cd057d9d8ff2f0714 (patch)
treeee9e8d2e5457a2bb06d301b528203fca2c4db18e /drivers/net/iseries_veth.c
parentd7893ddd1b2110a54a5b1773a405748172ba1fe5 (diff)
downloadlwn-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.c13
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];