[PATCH v4] af_rxrpc: Keep rxrpc_call pointers in a hashtable
David Howells
dhowells at redhat.com
Mon Mar 3 16:40:27 EST 2014
I need to apply something like the following patch to yours to keep sparse
happy. What do you think?
Compiling with:
make C=1 CF=-D__CHECK_ENDIAN__
After touching ar-call.c should throw up a few errors - mostly off by 3 lines
though.
David
---
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c
index fb55bdb63709..aa4987beac65 100644
--- a/net/rxrpc/ar-call.c
+++ b/net/rxrpc/ar-call.c
@@ -65,11 +65,11 @@ static DEFINE_HASHTABLE(rxrpc_call_hash, 10);
*/
static unsigned long rxrpc_call_hashfunc(
u8 clientflag,
- u32 cid,
+ __be32 cid,
__be32 call_id,
__be32 epoch,
__be16 service_id,
- __be16 proto,
+ sa_family_t proto,
void *localptr,
unsigned int addr_size,
const u8 *peer_addr)
@@ -77,15 +77,19 @@ static unsigned long rxrpc_call_hashfunc(
const u16 *p;
unsigned int i;
unsigned long key;
+ u32 hcid = ntohl(cid);
_enter("");
key = (unsigned long)localptr;
- key += (u32)epoch;
- key += (u16)service_id;
- key += (u32)call_id;
- key += (cid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
- key += cid & RXRPC_CHANNELMASK;
+ /* We just want to add up the __be32 values, so forcing the
+ * cast should be okay.
+ */
+ key += (__force u32)epoch;
+ key += (__force u16)service_id;
+ key += (__force u32)call_id;
+ key += (hcid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
+ key += hcid & RXRPC_CHANNELMASK;
key += clientflag;
key += (u16)proto;
/* Step through the peer address in 16-bit portions for speed */
@@ -114,7 +118,7 @@ static void rxrpc_call_hash_add(struct rxrpc_call *call)
default:
break;
}
- key = rxrpc_call_hashfunc(call->in_clientflag, htonl(call->cid),
+ key = rxrpc_call_hashfunc(call->in_clientflag, call->cid,
call->call_id, call->epoch,
call->service_id, call->proto,
call->conn->trans->local, addr_size,
@@ -150,7 +154,7 @@ struct rxrpc_call *rxrpc_find_call_hash(
__be32 epoch,
__be16 service_id,
void *localptr,
- __be16 proto,
+ sa_family_t proto,
const u8 *peer_addr)
{
unsigned long key;
@@ -170,7 +174,7 @@ struct rxrpc_call *rxrpc_find_call_hash(
break;
}
- key = rxrpc_call_hashfunc(clientflag, htonl(cid), call_id, epoch,
+ key = rxrpc_call_hashfunc(clientflag, cid, call_id, epoch,
service_id, proto, localptr, addr_size,
peer_addr);
hash_for_each_possible_rcu(rxrpc_call_hash, call, hash_node, key) {
@@ -485,9 +489,12 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
parent = *p;
call = rb_entry(parent, struct rxrpc_call, conn_node);
- if (call_id < call->call_id)
+ /* The tree is sorted in order of the __be32 value without
+ * turning it into host order.
+ */
+ if ((__force u32)call_id < (__force u32)call->call_id)
p = &(*p)->rb_left;
- else if (call_id > call->call_id)
+ else if ((__force u32)call_id > (__force u32)call->call_id)
p = &(*p)->rb_right;
else
goto old_call;
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index d583ee9b4fd9..c831d44b0841 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -465,7 +465,7 @@ extern struct list_head rxrpc_calls;
extern rwlock_t rxrpc_call_lock;
struct rxrpc_call *rxrpc_find_call_hash(u8, __be32, __be32, __be32,
- __be16, void *, __be16, const u8 *);
+ __be16, void *, sa_family_t, const u8 *);
struct rxrpc_call *rxrpc_get_client_call(struct rxrpc_sock *,
struct rxrpc_transport *,
struct rxrpc_conn_bundle *,
More information about the linux-afs
mailing list