[RFC][1/2] remove atm_find_ci(); convert vcc_sklist to hash

From: chas williams <hidden>
Date: 2003-10-08 12:46:58

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1435  -> 1.1436 
#	    drivers/atm/he.c	1.28    -> 1.29   
#	   drivers/atm/eni.c	1.29    -> 1.30   
#	      net/atm/proc.c	1.34    -> 1.35   
#	drivers/atm/atmtcp.c	1.25    -> 1.26   
#	 net/atm/signaling.c	1.24    -> 1.25   
#	include/linux/atmdev.h	1.37    -> 1.38   
#	drivers/atm/fore200e.c	1.26    -> 1.27   
#	    net/atm/common.c	1.59    -> 1.60   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/08	chas@relax.cmf.nrl.navy.mil	1.1436
# [ATM]: convert vcc list to hash
# --------------------------------------------
#
diff -Nru a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
--- a/drivers/atm/atmtcp.c	Wed Oct  8 08:29:48 2003
+++ b/drivers/atm/atmtcp.c	Wed Oct  8 08:29:48 2003
@@ -158,6 +158,7 @@
 	struct atm_vcc *vcc;
 	struct hlist_node *node;
 	struct sock *s;
+	int i;
 
 	if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
 	if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT;
@@ -166,14 +167,18 @@
 	if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
 	    ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
 	read_lock(&vcc_sklist_lock);
-	sk_for_each(s, node, &vcc_sklist) {
-		vcc = atm_sk(s);
-		if (vcc->dev != dev)
-			continue;
-		if ((vcc->vpi >> ci.vpi_bits) ||
-		    (vcc->vci >> ci.vci_bits)) {
-			read_unlock(&vcc_sklist_lock);
-			return -EBUSY;
+	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
+		struct hlist_head *head = &vcc_hash[i];
+
+		sk_for_each(s, node, head) {
+			vcc = atm_sk(s);
+			if (vcc->dev != dev)
+				continue;
+			if ((vcc->vpi >> ci.vpi_bits) ||
+			    (vcc->vci >> ci.vci_bits)) {
+				read_unlock(&vcc_sklist_lock);
+				return -EBUSY;
+			}
 		}
 	}
 	read_unlock(&vcc_sklist_lock);
@@ -244,6 +249,7 @@
 	struct sock *s;
 	struct hlist_node *node;
 	struct atm_vcc *walk;
+	int i;
 
 	atmtcp_dev = (struct atm_dev *) vcc->dev_data;
 	dev_data = PRIV(atmtcp_dev);
@@ -254,11 +260,15 @@
 	shutdown_atm_dev(atmtcp_dev);
 	vcc->dev_data = NULL;
 	read_lock(&vcc_sklist_lock);
-	sk_for_each(s, node, &vcc_sklist) {
-		walk = atm_sk(s);
-		if (walk->dev != atmtcp_dev)
-			continue;
-		wake_up(walk->sk->sk_sleep);
+	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
+		struct hlist_head *head = &vcc_hash[i];
+
+		sk_for_each(s, node, head) {
+			walk = atm_sk(s);
+			if (walk->dev != atmtcp_dev)
+				continue;
+			wake_up(walk->sk->sk_sleep);
+		}
 	}
 	read_unlock(&vcc_sklist_lock);
 }
@@ -272,7 +282,7 @@
 	struct hlist_node *node;
 	struct atm_vcc *out_vcc = NULL;
 	struct sk_buff *new_skb;
-	int result = 0;
+	int i, result = 0;
 
 	if (!skb->len) return 0;
 	dev = vcc->dev_data;
@@ -283,14 +293,18 @@
 		goto done;
 	}
 	read_lock(&vcc_sklist_lock);
