intel_l3_parity: Use getopt for the l3 parity tool
authorBen Widawsky <benjamin.widawsky@intel.com>
Sat, 7 Sep 2013 04:10:50 +0000 (21:10 -0700)
committerBen Widawsky <benjamin.widawsky@intel.com>
Fri, 20 Sep 2013 16:42:07 +0000 (09:42 -0700)
Add new command line arguments in addition to supporting the old
features. This patch only introduces one feature, the -e argument to
enable a specific row/bank/subbank. Previously you could only enable
all. Otherwise, it has what you expect (we prefer -r -b -s for
specifying the row/bank/subbank).

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
tests/sysfs_l3_parity
tools/intel_l3_parity.c

index 6f814a1..a0dfad9 100755 (executable)
@@ -8,20 +8,20 @@ fi
 SOURCE_DIR="$( dirname "${BASH_SOURCE[0]}" )"
 . $SOURCE_DIR/drm_lib.sh
 
-$SOURCE_DIR/../tools/intel_l3_parity -c
+$SOURCE_DIR/../tools/intel_l3_parity -r 0 -b 0 -s 0 -e
 
 #Check that we can remap a row
-$SOURCE_DIR/../tools/intel_l3_parity 0,0,0
-disabled=`$SOURCE_DIR/../tools/intel_l3_parity | grep -c 'Row 0, Bank 0, Subbank 0 is disabled'`
+$SOURCE_DIR/../tools/intel_l3_parity -r 0 -b 0 -s 0 -d
+disabled=`$SOURCE_DIR/../tools/intel_l3_parity -l | grep -c 'Row 0, Bank 0, Subbank 0 is disabled'`
 if [ "$disabled" != "1" ] ; then
        echo "Fail"
        exit 1
 fi
 
-$SOURCE_DIR/../tools/intel_l3_parity -c
+$SOURCE_DIR/../tools/intel_l3_parity -r 0 -b 0 -s 0 -e
 
 #Check that we can clear remaps
-if [ `$SOURCE_DIR/../tools/intel_l3_parity | wc -c` != "0" ] ; then
-       echo "Fail"
+if [ `$SOURCE_DIR/../tools/intel_l3_parity -l | wc -c` != "0" ] ; then
+       echo "Fail 2"
        exit 1
 fi
index 715d095..507a522 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <getopt.h>
 #include "intel_chipset.h"
 #include "intel_gpu_tools.h"
 #include "drmtest.h"
 
 #define NUM_BANKS 4
 #define NUM_SUBBANKS 8
+#define MAX_ROW (1<<12)
 #define NUM_REGS (NUM_BANKS * NUM_SUBBANKS)
 
 struct __attribute__ ((__packed__)) l3_log_register {
@@ -93,17 +95,34 @@ static int disable_rbs(int row, int bank, int sbank)
        return 0;
 }
 
-static int do_parse(int argc, char *argv[])
+static void enables_rbs(int row, int bank, int sbank)
 {
-       int row, bank, sbank, i, ret;
+       struct l3_log_register *reg = &l3log[bank][sbank];
 
-       for (i = 1; i < argc; i++) {
-               ret = sscanf(argv[i], "%d,%d,%d", &row, &bank, &sbank);
-               if (ret != 3)
-                       return i;
-               assert(disable_rbs(row, bank, sbank) == 0);
-       }
-       return 0;
+       if (!reg->row0_enable && !reg->row1_enable)
+               return;
+
+       if (reg->row1_enable && reg->row1 == row)
+               reg->row1_enable = 0;
+       else if (reg->row0_enable && reg->row0 == row)
+               reg->row0_enable = 0;
+}
+
+static void usage(const char *name)
+{
+       printf("usage: %s [OPTIONS] [ACTION]\n"
+               "Operate on the i915 L3 GPU cache (should be run as root)\n\n"
+               " OPTIONS:\n"
+               "  -r, --row=[row]                      The row to act upon (default 0)\n"
+               "  -b, --bank=[bank]                    The bank to act upon (default 0)\n"
+               "  -s, --subbank=[subbank]              The subbank to act upon (default 0)\n"
+               " ACTIONS (only 1 may be specified at a time):\n"
+               "  -h, --help                           Display this help\n"
+               "  -l, --list                           List the current L3 logs\n"
+               "  -a, --clear-all                      Clear all disabled rows\n"
+               "  -e, --enable                         Enable row, bank, subbank (undo -d)\n"
+               "  -d, --disable=<row,bank,subbank>     Disable row, bank, subbank (inline arguments are deprecated. Please use -r, -b, -s instead\n",
+               name);
 }
 
 int main(int argc, char *argv[])
