[MIPS] SMTC: Allow control over TC assignment to vpe0.
authorKevin D. Kissell <kevink@mips.com>
Wed, 21 Mar 2007 12:28:37 +0000 (13:28 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Mon, 29 Oct 2007 19:35:32 +0000 (19:35 +0000)
Modify the SMTC initialization code to allow boot-time specification not
only of how many VPEs and TCs to use, but also how many TCs out of the
allowed pool are to be bound to VPE 0.  The new boot option is "vpe0tcs=N",
where N is an integer.  Using it in combination with the existing options
allows arbitrary assignments across the 2 VPEs of a 34K.  e.g. "maxtcs=3
 vpe0tcs=1" forces VPE0 to have 1 TC, while VPE1 has 2, and "maxtcs=4
vpe0tcs=3" forces VPE0 to have 3 TCs, while VPE1 gets 1.  If no vpe0tcs
option is specified, the traditional algorithm of evenly dividing TCs
between available VPEs, with the odd "slop" going to VPE0, is retained.

The reason for doing this is to allow a finer balancing of TCs which can
handle I/O interrupts on Malta (those on VPE 0) and those which cannot.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/kernel/smtc.c

index a8c1a698d5889f722b80419de6707296148528e5..9c92d42996cb48eade410f317d9e9e68821ffd45 100644 (file)
@@ -88,11 +88,19 @@ unsigned int smtc_status = 0;
 
 /* Boot command line configuration overrides */
 
+static int vpe0limit;
 static int ipibuffers = 0;
 static int nostlb = 0;
 static int asidmask = 0;
 unsigned long smtc_asid_mask = 0xff;
 
+static int __init vpe0tcs(char *str)
+{
+       get_option(&str, &vpe0limit);
+
+       return 1;
+}
+
 static int __init ipibufs(char *str)
 {
        get_option(&str, &ipibuffers);
@@ -125,6 +133,7 @@ static int __init asidmask_set(char *str)
        return 1;
 }
 
+__setup("vpe0tcs=", vpe0tcs);
 __setup("ipibufs=", ipibufs);
 __setup("nostlb", stlb_disable);
 __setup("asidmask=", asidmask_set);
@@ -340,7 +349,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
 
 void mipsmt_prepare_cpus(void)
 {
-       int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu;
+       int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu;
        unsigned long flags;
        unsigned long val;
        int nipi;
@@ -401,8 +410,39 @@ void mipsmt_prepare_cpus(void)
                ntc = NR_CPUS;
        if (tclimit > 0 && ntc > tclimit)
                ntc = tclimit;
-       tcpervpe = ntc / nvpe;
-       slop = ntc % nvpe;      /* Residual TCs, < NVPE */
+       slop = ntc % nvpe;
+       for (i = 0; i < nvpe; i++) {
+               tcpervpe[i] = ntc / nvpe;
+               if (slop) {
+                       if((slop - i) > 0) tcpervpe[i]++;
+               }
+       }
+       /* Handle command line override for VPE0 */
+       if (vpe0limit > ntc) vpe0limit = ntc;
+       if (vpe0limit > 0) {
+               int slopslop;
+               if (vpe0limit < tcpervpe[0]) {
+                   /* Reducing TC count - distribute to others */
+                   slop = tcpervpe[0] - vpe0limit;
+                   slopslop = slop % (nvpe - 1);
+                   tcpervpe[0] = vpe0limit;
+                   for (i = 1; i < nvpe; i++) {
+                       tcpervpe[i] += slop / (nvpe - 1);
+                       if(slopslop && ((slopslop - (i - 1) > 0)))
+                               tcpervpe[i]++;
+                   }
+               } else if (vpe0limit > tcpervpe[0]) {
+                   /* Increasing TC count - steal from others */
+                   slop = vpe0limit - tcpervpe[0];
+                   slopslop = slop % (nvpe - 1);
+                   tcpervpe[0] = vpe0limit;
+                   for (i = 1; i < nvpe; i++) {
+                       tcpervpe[i] -= slop / (nvpe - 1);
+                       if(slopslop && ((slopslop - (i - 1) > 0)))
+                               tcpervpe[i]--;
+                   }
+               }
+       }
 
        /* Set up shared TLB */
        smtc_configure_tlb();
@@ -416,7 +456,7 @@ void mipsmt_prepare_cpus(void)
                if (vpe != 0)
                        printk(", ");
                printk("VPE %d: TC", vpe);
-               for (i = 0; i < tcpervpe; i++) {
+               for (i = 0; i < tcpervpe[vpe]; i++) {
                        /*
                         * TC 0 is bound to VPE 0 at reset,
                         * and is presumably executing this
@@ -429,15 +469,6 @@ void mipsmt_prepare_cpus(void)
                        printk(" %d", tc);
                        tc++;
                }
-               if (slop) {
-                       if (tc != 0) {
-                               smtc_tc_setup(vpe, tc, cpu);
-                               cpu++;
-                       }
-                       printk(" %d", tc);
-                       tc++;
-                       slop--;
-               }
                if (vpe != 0) {
                        /*
                         * Clear any stale software interrupts from VPE's Cause