-	sk_for_each(s, node, &vcc_sklist) {
-		out_vcc = atm_sk(s);
-		if (out_vcc->dev != dev)
-			continue;
-		if (out_vcc->vpi == ntohs(hdr->vpi) &&
-		    out_vcc->vci == ntohs(hdr->vci) &&
-		    out_vcc->qos.rxtp.traffic_class != ATM_NONE)
-			break;
+	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
+		struct hlist_head *head = &vcc_hash[i];
+
+		sk_for_each(s, node, head) {
+			out_vcc = atm_sk(s);
+			if (out_vcc->dev != dev)
+				continue;
+			if (out_vcc->vpi == ntohs(hdr->vpi) &&
+			    out_vcc->vci == ntohs(hdr->vci) &&
+			    out_vcc->qos.rxtp.traffic_class != ATM_NONE)
+				break;
+		}
 	}
 	read_unlock(&vcc_sklist_lock);
 	if (!out_vcc) {
diff -Nru a/drivers/atm/eni.c b/drivers/atm/eni.c
--- a/drivers/atm/eni.c	Wed Oct  8 08:29:48 2003
+++ b/drivers/atm/eni.c	Wed Oct  8 08:29:48 2003
@@ -2147,30 +2147,34 @@
 		    skb_queue_len(&tx->backlog));
 	}
 	read_lock(&vcc_sklist_lock);
-	sk_for_each(s, node, &vcc_sklist) {
-		struct eni_vcc *eni_vcc;
-		int length;
+	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
+		struct hlist_head *head = &vcc_hash[i];
 
-		vcc = atm_sk(s);
-		if (vcc->dev != dev)
-			continue;
-		eni_vcc = ENI_VCC(vcc);
-		if (--left) continue;
-		length = sprintf(page,"vcc %4d: ",vcc->vci);
-		if (eni_vcc->rx) {
-			length += sprintf(page+length,"0x%06lx-0x%06lx "
-			    "(%6ld bytes)",
-			    eni_vcc->recv-eni_dev->ram,
-			    eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1,
-			    eni_vcc->words*4);
-			if (eni_vcc->tx) length += sprintf(page+length,", ");
+		sk_for_each(s, node, head) {
+			struct eni_vcc *eni_vcc;
+			int length;
+
+			vcc = atm_sk(s);
+			if (vcc->dev != dev)
+				continue;
+			eni_vcc = ENI_VCC(vcc);
+			if (--left) continue;
+			length = sprintf(page,"vcc %4d: ",vcc->vci);
+			if (eni_vcc->rx) {
+				length += sprintf(page+length,"0x%06lx-0x%06lx "
+				    "(%6ld bytes)",
+				    eni_vcc->recv-eni_dev->ram,
+				    eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1,
+				    eni_vcc->words*4);
+				if (eni_vcc->tx) length += sprintf(page+length,", ");
+			}
+			if (eni_vcc->tx)
+				length += sprintf(page+length,"tx[%d], txing %d bytes",
+				    eni_vcc->tx->index,eni_vcc->txing);
+			page[length] = '\n';
+			read_unlock(&vcc_sklist_lock);
+			return length+1;
 		}
-		if (eni_vcc->tx)
-			length += sprintf(page+length,"tx[%d], txing %d bytes",
-			    eni_vcc->tx->index,eni_vcc->txing);
-		page[length] = '\n';
-		read_unlock(&vcc_sklist_lock);
-		return length+1;
 	}
 	read_unlock(&vcc_sklist_lock);
 	for (i = 0; i < eni_dev->free_len; i++) {
diff -Nru a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
--- a/drivers/atm/fore200e.c	Wed Oct  8 08:29:48 2003
+++ b/drivers/atm/fore200e.c	Wed Oct  8 08:29:48 2003
@@ -1071,14 +1071,16 @@
     struct sock *s;
     struct atm_vcc* vcc;
     struct hlist_node *node;
+    int i;
 
     read_lock(&vcc_sklist_lock);
-    sk_for_each(s, node, &vcc_sklist) {
+
+    sk_for_each(s, node, &vcc_hash[rpd->atm_header.vci & (VCC_HTABLE_SIZE-1)]) {
 	vcc = atm_sk(s);
 	if (vcc->dev != fore200e->atm_dev)
-		continue;
+	    continue;
 	if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) {
-            read_unlock(&vcc_sklist_lock);
+	    read_unlock(&vcc_sklist_lock);
 	    return vcc;
 	}
     }
@@ -2606,7 +2608,7 @@
     struct sock *s;
     struct hlist_node *node;
     struct fore200e* fore200e  = FORE200E_DEV(dev);
-    int              len, left = *pos;
+    int              i, len, left = *pos;
 
     if (!left--) {
 
@@ -2852,15 +2854,18 @@
 		      " VCCs:\n  address\tVPI.VCI:AAL\t(min/max tx PDU size) (min/max rx PDU size)\n");
 	
 	read_lock(&vcc_sklist_lock);
-	sk_for_each(s, node, &vcc_sklist) {
-	    vcc = atm_sk(s);
+	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
+	    struct hlist_head *head = &vcc_hash[i];
 
-	    if (vcc->dev != fore200e->atm_dev)
+	    sk_for_each(s, node, head) {
+		vcc = atm_sk(s);
+
+		if (vcc->dev != fore200e->atm_dev)
 		    continue;
 
-	    fore200e_vcc = FORE200E_VCC(vcc);
+		fore200e_vcc = FORE200E_VCC(vcc);
 	    
-	    len += sprintf(page + len,
+		len += sprintf(page + len,
 			   "  %x\t%d.%d:%d\t\t(%d/%d)\t(%d/%d)\n",
 			   (u32)(unsigned long)vcc,
 			   vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
@@ -2869,6 +2874,7 @@
 			   fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu,
 			   fore200e_vcc->rx_max_pdu
 		);
+	    }
 	}
 	read_unlock(&vcc_sklist_lock);
 
diff -Nru a/drivers/atm/he.c b/drivers/atm/he.c
--- a/drivers/atm/he.c	Wed Oct  8 08:29:48 2003
+++ b/drivers/atm/he.c	Wed Oct  8 08:29:48 2003
@@ -328,6 +328,7 @@
 static __inline__ struct atm_vcc*
 __find_vcc(struct he_dev *he_dev, unsigned cid)
 {
+	struct hlist_head *head;
 	struct atm_vcc *vcc;
 	struct hlist_node *node;
 	struct sock *s;
@@ -336,8 +337,9 @@
 
 	vpi = cid >> he_dev->vcibits;
 	vci = cid & ((1 << he_dev->vcibits) - 1);
+	head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
 
-	sk_for_each(s, node, &vcc_sklist) {
+	sk_for_each(s, node, head) {
 		vcc = atm_sk(s);
 		if (vcc->dev == he_dev->atm_dev &&
 		    vcc->vci == vci && vcc->vpi == vpi &&
diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h
--- a/include/linux/atmdev.h	Wed Oct  8 08:29:48 2003
+++ b/include/linux/atmdev.h	Wed Oct  8 08:29:48 2003
@@ -380,7 +380,9 @@
 	unsigned long	atm_options;	/* ATM layer options */
 };
 
-extern struct hlist_head vcc_sklist;
+#define VCC_HTABLE_SIZE 32
+
+extern struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
 extern rwlock_t vcc_sklist_lock;
 
 #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
diff -Nru a/net/atm/common.c b/net/atm/common.c
--- a/net/atm/common.c	Wed Oct  8 08:29:48 2003
+++ b/net/atm/common.c	Wed Oct  8 08:29:48 2003
@@ -38,13 +38,16 @@
 #define DPRINTK(format,args...)
 #endif
 
-
-HLIST_HEAD(vcc_sklist);
+struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
 rwlock_t vcc_sklist_lock = RW_LOCK_UNLOCKED;
 
 void __vcc_insert_socket(struct sock *sk)
 {
-	sk_add_node(sk, &vcc_sklist);
+	struct atm_vcc *vcc = atm_sk(sk);
+	struct hlist_head *head = &vcc_hash[vcc->vci &
+					(VCC_HTABLE_SIZE - 1)];
+	sk->sk_hashent = vcc->vci & (VCC_HTABLE_SIZE - 1);
+	sk_add_node(sk, head);
 }
 
 void vcc_insert_socket(struct sock *sk)
@@ -80,7 +83,7 @@
 }
 
 
-EXPORT_SYMBOL(vcc_sklist);
+EXPORT_SYMBOL(vcc_hash);
 EXPORT_SYMBOL(vcc_sklist_lock);
 EXPORT_SYMBOL(vcc_insert_socket);
 EXPORT_SYMBOL(vcc_remove_socket);
@@ -250,11 +253,13 @@
 
 static int check_ci(struct atm_vcc *vcc, short vpi, int vci)
 {
+	struct hlist_head *head = &vcc_hash[vci &
+					(VCC_HTABLE_SIZE - 1)];
 	struct hlist_node *node;
 	struct sock *s;
 	struct atm_vcc *walk;
 
-	sk_for_each(s, node, &vcc_sklist) {
+	sk_for_each(s, node, head) {
 		walk = atm_sk(s);
 		if (walk->dev != vcc->dev)
 			continue;
diff -Nru a/net/atm/proc.c b/net/atm/proc.c
--- a/net/atm/proc.c	Wed Oct  8 08:29:48 2003
+++ b/net/atm/proc.c	Wed Oct  8 08:29:48 2003
@@ -64,6 +64,7 @@
 }
 
 struct vcc_state {
+	int bucket;
 	struct sock *sk;
 	int family;
 };
@@ -75,19 +76,30 @@
 	return !family || (vcc->sk->sk_family == family);
 }
 
-static int __vcc_walk(struct sock **sock, int family, loff_t l)
+static int __vcc_walk(struct sock **sock, int family, int *bucket, loff_t l)
 {
 	struct sock *sk = *sock;
 
 	if (sk == (void *)1) {
-		sk = hlist_empty(&vcc_sklist) ? NULL : __sk_head(&vcc_sklist);
+		for (*bucket = 0; *bucket < VCC_HTABLE_SIZE; ++*bucket) {
+			struct hlist_head *head = &vcc_hash[*bucket];
+
+			sk = hlist_empty(head) ? NULL : __sk_head(head);
+			if (sk)
+				break;
+		}
 		l--;
 	} 
+try_again:
 	for (; sk; sk = sk_next(sk)) {
 		l -= compare_family(sk, family);
 		if (l < 0)
 			goto out;
 	}
+	if (!sk && ++*bucket < VCC_HTABLE_SIZE) {
+		sk = sk_head(&vcc_hash[*bucket]);
+		goto try_again;
+	}
 	sk = (void *)1;
 out:
 	*sock = sk;
@@ -96,7 +108,7 @@
 
 static inline void *vcc_walk(struct vcc_state *state, loff_t l)
 {
-	return __vcc_walk(&state->sk, state->family, l) ?
+	return __vcc_walk(&state->sk, state->family, &state->bucket, l) ?
 	       state : NULL;
 }
 
@@ -207,9 +219,10 @@
 		default:
 			seq_printf(seq, "%3d", vcc->sk->sk_family);
 	}
-	seq_printf(seq, " %04lx  %5d %7d/%7d %7d/%7d\n", vcc->flags, vcc->sk->sk_err,
+	seq_printf(seq, " %04lx  %5d %7d/%7d %7d/%7d [%d] 0x%x\n", vcc->flags, vcc->sk->sk_err,
 		atomic_read(&vcc->sk->sk_wmem_alloc),vcc->sk->sk_sndbuf,
-		atomic_read(&vcc->sk->sk_rmem_alloc),vcc->sk->sk_rcvbuf);
+		atomic_read(&vcc->sk->sk_rmem_alloc),vcc->sk->sk_rcvbuf,
+		atomic_read(&vcc->sk->sk_refcnt), vcc->sk->sk_hashent);
 }
 
 static void svc_info(struct seq_file *seq, struct atm_vcc *vcc)
diff -Nru a/net/atm/signaling.c b/net/atm/signaling.c
--- a/net/atm/signaling.c	Wed Oct  8 08:29:48 2003
+++ b/net/atm/signaling.c	Wed Oct  8 08:29:48 2003
@@ -216,6 +216,7 @@
 {
 	struct hlist_node *node;
 	struct sock *s;
+	int i;
 
 	DPRINTK("sigd_close\n");
 	sigd = NULL;
@@ -224,11 +225,15 @@
 	skb_queue_purge(&vcc->sk->sk_receive_queue);
 
 	read_lock(&vcc_sklist_lock);
-	sk_for_each(s, node, &vcc_sklist) {
-		struct atm_vcc *vcc = atm_sk(s);
+	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
+		struct hlist_head *head = &vcc_hash[i];
 
-		if (vcc->dev)
-			purge_vcc(vcc);
+		sk_for_each(s, node, head) {
+			struct atm_vcc *vcc = atm_sk(s);
+
+			if (vcc->dev)
+				purge_vcc(vcc);
+		}
 	}
 	read_unlock(&vcc_sklist_lock);
 }
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help