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 + -
显示快捷键?