6507173 Sockets should allocate minor numbers from higher order arena
authorgt145670
Fri, 11 Jan 2008 12:54:58 -0800
changeset 5815 837c8cd4d6b6
parent 5814 7d97ece0b3d4
child 5816 81ccb6927d98
6507173 Sockets should allocate minor numbers from higher order arena
usr/src/uts/common/inet/common.h
usr/src/uts/common/inet/inet_common.c
usr/src/uts/common/inet/ip.h
usr/src/uts/common/inet/ip/icmp.c
usr/src/uts/common/inet/ip/ip.c
usr/src/uts/common/inet/ip/rts.c
usr/src/uts/common/inet/ipclassifier.h
usr/src/uts/common/inet/mi.c
usr/src/uts/common/inet/sctp/sctp_ioc.c
usr/src/uts/common/inet/tcp/tcp.c
usr/src/uts/common/inet/udp/udp.c
usr/src/uts/intel/ip/ip.global-objs.debug64
usr/src/uts/intel/ip/ip.global-objs.obj64
usr/src/uts/sparc/ip/ip.global-objs.debug64
usr/src/uts/sparc/ip/ip.global-objs.obj64
--- a/usr/src/uts/common/inet/common.h	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/common.h	Fri Jan 11 12:54:58 2008 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -41,6 +40,7 @@
 
 #include <sys/inttypes.h>
 #include <sys/sysmacros.h>
+#include <sys/mkdev.h>
 
 #define	A_CNT(arr)	(sizeof (arr) / sizeof (arr[0]))
 #define	A_END(arr)	(&arr[A_CNT(arr)])
@@ -94,12 +94,11 @@
 #endif
 
 #define	INET_MIN_DEV		2	/* minimum minor device number */
-#define	INET_MAXMINOR		MAXMIN	/* maximum device minor number */
 
 #ifdef _KERNEL
 #include <sys/stream.h>
 
-extern void *inet_minor_create(char *, dev_t, int);
+extern void *inet_minor_create(char *, dev_t, dev_t, int);
 extern void inet_minor_destroy(void *);
 extern dev_t inet_minor_alloc(void *);
 extern void inet_minor_free(void *, dev_t);
--- a/usr/src/uts/common/inet/inet_common.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/inet_common.c	Fri Jan 11 12:54:58 2008 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -44,16 +43,13 @@
 	minor_t ineta_maxminor;	/* max minor number in the arena */
 } inet_arena_t;
 
-/* Maximum minor number to use */
-static minor_t inet_maxminor = INET_MAXMINOR;
-
 void *
