lkml.org 
[lkml]   [2016]   [Aug]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: DAX can not work on virtual nvdimm device
From
Date


On 08/31/2016 01:09 AM, Dan Williams wrote:

>
> Can you post your exact reproduction steps? This test is not failing for me.
>

Sure.

1. make the guest kernel based on your tree, the top commit is
10d7902fa0e82b (dax: unmap/truncate on device shutdown) and
the config file can be found in this thread.

2. add guest kernel command line: memmap=6G!10G

3: start the guest:
x86_64-softmmu/qemu-system-x86_64 -machine pc,nvdimm --enable-kvm \
-smp 16 -m 32G,maxmem=100G,slots=100 /other/VMs/centos6.img -monitor stdio

4: in guest:
mkfs.ext4 /dev/pmem0
mount -o dax /dev/pmem0 /mnt/pmem/
echo > /mnt/pmem/xxx
./mmap /mnt/pmem/xxx
./read /mnt/pmem/xxx

The source code of mmap and read has been attached in this mail.

Hopefully, you can detect the error triggered by read test.

Thanks!
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
char *filename;

if (argc < 2) {
printf("arg: filename.\n");
return -1;
}

filename = argv[1];
printf("test on %s.\n", filename);

int fd = open(filename, O_RDWR);

if (fd < 0) {
perror("open");
return -1;
}

int count = 0;

while (1) {
ssize_t ret;
char buf;

ret = read(fd, &buf, sizeof(buf));
if (ret < 0) {
perror("READ");
return -1;
}

if (ret == 0)
break;
if (ret != sizeof(buf)) {
printf("Count %x Ret %lx sizeof(buf) %lx.\n",
count, ret, sizeof(buf));
return -1;
}

count++;
printf("%c", buf);
}

printf("\n Good Read.\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

static void write_test(char *buf, int size)
{
int i;

printf("Try to write %p for %x size.\n", buf, size);
for (i = 0; i < size; i++)
buf[i] = (char)(i & 0xFF);
printf("Write Done.\n");
}

static void read_test(char *buf, int size)
{
int i;

printf("Try to read %p for %x size.\n", buf, size);
for (i = 0; i < size; i++)
if (buf[i] != (char)(i & 0xFF)) {
printf("Read Check failed.\n");
printf("Index %x, %c expect %x.\n", i, buf[i], i & 0xFF);
exit(-1);
}
printf("Read Done.\n");
}

static void fread_test(int fd, int size)
{
char buf;
int i;

i = lseek(fd, 0, SEEK_END);
printf("End: %x.\n", i);

i = lseek(fd, 0, SEEK_SET);
if (i != 0) {
perror("seek");
exit(-1);
}

printf("Try to fread fd=%d size %x sizeof(buf) %ld.\n", fd, size,
sizeof(buf));

for (i = 0; i < size; i++) {
int ret;

ret = read(fd, &buf, sizeof(buf));
if (ret != sizeof(buf)) {
printf("Read failed, offset %x, ret %d ftell %ld.\n",
i, ret, lseek(fd, 0, SEEK_CUR));
perror("read");
exit(-1);
}
if (buf != (char)(i & 0xFF)) {
printf("Read Check failed.\n");
printf("Index %x, %c expect %x.\n", i, buf, i & 0xFF);
exit (-1);
}
}

printf("Fread Done.\n");
}

int main(int argc, char *argv[])
{
char *filename;
char *buf;
int fd;

if (argc < 2) {
printf("arg: filename.\n");
return -1;
}

filename = argv[1];
printf("mmap test on %s.\n", filename);

fd = open(filename, O_RDWR);
if (fd < 0) {
perror("open");
return -1;
}

if (lseek(fd, 0x1000, SEEK_SET) != 0x1000) {
perror("seek");
return -1;
}

if (ftruncate(fd, 0x1000) != 0) {
perror("ftruncate");
return -1;
}

// return 0;

buf = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED) {
perror("mmap");
return -1;
}

write_test(buf, 0x1000);
read_test(buf, 0x1000);
msync(buf, 0x1000, MS_SYNC);
fread_test(fd, 0x1000);

close(fd);

return 0;
}
\
 
 \ /
  Last update: 2016-09-17 09:58    [W:0.086 / U:1.232 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site