Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/bpf/bpftool/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  map_perf_ring.c   Sprache: C

 
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2018 Netronome Systems, Inc. */
/* This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 */

#include <errno.h>
#include <fcntl.h>
#include <bpf/libbpf.h>
#include <poll.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <linux/bpf.h>
#include <linux/perf_event.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/syscall.h>

#include <bpf/bpf.h>

#include "main.h"

#define MMAP_PAGE_CNT 16

static volatile bool stop;

struct perf_event_sample {
 struct perf_event_header header;
 __u64 time;
 __u32 size;
 unsigned char data[];
};

struct perf_event_lost {
 struct perf_event_header header;
 __u64 id;
 __u64 lost;
};

static void int_exit(int signo)
{
 fprintf(stderr, "Stopping...\n");
 stop = true;
}

struct event_pipe_ctx {
 bool all_cpus;
 int cpu;
 int idx;
};

static enum bpf_perf_event_ret
print_bpf_output(void *private_data, int cpu, struct perf_event_header *event)
{
 struct perf_event_sample *e = container_of(event,
         struct perf_event_sample,
         header);
 struct perf_event_lost *lost = container_of(event,
          struct perf_event_lost,
          header);
 struct event_pipe_ctx *ctx = private_data;
 int idx = ctx->all_cpus ? cpu : ctx->idx;

 if (json_output) {
  jsonw_start_object(json_wtr);
  jsonw_name(json_wtr, "type");
  jsonw_uint(json_wtr, e->header.type);
  jsonw_name(json_wtr, "cpu");
  jsonw_uint(json_wtr, cpu);
  jsonw_name(json_wtr, "index");
  jsonw_uint(json_wtr, idx);
  if (e->header.type == PERF_RECORD_SAMPLE) {
   jsonw_name(json_wtr, "timestamp");
   jsonw_uint(json_wtr, e->time);
   jsonw_name(json_wtr, "data");
   print_data_json(e->data, e->size);
  } else if (e->header.type == PERF_RECORD_LOST) {
   jsonw_name(json_wtr, "lost");
   jsonw_start_object(json_wtr);
   jsonw_name(json_wtr, "id");
   jsonw_uint(json_wtr, lost->id);
   jsonw_name(json_wtr, "count");
   jsonw_uint(json_wtr, lost->lost);
   jsonw_end_object(json_wtr);
  }
  jsonw_end_object(json_wtr);
 } else {
  if (e->header.type == PERF_RECORD_SAMPLE) {
   printf("== @%llu.%09llu CPU: %d index: %d =====\n",
          e->time / 1000000000ULL, e->time % 1000000000ULL,
          cpu, idx);
   fprint_hex(stdout, e->data, e->size, " ");
   printf("\n");
  } else if (e->header.type == PERF_RECORD_LOST) {
   printf("lost %llu events\n", lost->lost);
  } else {
   printf("unknown event type=%u size=%u\n",
          e->header.type, e->header.size);
  }
 }

 return LIBBPF_PERF_EVENT_CONT;
}

int do_event_pipe(int argc, char **argv)
{
 struct perf_event_attr perf_attr = {
  .sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_TIME,
  .type = PERF_TYPE_SOFTWARE,
  .config = PERF_COUNT_SW_BPF_OUTPUT,
  .sample_period = 1,
  .wakeup_events = 1,
 };
 struct bpf_map_info map_info = {};
 LIBBPF_OPTS(perf_buffer_raw_opts, opts);
 struct event_pipe_ctx ctx = {
  .all_cpus = true,
  .cpu = -1,
  .idx = -1,
 };
 struct perf_buffer *pb;
 __u32 map_info_len;
 int err, map_fd;

 map_info_len = sizeof(map_info);
 map_fd = map_parse_fd_and_info(&argc, &argv, &map_info, &map_info_len,
           0);
 if (map_fd < 0)
  return -1;

 if (map_info.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) {
  p_err("map is not a perf event array");
  goto err_close_map;
 }

 while (argc) {
  if (argc < 2) {
   BAD_ARG();
   goto err_close_map;
  }

  if (is_prefix(*argv, "cpu")) {
   char *endptr;

   NEXT_ARG();
   ctx.cpu = strtoul(*argv, &endptr, 0);
   if (*endptr) {
    p_err("can't parse %s as CPU ID", *argv);
    goto err_close_map;
   }

   NEXT_ARG();
  } else if (is_prefix(*argv, "index")) {
   char *endptr;

   NEXT_ARG();
   ctx.idx = strtoul(*argv, &endptr, 0);
   if (*endptr) {
    p_err("can't parse %s as index", *argv);
    goto err_close_map;
   }

   NEXT_ARG();
  } else {
   BAD_ARG();
   goto err_close_map;
  }

  ctx.all_cpus = false;
 }

 if (!ctx.all_cpus) {
  if (ctx.idx == -1 || ctx.cpu == -1) {
   p_err("cpu and index must be specified together");
   goto err_close_map;
  }
 } else {
  ctx.cpu = 0;
  ctx.idx = 0;
 }

 opts.cpu_cnt = ctx.all_cpus ? 0 : 1;
 opts.cpus = &ctx.cpu;
 opts.map_keys = &ctx.idx;
 pb = perf_buffer__new_raw(map_fd, MMAP_PAGE_CNT, &perf_attr,
      print_bpf_output, &ctx, &opts);
 if (!pb) {
  p_err("failed to create perf buffer: %s (%d)",
        strerror(errno), errno);
  goto err_close_map;
 }

 signal(SIGINT, int_exit);
 signal(SIGHUP, int_exit);
 signal(SIGTERM, int_exit);

 if (json_output)
  jsonw_start_array(json_wtr);

 while (!stop) {
  err = perf_buffer__poll(pb, 200);
  if (err < 0 && err != -EINTR) {
   p_err("perf buffer polling failed: %s (%d)",
         strerror(errno), errno);
   goto err_close_pb;
  }
 }

 if (json_output)
  jsonw_end_array(json_wtr);

 perf_buffer__free(pb);
 close(map_fd);

 return 0;

err_close_pb:
 perf_buffer__free(pb);
err_close_map:
 close(map_fd);
 return -1;
}

Messung V0.5
C=99 H=75 G=87

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.