-inet_minor_create(char *name, dev_t min_dev, int kmflags)
+inet_minor_create(char *name, dev_t min_dev, dev_t max_dev, int kmflags)
 {
 	inet_arena_t *arena = kmem_alloc(sizeof (inet_arena_t), kmflags);
 
 	if (arena != NULL) {
-		arena->ineta_maxminor = MIN(MAXMIN32, inet_maxminor);
+		arena->ineta_maxminor = max_dev;
 		arena->ineta_arena = vmem_create(name,
 		    (void *)min_dev, arena->ineta_maxminor - min_dev + 1,
 		    1, NULL, NULL, NULL, 1, kmflags | VMC_IDENTIFIER);
@@ -79,29 +75,17 @@
 }
 
 dev_t
-inet_minor_alloc(void *a)
+inet_minor_alloc(void *arena)
 {
-	inet_arena_t *arena = (inet_arena_t *)a;
-	dev_t dev;
-
-	while ((dev = (dev_t)vmem_alloc(arena->ineta_arena, 1,
-		    VM_NOSLEEP)) == 0) {
-		if (arena->ineta_maxminor >= inet_maxminor)
-			return (0);
-		if (vmem_add(arena->ineta_arena,
-		    (void *)(uintptr_t)(arena->ineta_maxminor + 1),
-		    inet_maxminor - arena->ineta_maxminor, VM_NOSLEEP) == NULL)
-			return (0);
-		arena->ineta_maxminor = inet_maxminor;
-	}
-	return (dev);
+	return ((dev_t)vmem_alloc(((inet_arena_t *)arena)->ineta_arena,
+	    1, VM_NOSLEEP));
 }
 
 void
-inet_minor_free(void *a, dev_t dev)
+inet_minor_free(void *arena, dev_t dev)
 {
-	ASSERT((dev != OPENFAIL) && (dev != 0) && (dev <= inet_maxminor));
-	vmem_free(((inet_arena_t *)a)->ineta_arena, (void *)dev, 1);
+	ASSERT((dev != OPENFAIL) && (dev != 0) && (dev <= MAXMIN));
+	vmem_free(((inet_arena_t *)arena)->ineta_arena, (void *)dev, 1);
 }
 
 /*
--- a/usr/src/uts/common/inet/ip.h	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/ip.h	Fri Jan 11 12:54:58 2008 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -2803,7 +2803,8 @@
 
 extern	uint_t	ip_loopback_mtu;	/* /etc/system */
 
-extern vmem_t *ip_minor_arena;
+extern vmem_t *ip_minor_arena_sa;
+extern vmem_t *ip_minor_arena_la;
 
 /*
  * ip_g_forward controls IP forwarding.  It takes two values:
--- a/usr/src/uts/common/inet/ip/icmp.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/ip/icmp.c	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -781,7 +781,7 @@
 	 */
 	ASSERT(connp->conn_ref == 1);
 
-	inet_minor_free(ip_minor_arena, connp->conn_dev);
+	inet_minor_free(connp->conn_minor_arena, connp->conn_dev);
 
 	connp->conn_ref--;
 	ipcl_conn_destroy(connp);
@@ -1491,7 +1491,11 @@
 	else
 		zoneid = crgetzoneid(credp);
 
-	if ((conn_dev = inet_minor_alloc(ip_minor_arena)) == 0) {
+	/*
+	 * Since ICMP is not used so heavily, allocating from the small
+	 * arena should be sufficient.
+	 */
+	if ((conn_dev = inet_minor_alloc(ip_minor_arena_sa)) == 0) {
 		netstack_rele(ns);
 		return (EBUSY);
 	}
@@ -1499,6 +1503,7 @@
 
 	connp = ipcl_conn_create(IPCL_RAWIPCONN, KM_SLEEP, ns);
 	connp->conn_dev = conn_dev;
+	connp->conn_minor_arena = ip_minor_arena_sa;
 	icmp = connp->conn_icmp;
 
 	/*
--- a/usr/src/uts/common/inet/ip/ip.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/ip/ip.c	Fri Jan 11 12:54:58 2008 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -785,7 +785,8 @@
 static long ip_rput_pullups;
 int	dohwcksum = 1;	/* use h/w cksum if supported by the hardware */
 
-vmem_t *ip_minor_arena;
+vmem_t *ip_minor_arena_sa; /* for minor nos. from INET_MIN_DEV+2 thru 2^^18-1 */
+vmem_t *ip_minor_arena_la; /* for minor nos. from 2^^18 thru 2^^32-1 */
 
 int	ip_debug;
 
@@ -5628,7 +5629,7 @@
 	 */
 	ASSERT(connp->conn_ref == 1);
 
-	inet_minor_free(ip_minor_arena, connp->conn_dev);
+	inet_minor_free(connp->conn_minor_arena, connp->conn_dev);
 
 	connp->conn_ref--;
 	ipcl_conn_destroy(connp);
@@ -5694,7 +5695,10 @@
 	ipcl_g_destroy();
 	ip_net_g_destroy();
 	ip_ire_g_fini();
-	inet_minor_destroy(ip_minor_arena);
+	inet_minor_destroy(ip_minor_arena_sa);
+#if defined(_LP64)
+	inet_minor_destroy(ip_minor_arena_la);
+#endif
 
 #ifdef DEBUG
 	list_destroy(&ip_thread_list);
@@ -5861,12 +5865,31 @@
 	 * For IP and TCP the minor numbers should start from 2 since we have 4
 	 * initial devices: ip, ip6, tcp, tcp6.
 	 */
-	if ((ip_minor_arena = inet_minor_create("ip_minor_arena",
-	    INET_MIN_DEV + 2, KM_SLEEP)) == NULL) {
+	/*
+	 * If this is a 64-bit kernel, then create two separate arenas -
+	 * one for TLIs in the range of INET_MIN_DEV+2 through 2^^18-1, and the
+	 * other for socket apps in the range 2^^18 through 2^^32-1.
+	 */
+	ip_minor_arena_la = NULL;
+	ip_minor_arena_sa = NULL;
+#if defined(_LP64)
+	if ((ip_minor_arena_sa = inet_minor_create("ip_minor_arena_sa",
+	    INET_MIN_DEV + 2, MAXMIN32, KM_SLEEP)) == NULL) {
 		cmn_err(CE_PANIC,
-		    "ip_ddi_init: ip_minor_arena creation failed\n");
-	}
-
+		    "ip_ddi_init: ip_minor_arena_sa creation failed\n");
+	}
+	if ((ip_minor_arena_la = inet_minor_create("ip_minor_arena_la",
+	    MAXMIN32 + 1, MAXMIN64, KM_SLEEP)) == NULL) {
+		cmn_err(CE_PANIC,
+		    "ip_ddi_init: ip_minor_arena_la creation failed\n");
+	}
+#else
+	if ((ip_minor_arena_sa = inet_minor_create("ip_minor_arena_sa",
+	    INET_MIN_DEV + 2, MAXMIN, KM_SLEEP)) == NULL) {
+		cmn_err(CE_PANIC,
+		    "ip_ddi_init: ip_minor_arena_sa creation failed\n");
+	}
+#endif
 	ip_poll_normal_ticks = MSEC_TO_TICK_ROUNDUP(ip_poll_normal_ms);
 
 	ipcl_g_init();
@@ -9847,11 +9870,23 @@
 		connp->conn_pkt_isv6 = B_FALSE;
 	}
 
