portals.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,711 行 · 第 1/4 页

C
1,711
字号
        fprintf(stderr, "IOC_LIBCFS_LWT_CONTROL failed: %s\n",                strerror(errno));        return (-1);}static intlwt_snapshot(cycles_t *now, int *ncpu, int *totalsize,             lwt_event_t *events, int size){        struct libcfs_ioctl_data data;        int                      rc;        LIBCFS_IOC_INIT(data);        data.ioc_pbuf1 = (char *)events;        data.ioc_plen1 = size;        rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LWT_SNAPSHOT, &data);        if (rc != 0) {                fprintf(stderr, "IOC_LIBCFS_LWT_SNAPSHOT failed: %s\n",                        strerror(errno));                return (-1);        }        /* crappy overloads */        if (data.ioc_u32[2] != sizeof(lwt_event_t) ||            data.ioc_u32[3] != offsetof(lwt_event_t, lwte_where)) {                fprintf(stderr,"kernel/user LWT event mismatch %d(%d),%d(%d)\n",                        (int)data.ioc_u32[2], (int)sizeof(lwt_event_t),                        (int)data.ioc_u32[3],                        (int)offsetof(lwt_event_t, lwte_where));                return (-1);        }        if (now != NULL)                *now = data.ioc_u64[0];        LASSERT (data.ioc_u32[0] != 0);        if (ncpu != NULL)                *ncpu = data.ioc_u32[0];        LASSERT (data.ioc_u32[1] != 0);        if (totalsize != NULL)                *totalsize = data.ioc_u32[1];        return (0);}static char *lwt_get_string(char *kstr){        char                     *ustr;        struct libcfs_ioctl_data  data;        int                       size;        int                       rc;        /* FIXME: this could maintain a symbol table since we expect to be         * looking up the same strings all the time... */        LIBCFS_IOC_INIT(data);        data.ioc_pbuf1 = kstr;        data.ioc_plen1 = 1;        /* non-zero just to fool portal_ioctl_is_invalid() */        data.ioc_pbuf2 = NULL;        data.ioc_plen2 = 0;        rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LWT_LOOKUP_STRING, &data);        if (rc != 0) {                fprintf(stderr, "IOC_LIBCFS_LWT_LOOKUP_STRING failed: %s\n",                        strerror(errno));                return (NULL);        }        size = data.ioc_count;        ustr = (char *)malloc(size);        if (ustr == NULL) {                fprintf(stderr, "Can't allocate string storage of size %d\n",                        size);                return (NULL);        }        LIBCFS_IOC_INIT(data);        data.ioc_pbuf1 = kstr;        data.ioc_plen1 = 1;        /* non-zero just to fool portal_ioctl_is_invalid() */        data.ioc_pbuf2 = ustr;        data.ioc_plen2 = size;        rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LWT_LOOKUP_STRING, &data);        if (rc != 0) {                fprintf(stderr, "IOC_LIBCFS_LWT_LOOKUP_STRING failed: %s\n",                        strerror(errno));                return (NULL);        }        LASSERT(strlen(ustr) == size - 1);        return (ustr);}static voidlwt_put_string(char *ustr){        free(ustr);}static intlwt_print(FILE *f, cycles_t t0, cycles_t tlast, double mhz, int cpu, lwt_event_t *e){#ifndef __WORDSIZE# error "__WORDSIZE not defined"#elif __WORDSIZE == 32# define XFMT "%#010lx"#elif __WORDSIZE== 64# define XFMT "%#018lx"#else# error "Unexpected __WORDSIZE"#endif        char           *where = lwt_get_string(e->lwte_where);        if (where == NULL)                return (-1);        fprintf(f, XFMT" "XFMT" "XFMT" "XFMT": "XFMT" %2d %10.6f %10.2f %s\n",                e->lwte_p1, e->lwte_p2, e->lwte_p3, e->lwte_p4,                (long)e->lwte_task, cpu, (e->lwte_when - t0) / (mhz * 1000000.0),                (t0 == e->lwte_when) ? 0.0 : (e->lwte_when - tlast) / mhz,                where);        lwt_put_string(where);        return (0);#undef XFMT}doubleget_cycles_per_usec (){        FILE      *f = fopen ("/proc/cpuinfo", "r");        double     mhz;        char      line[64];        if (f != NULL) {                while (fgets (line, sizeof (line), f) != NULL)                        if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {                                fclose (f);                                return (mhz);                        }                fclose (f);        }        fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");        return (1000.0);}intjt_ptl_lwt(int argc, char **argv){        const int       lwt_max_cpus = 32;        int             ncpus;        int             totalspace;        int             nevents_per_cpu;        lwt_event_t    *events;        lwt_event_t    *cpu_event[lwt_max_cpus + 1];        lwt_event_t    *next_event[lwt_max_cpus];        lwt_event_t    *first_event[lwt_max_cpus];        int             cpu;        lwt_event_t    *e;        int             rc;        int             i;        double          mhz;        cycles_t        t0;        cycles_t        tlast;        cycles_t        tnow;        struct timeval  tvnow;        int             printed_date = 0;        int             nlines = 0;        FILE           *f = stdout;        if (argc < 2 ||            (strcmp(argv[1], "start") &&             strcmp(argv[1], "stop"))) {                fprintf(stderr,                         "usage:  %s start\n"                        "        %s stop [fname]\n", argv[0], argv[0]);                return (-1);        }        if (!strcmp(argv[1], "start")) {                /* disable */                if (lwt_control(0, 0) != 0)                        return (-1);                /* clear */                if (lwt_control(0, 1) != 0)                        return (-1);                /* enable */                if (lwt_control(1, 0) != 0)                        return (-1);                return (0);        }        if (lwt_snapshot(NULL, &ncpus, &totalspace, NULL, 0) != 0)                return (-1);        if (ncpus > lwt_max_cpus) {                fprintf(stderr, "Too many cpus: %d (%d)\n",                        ncpus, lwt_max_cpus);                return (-1);        }        events = (lwt_event_t *)malloc(totalspace);        if (events == NULL) {                fprintf(stderr, "Can't allocate %d\n", totalspace);                return (-1);        }        if (lwt_control(0, 0) != 0) {           /* disable */                free(events);                return (-1);        }        if (lwt_snapshot(&tnow, NULL, NULL, events, totalspace)) {                free(events);                return (-1);        }        /* we want this time to be sampled at snapshot time */        gettimeofday(&tvnow, NULL);        if (argc > 2) {                f = fopen (argv[2], "w");                if (f == NULL) {                        fprintf(stderr, "Can't open %s for writing: %s\n", argv[2], strerror (errno));                        free(events);                        return (-1);                }        }        mhz = get_cycles_per_usec();        /* carve events into per-cpu slices */        nevents_per_cpu = totalspace / (ncpus * sizeof(lwt_event_t));        for (cpu = 0; cpu <= ncpus; cpu++)                cpu_event[cpu] = &events[cpu * nevents_per_cpu];        /* find the earliest event on each cpu */        for (cpu = 0; cpu < ncpus; cpu++) {                first_event[cpu] = NULL;                for (e = cpu_event[cpu]; e < cpu_event[cpu + 1]; e++) {                        if (e->lwte_where == NULL) /* not an event */                                continue;                        if (first_event[cpu] == NULL ||                            first_event[cpu]->lwte_when > e->lwte_when)                                first_event[cpu] = e;                }                next_event[cpu] = first_event[cpu];        }        t0 = tlast = 0;        for (cpu = 0; cpu < ncpus; cpu++) {                e = first_event[cpu];                if (e == NULL)                  /* no events this cpu */                        continue;                if (e == cpu_event[cpu])                        e = cpu_event[cpu + 1] - 1;                else                        e = e - 1;                /* If there's an event immediately before the first one, this                 * cpu wrapped its event buffer */                if (e->lwte_where == NULL)                        continue;                /* We should only start outputting events from the most recent                 * first event in any wrapped cpu.  Events before this time on                 * other cpus won't have any events from this CPU to interleave                 * with. */                if (t0 < first_event[cpu]->lwte_when)                        t0 = first_event[cpu]->lwte_when;        }        for (;;) {                /* find which cpu has the next event */                cpu = -1;                for (i = 0; i < ncpus; i++) {                        if (next_event[i] == NULL) /* this cpu exhausted */                                continue;                        if (cpu < 0 ||                            next_event[i]->lwte_when < next_event[cpu]->lwte_when)                                cpu = i;                }                if (cpu < 0)                    /* all cpus exhausted */                        break;                if (t0 == 0) {                        /* no wrapped cpus and this is he first ever event */                        t0 = next_event[cpu]->lwte_when;                }                if (t0 <= next_event[cpu]->lwte_when) {                        /* on or after the first event */                        if (!printed_date) {                                cycles_t du = (tnow - t0) / mhz;                                time_t   then = tvnow.tv_sec - du/1000000;                                if (du % 1000000 > tvnow.tv_usec)                                        then--;                                fprintf(f, "%s", ctime(&then));                                printed_date = 1;                        }                        rc = lwt_print(f, t0, tlast, mhz, cpu, next_event[cpu]);                        if (rc != 0)                                break;                        if (++nlines % 10000 == 0 && f != stdout) {                                /* show some activity... */                                printf(".");                                fflush (stdout);                        }                }                tlast = next_event[cpu]->lwte_when;                next_event[cpu]++;                if (next_event[cpu] == cpu_event[cpu + 1])                        next_event[cpu] = cpu_event[cpu];                if (next_event[cpu]->lwte_where == NULL ||                    next_event[cpu] == first_event[cpu])                        next_event[cpu] = NULL;        }        if (f != stdout) {                printf("\n");                fclose(f);        }        free(events);        return (0);}int jt_ptl_memhog(int argc, char **argv){        static int                gfp = 0;        /* sticky! */        struct libcfs_ioctl_data  data;        int                       rc;        int                       count;        char                     *end;        if (argc < 2)  {                fprintf(stderr, "usage: %s <npages> [<GFP flags>]\n", argv[0]);                return 0;        }        count = strtol(argv[1], &end, 0);        if (count < 0 || *end != 0) {                fprintf(stderr, "Can't parse page count '%s'\n", argv[1]);                return -1;        }        if (argc >= 3) {                rc = strtol(argv[2], &end, 0);                if (*end != 0) {                        fprintf(stderr, "Can't parse gfp flags '%s'\n", argv[2]);                        return -1;                }                gfp = rc;        }        LIBCFS_IOC_INIT(data);        data.ioc_count = count;        data.ioc_flags = gfp;        rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_MEMHOG, &data);        if (rc != 0) {                fprintf(stderr, "memhog %d failed: %s\n", count, strerror(errno));                return -1;        }        printf("memhog %d OK\n", count);        return 0;}int jt_ptl_testprotocompat(int argc, char **argv){        struct libcfs_ioctl_data  data;        int                       rc;        int                       flags;        char                     *end;        if (argc < 2)  {                fprintf(stderr, "usage: %s <number>\n", argv[0]);                return 0;        }        flags = strtol(argv[1], &end, 0);        if (flags < 0 || *end != 0) {                fprintf(stderr, "Can't parse flags '%s'\n", argv[1]);                return -1;        }        LIBCFS_IOC_INIT(data);        data.ioc_flags = flags;        rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_TESTPROTOCOMPAT, &data);        if (rc != 0) {                fprintf(stderr, "test proto compat %x failed: %s\n",                        flags, strerror(errno));                return -1;        }        printf("test proto compat %x OK\n", flags);        return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?