[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