-	if ((connp->conn_dev = inet_minor_alloc(ip_minor_arena)) == 0) {
-		/* CONN_DEC_REF takes care of netstack_rele() */
-		q->q_ptr = WR(q)->q_ptr = NULL;
-		CONN_DEC_REF(connp);
-		return (EBUSY);
+	if ((ip_minor_arena_la != NULL) && (flag & SO_SOCKSTR) &&
+	    ((connp->conn_dev = inet_minor_alloc(ip_minor_arena_la)) != 0)) {
+		connp->conn_minor_arena = ip_minor_arena_la;
+	} else {
+		/*
+		 * Either minor numbers in the large arena were exhausted
+		 * or a non socket application is doing the open.
+		 * Try to allocate from the small arena.
+		 */
+		if ((connp->conn_dev =
+		    inet_minor_alloc(ip_minor_arena_sa)) == 0) {
+			/* CONN_DEC_REF takes care of netstack_rele() */
+			q->q_ptr = WR(q)->q_ptr = NULL;
+			CONN_DEC_REF(connp);
+			return (EBUSY);
+		}
+		connp->conn_minor_arena = ip_minor_arena_sa;
 	}
 
 	maj = getemajor(*devp);
--- a/usr/src/uts/common/inet/ip/rts.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/ip/rts.c	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -225,7 +225,7 @@
 	 */
 	ASSERT(connp->conn_ref == 1);
 
-	inet_minor_free(ip_minor_arena, connp->conn_dev);
+	inet_minor_free(connp->conn_minor_arena, connp->conn_dev);
 
 	connp->conn_ref--;
 	ipcl_conn_destroy(connp);
@@ -270,7 +270,11 @@
 	else
 		zoneid = crgetzoneid(credp);
 
-	if ((conn_dev = inet_minor_alloc(ip_minor_arena)) == 0) {
+	/*
+	 * Since RTS is not used so heavily, allocating from the small
+	 * arena should be sufficient.
+	 */
+	if ((conn_dev = inet_minor_alloc(ip_minor_arena_sa)) == 0) {
 		netstack_rele(ns);
 		return (EBUSY);
 	}
@@ -278,6 +282,7 @@
 
 	connp = ipcl_conn_create(IPCL_RTSCONN, KM_SLEEP, ns);
 	connp->conn_dev = conn_dev;
+	connp->conn_minor_arena = ip_minor_arena_sa;
 	rts = connp->conn_rts;
 
 	/*
--- a/usr/src/uts/common/inet/ipclassifier.h	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/ipclassifier.h	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -234,6 +234,7 @@
 	queue_t		*conn_rq;		/* Read queue */
 	queue_t		*conn_wq;		/* Write queue */
 	dev_t		conn_dev;		/* Minor number */
+	vmem_t		*conn_minor_arena;	/* Minor arena */
 
 	cred_t		*conn_cred;		/* Credentials */
 	connf_t		*conn_g_fanout;		/* Global Hash bucket head */
--- a/usr/src/uts/common/inet/mi.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/mi.c	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -830,7 +830,7 @@
 		mi_head->mh_o.mi_o_prev = &mi_head->mh_o;
 		mi_head->mh_o.mi_o_dev = 0;	/* For asserts only */
 		mi_head->mh_arena = (vmem_t *)inet_minor_create(arena_name,
-		    INET_MIN_DEV, KM_SLEEP);
+		    INET_MIN_DEV, MAXMIN, KM_SLEEP);
 	}
 	ASSERT(ptr != NULL);
 	mi_o = (MI_OP)ptr;
