Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  perf_test.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * User Events Perf Events Test Program
 *
 * Copyright (c) 2021 Beau Belgrave <beaub@linux.microsoft.com>
 */


#include <errno.h>
#include <linux/user_events.h>
#include <linux/perf_event.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <asm/unistd.h>

#include "../kselftest_harness.h"
#include "user_events_selftests.h"

const char *data_file = "/sys/kernel/tracing/user_events_data";
const char *id_file = "/sys/kernel/tracing/events/user_events/__test_event/id";
const char *fmt_file = "/sys/kernel/tracing/events/user_events/__test_event/format";

struct event {
 __u32 index;
 __u32 field1;
 __u32 field2;
};

static long perf_event_open(struct perf_event_attr *pe, pid_t pid,
       int cpu, int group_fd, unsigned long flags)
{
 return syscall(__NR_perf_event_open, pe, pid, cpu, group_fd, flags);
}

static int get_id(void)
{
 FILE *fp = fopen(id_file, "r");
 int ret, id = 0;

 if (!fp)
  return -1;

 ret = fscanf(fp, "%d", &id);
 fclose(fp);

 if (ret != 1)
  return -1;

 return id;
}

static int get_offset(void)
{
 FILE *fp = fopen(fmt_file, "r");
 int ret, c, last = 0, offset = 0;

 if (!fp)
  return -1;

 /* Read until empty line */
 while (true) {
  c = getc(fp);

  if (c == EOF)
   break;

  if (last == '\n' && c == '\n')
   break;

  last = c;
 }

 ret = fscanf(fp, "\tfield:u32 field1;\toffset:%d;", &offset);
 fclose(fp);

 if (ret != 1)
  return -1;

 return offset;
}

static int clear(int *check)
{
 struct user_unreg unreg = {0};

 unreg.size = sizeof(unreg);
 unreg.disable_bit = 31;
 unreg.disable_addr = (__u64)check;

 int fd = open(data_file, O_RDWR);

 if (fd == -1)
  return -1;

 if (ioctl(fd, DIAG_IOCSUNREG, &unreg) == -1)
  if (errno != ENOENT)
   return -1;

 if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1)
  if (errno != ENOENT)
   return -1;

 close(fd);

 return 0;
}

FIXTURE(user) {
 int data_fd;
 int check;
 bool umount;
};

FIXTURE_SETUP(user) {
 USER_EVENT_FIXTURE_SETUP(return, self->umount);

 self->data_fd = open(data_file, O_RDWR);
 ASSERT_NE(-1, self->data_fd);
}

FIXTURE_TEARDOWN(user) {
 USER_EVENT_FIXTURE_TEARDOWN(self->umount);

 close(self->data_fd);

 if (clear(&self->check) != 0)
  printf("WARNING: Clear didn't work!\n");
}

TEST_F(user, perf_write) {
 struct perf_event_attr pe = {0};
 struct user_reg reg = {0};
 struct event event;
 struct perf_event_mmap_page *perf_page;
 int page_size = sysconf(_SC_PAGESIZE);
 int id, fd, offset;
 __u32 *val;

 reg.size = sizeof(reg);
 reg.name_args = (__u64)"__test_event u32 field1; u32 field2";
 reg.enable_bit = 31;
 reg.enable_addr = (__u64)&self->check;
 reg.enable_size = sizeof(self->check);

 /* Register should work */
 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®));
 ASSERT_EQ(0, reg.write_index);
 ASSERT_EQ(0, self->check);

 /* Id should be there */
 id = get_id();
 ASSERT_NE(-1, id);
 offset = get_offset();
 ASSERT_NE(-1, offset);

 pe.type = PERF_TYPE_TRACEPOINT;
 pe.size = sizeof(pe);
 pe.config = id;
 pe.sample_type = PERF_SAMPLE_RAW;
 pe.sample_period = 1;
 pe.wakeup_events = 1;

 /* Tracepoint attach should work */
 fd = perf_event_open(&pe, 0, -1, -1, 0);
 ASSERT_NE(-1, fd);

 perf_page = mmap(NULL, page_size * 2, PROT_READ, MAP_SHARED, fd, 0);
 ASSERT_NE(MAP_FAILED, perf_page);

 /* Status should be updated */
 ASSERT_EQ(1 << reg.enable_bit, self->check);

 event.index = reg.write_index;
 event.field1 = 0xc001;
 event.field2 = 0xc01a;

 /* Ensure write shows up at correct offset */
 ASSERT_NE(-1, write(self->data_fd, &event, sizeof(event)));
 val = (void *)(((char *)perf_page) + perf_page->data_offset);
 ASSERT_EQ(PERF_RECORD_SAMPLE, *val);
 /* Skip over header and size, move to offset */
 val += 3;
 val = (void *)((char *)val) + offset;
 /* Ensure correct */
 ASSERT_EQ(event.field1, *val++);
 ASSERT_EQ(event.field2, *val++);

 munmap(perf_page, page_size * 2);
 close(fd);

 /* Status should be updated */
 ASSERT_EQ(0, self->check);
}

TEST_F(user, perf_empty_events) {
 struct perf_event_attr pe = {0};
 struct user_reg reg = {0};
 struct perf_event_mmap_page *perf_page;
 int page_size = sysconf(_SC_PAGESIZE);
 int id, fd;
 __u32 *val;

 reg.size = sizeof(reg);
 reg.name_args = (__u64)"__test_event";
 reg.enable_bit = 31;
 reg.enable_addr = (__u64)&self->check;
 reg.enable_size = sizeof(self->check);

 /* Register should work */
 ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®));
 ASSERT_EQ(0, reg.write_index);
 ASSERT_EQ(0, self->check);

 /* Id should be there */
 id = get_id();
 ASSERT_NE(-1, id);

 pe.type = PERF_TYPE_TRACEPOINT;
 pe.size = sizeof(pe);
 pe.config = id;
 pe.sample_type = PERF_SAMPLE_RAW;
 pe.sample_period = 1;
 pe.wakeup_events = 1;

 /* Tracepoint attach should work */
 fd = perf_event_open(&pe, 0, -1, -1, 0);
 ASSERT_NE(-1, fd);

 perf_page = mmap(NULL, page_size * 2, PROT_READ, MAP_SHARED, fd, 0);
 ASSERT_NE(MAP_FAILED, perf_page);

 /* Status should be updated */
 ASSERT_EQ(1 << reg.enable_bit, self->check);

 /* Ensure write shows up at correct offset */
 ASSERT_NE(-1, write(self->data_fd, (void *)®.write_index,
     sizeof(reg.write_index)));
 val = (void *)(((char *)perf_page) + perf_page->data_offset);
 ASSERT_EQ(PERF_RECORD_SAMPLE, *val);

 munmap(perf_page, page_size * 2);
 close(fd);

 /* Status should be updated */
 ASSERT_EQ(0, self->check);
}

int main(int argc, char **argv)
{
 return test_harness_run(argc, argv);
}

Messung V0.5
C=94 H=95 G=94

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge