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


Quelle  udmabuf.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#define __EXPORTED_HEADERS__

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdbool.h>

#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <linux/memfd.h>
#include <linux/udmabuf.h>
#include "../../kselftest.h"

#define TEST_PREFIX "drivers/dma-buf/udmabuf"
#define NUM_PAGES       4
#define NUM_ENTRIES     4
#define MEMFD_SIZE      1024 /* in pages */

static unsigned int page_size;

static int create_memfd_with_seals(off64_t size, bool hpage)
{
 int memfd, ret;
 unsigned int flags = MFD_ALLOW_SEALING;

 if (hpage)
  flags |= MFD_HUGETLB;

 memfd = memfd_create("udmabuf-test", flags);
 if (memfd < 0) {
  ksft_print_msg("%s: [skip,no-memfd]\n", TEST_PREFIX);
  exit(KSFT_SKIP);
 }

 ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK);
 if (ret < 0) {
  ksft_print_msg("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX);
  exit(KSFT_SKIP);
 }

 ret = ftruncate(memfd, size);
 if (ret == -1) {
  ksft_print_msg("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX);
  exit(KSFT_FAIL);
 }

 return memfd;
}

static int create_udmabuf_list(int devfd, int memfd, off64_t memfd_size)
{
 struct udmabuf_create_list *list;
 int ubuf_fd, i;

 list = malloc(sizeof(struct udmabuf_create_list) +
        sizeof(struct udmabuf_create_item) * NUM_ENTRIES);
 if (!list) {
  ksft_print_msg("%s: [FAIL, udmabuf-malloc]\n", TEST_PREFIX);
  exit(KSFT_FAIL);
 }

 for (i = 0; i < NUM_ENTRIES; i++) {
  list->list[i].memfd  = memfd;
  list->list[i].offset = i * (memfd_size / NUM_ENTRIES);
  list->list[i].size   = getpagesize() * NUM_PAGES;
 }

 list->count = NUM_ENTRIES;
 list->flags = UDMABUF_FLAGS_CLOEXEC;
 ubuf_fd = ioctl(devfd, UDMABUF_CREATE_LIST, list);
 free(list);
 if (ubuf_fd < 0) {
  ksft_print_msg("%s: [FAIL, udmabuf-create]\n", TEST_PREFIX);
  exit(KSFT_FAIL);
 }

 return ubuf_fd;
}

static void write_to_memfd(void *addr, off64_t size, char chr)
{
 int i;

 for (i = 0; i < size / page_size; i++) {
  *((char *)addr + (i * page_size)) = chr;
 }
}

static void *mmap_fd(int fd, off64_t size)
{
 void *addr;

 addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 if (addr == MAP_FAILED) {
  ksft_print_msg("%s: ubuf_fd mmap fail\n", TEST_PREFIX);
  exit(KSFT_FAIL);
 }

 return addr;
}

static int compare_chunks(void *addr1, void *addr2, off64_t memfd_size)
{
 off64_t off;
 int i = 0, j, k = 0, ret = 0;
 char char1, char2;

 while (i < NUM_ENTRIES) {
  off = i * (memfd_size / NUM_ENTRIES);
  for (j = 0; j < NUM_PAGES; j++, k++) {
   char1 = *((char *)addr1 + off + (j * getpagesize()));
   char2 = *((char *)addr2 + (k * getpagesize()));
   if (char1 != char2) {
    ret = -1;
    goto err;
   }
  }
  i++;
 }
err:
 munmap(addr1, memfd_size);
 munmap(addr2, NUM_ENTRIES * NUM_PAGES * getpagesize());
 return ret;
}

int main(int argc, char *argv[])
{
 struct udmabuf_create create;
 int devfd, memfd, buf, ret;
 off64_t size;
 void *addr1, *addr2;

 ksft_print_header();
 ksft_set_plan(7);

 devfd = open("/dev/udmabuf", O_RDWR);
 if (devfd < 0) {
  ksft_print_msg(
   "%s: [skip,no-udmabuf: Unable to access DMA buffer device file]\n",
   TEST_PREFIX);
  exit(KSFT_SKIP);
 }

 memfd = memfd_create("udmabuf-test", MFD_ALLOW_SEALING);
 if (memfd < 0) {
  ksft_print_msg("%s: [skip,no-memfd]\n", TEST_PREFIX);
  exit(KSFT_SKIP);
 }

 ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK);
 if (ret < 0) {
  ksft_print_msg("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX);
  exit(KSFT_SKIP);
 }

 size = getpagesize() * NUM_PAGES;
 ret = ftruncate(memfd, size);
 if (ret == -1) {
  ksft_print_msg("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX);
  exit(KSFT_FAIL);
 }

 memset(&create, 0, sizeof(create));

 /* should fail (offset not page aligned) */
 create.memfd  = memfd;
 create.offset = getpagesize()/2;
 create.size   = getpagesize();
 buf = ioctl(devfd, UDMABUF_CREATE, &create);
 if (buf >= 0)
  ksft_test_result_fail("%s: [FAIL,test-1]\n", TEST_PREFIX);
 else
  ksft_test_result_pass("%s: [PASS,test-1]\n", TEST_PREFIX);

 /* should fail (size not multiple of page) */
 create.memfd  = memfd;
 create.offset = 0;
 create.size   = getpagesize()/2;
 buf = ioctl(devfd, UDMABUF_CREATE, &create);
 if (buf >= 0)
  ksft_test_result_fail("%s: [FAIL,test-2]\n", TEST_PREFIX);
 else
  ksft_test_result_pass("%s: [PASS,test-2]\n", TEST_PREFIX);

 /* should fail (not memfd) */
 create.memfd  = 0; /* stdin */
 create.offset = 0;
 create.size   = size;
 buf = ioctl(devfd, UDMABUF_CREATE, &create);
 if (buf >= 0)
  ksft_test_result_fail("%s: [FAIL,test-3]\n", TEST_PREFIX);
 else
  ksft_test_result_pass("%s: [PASS,test-3]\n", TEST_PREFIX);

 /* should work */
 page_size = getpagesize();
 addr1 = mmap_fd(memfd, size);
 write_to_memfd(addr1, size, 'a');
 create.memfd  = memfd;
 create.offset = 0;
 create.size   = size;
 buf = ioctl(devfd, UDMABUF_CREATE, &create);
 if (buf < 0)
  ksft_test_result_fail("%s: [FAIL,test-4]\n", TEST_PREFIX);
 else
  ksft_test_result_pass("%s: [PASS,test-4]\n", TEST_PREFIX);

 munmap(addr1, size);
 close(buf);
 close(memfd);

 /* should work (migration of 4k size pages)*/
 size = MEMFD_SIZE * page_size;
 memfd = create_memfd_with_seals(size, false);
 addr1 = mmap_fd(memfd, size);
 write_to_memfd(addr1, size, 'a');
 buf = create_udmabuf_list(devfd, memfd, size);
 addr2 = mmap_fd(buf, NUM_PAGES * NUM_ENTRIES * getpagesize());
 write_to_memfd(addr1, size, 'b');
 ret = compare_chunks(addr1, addr2, size);
 if (ret < 0)
  ksft_test_result_fail("%s: [FAIL,test-5]\n", TEST_PREFIX);
 else
  ksft_test_result_pass("%s: [PASS,test-5]\n", TEST_PREFIX);

 close(buf);
 close(memfd);

 /* should work (migration of 2MB size huge pages)*/
 page_size = getpagesize() * 512; /* 2 MB */
 size = MEMFD_SIZE * page_size;
 memfd = create_memfd_with_seals(size, true);
 addr1 = mmap_fd(memfd, size);
 write_to_memfd(addr1, size, 'a');
 buf = create_udmabuf_list(devfd, memfd, size);
 addr2 = mmap_fd(buf, NUM_PAGES * NUM_ENTRIES * getpagesize());
 write_to_memfd(addr1, size, 'b');
 ret = compare_chunks(addr1, addr2, size);
 if (ret < 0)
  ksft_test_result_fail("%s: [FAIL,test-6]\n", TEST_PREFIX);
 else
  ksft_test_result_pass("%s: [PASS,test-6]\n", TEST_PREFIX);

 close(buf);
 close(memfd);

 /* same test as above but we pin first before writing to memfd */
 page_size = getpagesize() * 512; /* 2 MB */
 size = MEMFD_SIZE * page_size;
 memfd = create_memfd_with_seals(size, true);
 buf = create_udmabuf_list(devfd, memfd, size);
 addr2 = mmap_fd(buf, NUM_PAGES * NUM_ENTRIES * getpagesize());
 addr1 = mmap_fd(memfd, size);
 write_to_memfd(addr1, size, 'a');
 write_to_memfd(addr1, size, 'b');
 ret = compare_chunks(addr1, addr2, size);
 if (ret < 0)
  ksft_test_result_fail("%s: [FAIL,test-7]\n", TEST_PREFIX);
 else
  ksft_test_result_pass("%s: [PASS,test-7]\n", TEST_PREFIX);

 close(buf);
 close(memfd);
 close(devfd);

 ksft_print_msg("%s: ok\n", TEST_PREFIX);
 ksft_print_cnts();

 return 0;
}

Messung V0.5
C=96 H=92 G=93

¤ Dauer der Verarbeitung: 0.8 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


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