@@ -1513,7 +1513,7 @@
 		mi_tpi_addr_and_opt(mp, src, src_length, opt, opt_length);
 		((struct T_extconn_ind *)mp->b_rptr)->DEST_length = dst_length;
 		((struct T_extconn_ind *)mp->b_rptr)->DEST_offset =
-			(t_scalar_t)(mp->b_wptr - mp->b_rptr);
+		    (t_scalar_t)(mp->b_wptr - mp->b_rptr);
 		if (dst_length > 0) {
 			bcopy(dst, (char *)mp->b_wptr, dst_length);
 			mp->b_wptr += dst_length;
--- a/usr/src/uts/common/inet/sctp/sctp_ioc.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/sctp/sctp_ioc.c	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -189,7 +189,7 @@
 
 	ASSERT(connp->conn_ref == 1);
 
-	inet_minor_free(ip_minor_arena, connp->conn_dev);
+	inet_minor_free(connp->conn_minor_arena, connp->conn_dev);
 
 	q->q_ptr = WR(q)->q_ptr = NULL;
 	CONN_DEC_REF(connp);
@@ -244,11 +244,22 @@
 	connp->conn_wq = WR(q);
 	q->q_ptr = WR(q)->q_ptr = connp;
 
-	if ((connp->conn_dev = inet_minor_alloc(ip_minor_arena)) == 0) {
-		/* CONN_DEC_REF takes care of netstack_rele() */
-		q->q_ptr = WR(q)->q_ptr = NULL;
-		CONN_DEC_REF(connp);
-		return (EBUSY);
+	if ((ip_minor_arena_la != NULL) &&
+	    (connp->conn_dev = inet_minor_alloc(ip_minor_arena_la)) != 0) {
+		connp->conn_minor_arena = ip_minor_arena_la;
+	} else {
+		/*
+		 * Minor numbers in the large arena are exhausted.
+		 * Try to allocate from the small arena.
+		 */
+		if ((connp->conn_dev = inet_minor_alloc(ip_minor_arena_sa))
+		    == 0) {
+			/* CONN_DEC_REF takes care of netstack_rele() */
+			q->q_ptr = WR(q)->q_ptr = NULL;
+			CONN_DEC_REF(connp);
+			return (EBUSY);
+		}
+		connp->conn_minor_arena = ip_minor_arena_sa;
 	}
 
 	maj = getemajor(*devp);
--- a/usr/src/uts/common/inet/tcp/tcp.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/tcp/tcp.c	Fri Jan 11 12:54:58 2008 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -2428,6 +2428,8 @@
 	ASSERT(eager->tcp_ack_tid == 0);
 
 	econnp->conn_dev = aconnp->conn_dev;
+	econnp->conn_minor_arena = aconnp->conn_minor_arena;
+	ASSERT(econnp->conn_minor_arena != NULL);
 	if (eager->tcp_cred != NULL)
 		crfree(eager->tcp_cred);
 	eager->tcp_cred = econnp->conn_cred = aconnp->conn_cred;
@@ -4101,7 +4103,7 @@
 		conn_ioctl_cleanup(connp);
 
 	qprocsoff(q);
-	inet_minor_free(ip_minor_arena, connp->conn_dev);
+	inet_minor_free(connp->conn_minor_arena, connp->conn_dev);
 
 	tcp->tcp_cpid = -1;
 
@@ -4125,6 +4127,9 @@
 static int
 tcpclose_accept(queue_t *q)
 {
+	vmem_t	*minor_arena;
+	dev_t	conn_dev;
+
 	ASSERT(WR(q)->q_qinfo == &tcp_acceptor_winit);
 
 	/*
@@ -4132,7 +4137,12 @@
 	 * now being closed due to some error.
 	 */
 	qprocsoff(q);
-	inet_minor_free(ip_minor_arena, (dev_t)q->q_ptr);
+
+	minor_arena = (vmem_t *)WR(q)->q_ptr;
+	conn_dev = (dev_t)RD(q)->q_ptr;
+	ASSERT(minor_arena != NULL);
+	ASSERT(conn_dev != 0);
+	inet_minor_free(minor_arena, conn_dev);
 	q->q_ptr = WR(q)->q_ptr = NULL;
 	return (0);
 }
@@ -9614,6 +9624,7 @@
 	tcp_t		*tcp = NULL;
 	conn_t		*connp;
 	int		err;
+	vmem_t		*minor_arena = NULL;
 	dev_t		conn_dev;
 	zoneid_t	zoneid;
 	tcp_stack_t	*tcps = NULL;
@@ -9664,11 +9675,23 @@
 		}
 	}
 
