From owner-svn-src-all@FreeBSD.ORG Wed Jul 11 19:12:11 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 366031065675; Wed, 11 Jul 2012 19:12:11 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 174AF8FC1A; Wed, 11 Jul 2012 19:12:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q6BJCASC060516; Wed, 11 Jul 2012 19:12:10 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q6BJCAUT060514; Wed, 11 Jul 2012 19:12:10 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201207111912.q6BJCAUT060514@svn.freebsd.org> From: Konstantin Belousov Date: Wed, 11 Jul 2012 19:12:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r238374 - head/tools/test/upsdl X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Jul 2012 19:12:11 -0000 Author: kib Date: Wed Jul 11 19:12:10 2012 New Revision: 238374 URL: http://svn.freebsd.org/changeset/base/238374 Log: Add a test program, written by Stephan Uphoff, which demonstrates the deadlock due to i/o performed over the buffers backed by file mappings. MFC after: 2 weeks Approved by: ups Added: head/tools/test/upsdl/ head/tools/test/upsdl/Makefile (contents, props changed) head/tools/test/upsdl/upsdl.c (contents, props changed) Added: head/tools/test/upsdl/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/test/upsdl/Makefile Wed Jul 11 19:12:10 2012 (r238374) @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= upsdl +NO_MAN= + +.include Added: head/tools/test/upsdl/upsdl.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/test/upsdl/upsdl.c Wed Jul 11 19:12:10 2012 (r238374) @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2006, Stephan Uphoff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + + +#include +#include +#include +#include +#include +#include + + +int prepareFile(char* filename,int* fdp); +int mapBuffer(char** bufferp,int fd1,int fd2); +int startIO(int fd,char *buffer); + +int pagesize; + +#define FILESIZE (32*1024) +char wbuffer[FILESIZE]; + +/* Create a FILESIZE sized file - then remove file data from the cache*/ +int prepareFile(char* filename,int* fdp) +{ + int fd; + int len; + int status; + void *addr; + + fd = open(filename,O_CREAT | O_TRUNC | O_RDWR,S_IRWXU); + if (fd == -1) + { + perror("Creating file"); + return fd; + } + + len = write(fd,wbuffer,FILESIZE); + if (len < 0) + { + perror("Write failed"); + return 1; + } + + status = fsync(fd); + if (status != 0) + { + perror("fsync failed"); + return 1; + } + + addr = mmap(NULL,FILESIZE, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) + { + perror("Mmap failed"); + return 1; + } + + status = msync(addr,FILESIZE,MS_INVALIDATE | MS_SYNC); + if (status != 0) + { + perror("Msync failed"); + return 1; + } + + munmap(addr,FILESIZE); + + *fdp = fd; + return 0; +} + + +/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */ +int mapBuffer(char** bufferp,int fd1,int fd2) +{ + void* addr; + char *buffer; + + addr = mmap(NULL,pagesize*2, PROT_READ | PROT_WRITE , MAP_SHARED, fd1, 0); + if (addr == MAP_FAILED) + { + perror("Mmap failed"); + return 1; + } + + buffer = addr; + addr = mmap(buffer + pagesize,pagesize, PROT_READ | PROT_WRITE , MAP_FIXED | +MAP_SHARED, fd2, 0); + + if (addr == MAP_FAILED) + { + perror("Mmap2 failed"); + return 1; + } + *bufferp = buffer; + return 0; +} + + +int startIO(int fd,char *buffer) +{ + ssize_t len; + len = write(fd,buffer,2*pagesize); + if (len == -1) + { + perror("write failed"); + return 1; + } + return 0; +} + + +int main(int argc,char *argv[],char *envp[]) +{ + + int fdA,fdB,fdDelayA,fdDelayB; + int status; + char *bufferA,*bufferB; + pid_t pid; + + pagesize = getpagesize(); + + if ((prepareFile("A",&fdA)) + || (prepareFile("B",&fdB)) + || (prepareFile("DelayA",&fdDelayA)) + || (prepareFile("DelayB",&fdDelayB)) + || (mapBuffer(&bufferA,fdDelayA,fdB)) + || (mapBuffer(&bufferB,fdDelayB,fdA))) + exit(1); + + pid = fork(); + + if (pid == 0) + { + status = startIO(fdA,bufferA); + exit(status); + } + + if (pid == -1) + { + exit(1); + } + status = startIO(fdB,bufferB); + exit(status); + +} + + + + +