@@ -111,7 +130,9 @@ int main(int argc, char *argv[])
        const int device = drm_get_card();
        char *path;
        unsigned int devid;
+       int row = 0, bank = 0, sbank = 0;
        int drm_fd, fd, ret;
+       int action = '0';
 
        drm_fd = drm_open_any();
        devid = intel_get_drm_devid(drm_fd);
@@ -133,19 +154,82 @@ int main(int argc, char *argv[])
 
        assert(lseek(fd, 0, SEEK_SET) == 0);
 
-       if (argc == 1) {
-               dumpit();
-               exit(EXIT_SUCCESS);
-       } else if (!strncmp("-c", argv[1], 2)) {
-               memset(l3log, 0, sizeof(l3log));
-       } else {
-               ret = do_parse(argc, argv);
-               if (ret != 0) {
-                       fprintf(stderr, "Malformed command line at %s\n", argv[ret]);
-                       exit(EXIT_FAILURE);
+       while (1) {
+               int c, option_index = 0;
+               static struct option long_options[] = {
+                       { "help", no_argument, 0, 'h' },
+                       { "list", no_argument, 0, 'l' },
+                       { "clear-all", no_argument, 0, 'a' },
+                       { "enable", no_argument, 0, 'e' },
+                       { "disable", optional_argument, 0, 'd' },
+                       { "row", required_argument, 0, 'r' },
+                       { "bank", required_argument, 0, 'b' },
+                       { "subbank", required_argument, 0, 's' },
+                       {0, 0, 0, 0}
+               };
+
+               c = getopt_long(argc, argv, "hr:b:s:aled::", long_options,
+                               &option_index);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+                       case '?':
+                       case 'h':
+                               usage(argv[0]);
+                               exit(EXIT_SUCCESS);
+                       case 'r':
+                               row = atoi(optarg);
+                               if (row >= MAX_ROW)
+                                       exit(EXIT_FAILURE);
+                               break;
+                       case 'b':
+                               bank = atoi(optarg);
+                               if (bank >= NUM_BANKS)
+                                       exit(EXIT_FAILURE);
+                               break;
+                       case 's':
+                               sbank = atoi(optarg);
+                               if (sbank >= NUM_SUBBANKS)
+                                       exit(EXIT_FAILURE);
+                               break;
+                       case 'd':
+                               if (optarg) {
+                                       ret = sscanf(optarg, "%d,%d,%d", &row, &bank, &sbank);
+                                       if (ret != 3)
+                                               exit(EXIT_FAILURE);
+                               }
+                       case 'a':
+                       case 'l':
+                       case 'e':
+                               if (action != '0') {
+                                       fprintf(stderr, "Only one action may be specified\n");
+                                       exit(EXIT_FAILURE);
+                               }
+                               action = c;
+                               break;
+                       default:
+                               abort();
                }
        }
 
+       switch (action) {
+               case 'l':
+                       dumpit();
+                       exit(EXIT_SUCCESS);
+               case 'a':
+                       memset(l3log, 0, sizeof(l3log));
+                       break;
+               case 'e':
+                       enables_rbs(row, bank, sbank);
+                       break;
+               case 'd':
+                       assert(disable_rbs(row, bank, sbank) == 0);
+                       break;
+               default:
+                       abort();
+       }
+
        ret = write(fd, l3log, NUM_REGS * sizeof(uint32_t));
        if (ret == -1) {
                perror("Writing sysfs");