-	if ((conn_dev = inet_minor_alloc(ip_minor_arena)) == 0) {
-		if (tcps != NULL)
-			netstack_rele(tcps->tcps_netstack);
-		return (EBUSY);
-	}
+	if ((ip_minor_arena_la != NULL) && (flag & SO_SOCKSTR) &&
+	    ((conn_dev = inet_minor_alloc(ip_minor_arena_la)) != 0)) {
+		minor_arena = ip_minor_arena_la;
+	} else {
+		/*
+		 * Either minor numbers in the large arena were exhausted
+		 * or a non socket application is doing the open.
+		 * Try to allocate from the small arena.
+		 */
+		if ((conn_dev = inet_minor_alloc(ip_minor_arena_sa)) == 0) {
+			if (tcps != NULL)
+				netstack_rele(tcps->tcps_netstack);
+			return (EBUSY);
+		}
+		minor_arena = ip_minor_arena_sa;
+	}
+	ASSERT(minor_arena != NULL);
 
 	*devp = makedevice(getemajor(*devp), (minor_t)conn_dev);
 
@@ -9676,9 +9699,14 @@
 		/* No netstack_find_by_cred, hence no netstack_rele needed */
 		ASSERT(tcps == NULL);
 		q->q_qinfo = &tcp_acceptor_rinit;
-		q->q_ptr = (void *)conn_dev;
+		/*
+		 * the conn_dev and minor_arena will be subsequently used by
+		 * tcp_wput_accept() and tcpclose_accept() to figure out the
+		 * minor device number for this connection from the q_ptr.
+		 */
+		RD(q)->q_ptr = (void *)conn_dev;
 		WR(q)->q_qinfo = &tcp_acceptor_winit;
-		WR(q)->q_ptr = (void *)conn_dev;
+		WR(q)->q_ptr = (void *)minor_arena;
 		qprocson(q);
 		return (0);
 	}
@@ -9690,7 +9718,7 @@
 	 */
 	netstack_rele(tcps->tcps_netstack);
 	if (connp == NULL) {
-		inet_minor_free(ip_minor_arena, conn_dev);
+		inet_minor_free(minor_arena, conn_dev);
 		q->q_ptr = NULL;
 		return (ENOSR);
 	}
@@ -9740,6 +9768,7 @@
 		connp->conn_mac_exempt = B_TRUE;
 
 	connp->conn_dev = conn_dev;
+	connp->conn_minor_arena = minor_arena;
 
 	ASSERT(q->q_qinfo == &tcp_rinitv4 || q->q_qinfo == &tcp_rinitv6);
 	ASSERT(WR(q)->q_qinfo == &tcp_winit);
