diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h
index dd11208d9d20b9a21260e19c563fb9e3808c6a53..583544218d1b57592ac13ee197c8325fdc176ea8 100644
--- a/lustre/include/lustre_net.h
+++ b/lustre/include/lustre_net.h
@@ -94,12 +94,8 @@
 #define LDLM_MAXREPSIZE (1024)
 
 /* Absolute limits */
-#define MDS_THREADS_MIN 2UL
-#define MDS_THREADS_MAX 512UL
-/* Dynamic thread limits */
-#define MDS_THREADS_AUTO_MIN max(MDS_THREADS_MIN, min(32UL, \
-                             smp_num_cpus * num_physpages >> (27 - CFS_PAGE_SHIFT)))
-#define MDS_THREADS_AUTO_MAX min(MDS_THREADS_MAX, MDS_THREADS_AUTO_MIN * 4)
+#define MDS_THREADS_MIN 2
+#define MDS_THREADS_MAX 512
 #define MDS_THREADS_MIN_READPAGE 2
 #define MDS_NBUFS       (64 * smp_num_cpus)
 #define MDS_BUFSIZE     (8 * 1024)
@@ -123,20 +119,16 @@
 #define MDS_MAXREQSIZE  (5 * 1024)
 #define MDS_MAXREPSIZE  max(9 * 1024, 280 + LOV_MAX_STRIPE_COUNT * 56)
 
-#define MGS_THREADS_AUTO_MAX 128UL
-#define MGS_THREADS_AUTO_MIN MDS_THREADS_AUTO_MIN
+#define MGS_THREADS_AUTO_MIN 2
+#define MGS_THREADS_AUTO_MAX 128
 #define MGS_NBUFS       (64 * smp_num_cpus)
 #define MGS_BUFSIZE     (8 * 1024)
 #define MGS_MAXREQSIZE  (8 * 1024)
 #define MGS_MAXREPSIZE  (9 * 1024)
 
 /* Absolute limits */
-#define OSS_THREADS_MIN 2UL
-#define OSS_THREADS_MAX 512UL
-/* Dynamic thread limits */
-#define OSS_THREADS_AUTO_MIN max(OSS_THREADS_MIN, \
-                             smp_num_cpus * num_physpages >> (27 - CFS_PAGE_SHIFT))
-#define OSS_THREADS_AUTO_MAX min(OSS_THREADS_MAX, OSS_THREADS_AUTO_MIN * 4)
+#define OSS_THREADS_MIN 2
+#define OSS_THREADS_MAX 512
 #define OST_NBUFS       (64 * smp_num_cpus)
 #define OST_BUFSIZE     (8 * 1024)
 /* OST_MAXREQSIZE ~= 4768 bytes =
diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c
index 0f8788b9194a771a93bbe118e3cb1da817a123ae..5f59ab31eedfd324f446715cc836d17c3c2b33fc 100644
--- a/lustre/mds/handler.c
+++ b/lustre/mds/handler.c
@@ -2524,8 +2524,8 @@ static int mdt_setup(struct obd_device *obd, obd_count len, void *buf)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct lprocfs_static_vars lvars;
-        int mds_min_threads = MDS_THREADS_AUTO_MIN;
-        int mds_max_threads = MDS_THREADS_AUTO_MAX;
+        int mds_min_threads;
+        int mds_max_threads;
         int rc = 0;
         ENTRY;
 
@@ -2541,6 +2541,16 @@ static int mdt_setup(struct obd_device *obd, obd_count len, void *buf)
                 if (mds_num_threads < MDS_THREADS_MIN)
                         mds_num_threads = MDS_THREADS_MIN;
                 mds_max_threads = mds_min_threads = mds_num_threads;
+        } else {
+                /* Base min threads on memory and cpus */
+                mds_min_threads = smp_num_cpus * num_physpages >> 
+                        (27 - CFS_PAGE_SHIFT);
+                if (mds_min_threads < MDS_THREADS_MIN)
+                        mds_min_threads = MDS_THREADS_MIN;
+                /* Largest auto threads start value */
+                if (mds_min_threads > 32) 
+                        mds_min_threads = 32;
+                mds_max_threads = min(MDS_THREADS_MAX, mds_min_threads * 4);
         }
 
         mds->mds_service =
diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c
index 1377fca61660e7a96a76dbd09d60f4be07e79a2c..0e7203ba2b4c0ae4fdd22a1ce13aac1dee125e91 100644
--- a/lustre/ost/ost_handler.c
+++ b/lustre/ost/ost_handler.c
@@ -1613,8 +1613,8 @@ static int ost_setup(struct obd_device *obd, obd_count len, void *buf)
 {
         struct ost_obd *ost = &obd->u.ost;
         struct lprocfs_static_vars lvars;
-        int oss_min_threads = OSS_THREADS_AUTO_MIN;
-        int oss_max_threads = OSS_THREADS_AUTO_MAX;
+        int oss_min_threads;
+        int oss_max_threads;
         int rc;
         ENTRY;
 
@@ -1638,6 +1638,16 @@ static int ost_setup(struct obd_device *obd, obd_count len, void *buf)
                 if (oss_num_threads < OSS_THREADS_MIN)
                         oss_num_threads = OSS_THREADS_MIN;
                 oss_max_threads = oss_min_threads = oss_num_threads;
+        } else {
+                /* Base min threads on memory and cpus */
+                oss_min_threads = smp_num_cpus * num_physpages >> 
+                        (27 - CFS_PAGE_SHIFT);
+                if (oss_min_threads < OSS_THREADS_MIN)
+                        oss_min_threads = OSS_THREADS_MIN;
+                /* Insure a 4x range for dynamic threads */
+                if (oss_min_threads > OSS_THREADS_MAX / 4) 
+                        oss_min_threads = OSS_THREADS_MAX / 4;
+                oss_max_threads = min(OSS_THREADS_MAX, oss_min_threads * 4);
         }
 
         ost->ost_service =
diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c
index 1a34bf943d775c2941e163aacd6395e16b0e2b62..5c7306d0c92b831c82135824de9ca1295d5f561c 100644
--- a/lustre/ptlrpc/service.c
+++ b/lustre/ptlrpc/service.c
@@ -1087,8 +1087,6 @@ int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc)
         int id, rc;
         ENTRY;
 
-        /* Not worrying about the svc_lock at this check - no big deal if
-           we start an extra thread or 2. */
         CDEBUG(D_RPCTRACE, "%s started %d min %d max %d running %d\n",
                svc->srv_name, svc->srv_threads_started, svc->srv_threads_min,
                svc->srv_threads_max, svc->srv_threads_running);
@@ -1101,6 +1099,11 @@ int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc)
         cfs_waitq_init(&thread->t_ctl_waitq);
 
         spin_lock(&svc->srv_lock);
+        if (svc->srv_threads_started >= svc->srv_threads_max) {
+                spin_unlock(&svc->srv_lock);
+                OBD_FREE(thread, sizeof(*thread));
+                RETURN(-EMFILE);
+        }
         list_add(&thread->t_link, &svc->srv_threads);
         id = ++svc->srv_threads_started;
         spin_unlock(&svc->srv_lock);