@@ -9768,7 +9797,7 @@
 
 	err = tcp_init(tcp, q);
 	if (err != 0) {
-		inet_minor_free(ip_minor_arena, connp->conn_dev);
+		inet_minor_free(connp->conn_minor_arena, connp->conn_dev);
 		tcp_acceptor_hash_remove(tcp);
 		CONN_DEC_REF(connp);
 		q->q_ptr = WR(q)->q_ptr = NULL;
@@ -18265,7 +18294,8 @@
 		ok->PRIM_type = T_OK_ACK;
 		ok->CORRECT_prim = PRIM_type;
 		econnp = eager->tcp_connp;
-		econnp->conn_dev = (dev_t)q->q_ptr;
+		econnp->conn_dev = (dev_t)RD(q)->q_ptr;
+		econnp->conn_minor_arena = (vmem_t *)(WR(q)->q_ptr);
 		eager->tcp_rq = rq;
 		eager->tcp_wq = q;
 		rq->q_ptr = econnp;
--- a/usr/src/uts/common/inet/udp/udp.c	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/common/inet/udp/udp.c	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -1491,9 +1491,7 @@
 	 * future.
 	 */
 	ASSERT(connp->conn_ref == 1);
-
-	inet_minor_free(ip_minor_arena, connp->conn_dev);
-
+	inet_minor_free(connp->conn_minor_arena, connp->conn_dev);
 	connp->conn_ref--;
 	ipcl_conn_destroy(connp);
 
@@ -2378,13 +2376,14 @@
 udp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp,
     boolean_t isv6)
 {
-	int	err;
-	udp_t	*udp;
-	conn_t *connp;
-	dev_t	conn_dev;
-	zoneid_t zoneid;
-	netstack_t *ns;
-	udp_stack_t *us;
+	int		err;
+	udp_t		*udp;
+	conn_t		*connp;
+	dev_t		conn_dev;
+	zoneid_t	zoneid;
+	netstack_t	*ns;
+	udp_stack_t	*us;
+	vmem_t		*minor_arena;
 
 	TRACE_1(TR_FAC_UDP, TR_UDP_OPEN, "udp_open: q %p", q);
 
@@ -2409,14 +2408,27 @@
 	else
 		zoneid = crgetzoneid(credp);
 
-	if ((conn_dev = inet_minor_alloc(ip_minor_arena)) == 0) {
-		netstack_rele(ns);
-		return (EBUSY);
-	}
+	if ((ip_minor_arena_la != NULL) && (flag & SO_SOCKSTR) &&
+	    ((conn_dev = inet_minor_alloc(ip_minor_arena_la)) != 0)) {
+		minor_arena = ip_minor_arena_la;
+	} else {
+		/*
+		 * Either minor numbers in the large arena were exhausted
+		 * or a non socket application is doing the open.
+		 * Try to allocate from the small arena.
+		 */
+		if ((conn_dev = inet_minor_alloc(ip_minor_arena_sa)) == 0) {
+			netstack_rele(ns);
+			return (EBUSY);
+		}
+		minor_arena = ip_minor_arena_sa;
+	}
+
 	*devp = makedevice(getemajor(*devp), (minor_t)conn_dev);
 
 	connp = ipcl_conn_create(IPCL_UDPCONN, KM_SLEEP, ns);
 	connp->conn_dev = conn_dev;
+	connp->conn_minor_arena = minor_arena;
 	udp = connp->conn_udp;
 
 	/*
--- a/usr/src/uts/intel/ip/ip.global-objs.debug64	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/intel/ip/ip.global-objs.debug64	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -80,7 +80,6 @@
 ill_null
 inet_dev_info
 inet_devops
-inet_maxminor
 ip6_area_template
 ip6_ared_template
 ip6_cache_table_size
@@ -117,7 +116,8 @@
 ip_max_cache_table_size
 ip_max_frag_dups
 ip_min_frag_prune_time
-ip_minor_arena
+ip_minor_arena_sa
+ip_minor_arena_la
 ip_misc_ioctl_count
 ip_misc_ioctl_table
 ip_mod_info
--- a/usr/src/uts/intel/ip/ip.global-objs.obj64	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/intel/ip/ip.global-objs.obj64	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -80,7 +80,6 @@
 ill_null
 inet_dev_info
 inet_devops
-inet_maxminor
 ip6_area_template
 ip6_ared_template
 ip6_cache_table_size
@@ -117,7 +116,8 @@
 ip_max_cache_table_size
 ip_max_frag_dups
 ip_min_frag_prune_time
-ip_minor_arena
+ip_minor_arena_sa
+ip_minor_arena_la
 ip_misc_ioctl_count
 ip_misc_ioctl_table
 ip_mod_info
--- a/usr/src/uts/sparc/ip/ip.global-objs.debug64	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/sparc/ip/ip.global-objs.debug64	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -80,7 +80,6 @@
 ill_null
 inet_dev_info
 inet_devops
-inet_maxminor
 ip6_area_template
 ip6_ared_template
 ip6_cache_table_size
@@ -117,7 +116,8 @@
 ip_max_cache_table_size
 ip_max_frag_dups
 ip_min_frag_prune_time
-ip_minor_arena
+ip_minor_arena_sa
+ip_minor_arena_la
 ip_misc_ioctl_count
 ip_misc_ioctl_table
 ip_mod_info
--- a/usr/src/uts/sparc/ip/ip.global-objs.obj64	Fri Jan 11 12:35:21 2008 -0800
+++ b/usr/src/uts/sparc/ip/ip.global-objs.obj64	Fri Jan 11 12:54:58 2008 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -80,7 +80,6 @@
 ill_null
 inet_dev_info
 inet_devops
-inet_maxminor
 ip6_area_template
 ip6_ared_template
 ip6_cache_table_size
@@ -117,7 +116,8 @@
 ip_max_cache_table_size
 ip_max_frag_dups
 ip_min_frag_prune_time
-ip_minor_arena
+ip_minor_arena_sa
+ip_minor_arena_la
 ip_misc_ioctl_count
 ip_misc_ioctl_table
 ip_mod_info