<div dir="ltr">I wrote a unit test that basically exercises the dumb buffer IOCTL to verify that I can create and destroy dumb buffers without any problems. All of my tests pass except for one test, on the nouveau driver. <div><br></div><div>Right now I am testing on an nVidia K2000, which can support two monitors. If I allocate three buffers at 4096, 4096, attempts to access the third buffer causes a "Bus error" to occur. All of the IOCTLs, mmaps, and DRM API calls pass without error. You don't see a problem until you attempt to access the buffer itself. I have included a simple test case that demonstrates this. </div><div><br></div><div>Up front, I am aware that the test case doesn't clean up as this is part of the test (allocating more than one buffer). I am also aware that I am allocating more buffers than I need (as only two monitors are supported). My reason for bringing this up is that you would expect that if the nVidia card ran out of memory to map in, it would error out on one of the IOCTLs. </div><div><br></div><div>#define _FILE_OFFSET_BITS 64</div><div><br></div><div>// Generic Includes</div><div>#include <sys/ioctl.h></div><div>#include <sys/types.h></div><div>#include <sys/stat.h></div><div>#include <sys/mman.h></div><div>#include <stdbool.h></div><div>#include <stdint.h></div><div>#include <stdlib.h></div><div>#include <unistd.h></div><div>#include <getopt.h></div><div>#include <string.h></div><div>#include <fcntl.h></div><div>#include <stdio.h></div><div>#include <error.h></div><div>#include <errno.h></div><div><br></div><div>// LibDRM</div><div>#include <xf86drm.h></div><div>#include <xf86drmMode.h></div><div><br></div><div>int fd;</div><div><br></div><div>void allocate_buffer(int width, int height)</div><div>{</div><div>    unsigned int *mVaddr;</div><div>    int mSize, mStride, mHandle, mFb;</div><div>    struct drm_mode_create_dumb create_arg;</div><div>    struct drm_mode_map_dumb map_arg;</div><div><br></div><div>    // Clear the arg buffers. </div><div>    memset(&create_arg, 0, sizeof(create_arg));</div><div>    memset(&map_arg, 0, sizeof(map_arg));</div><div><br></div><div>    // ------------------------------------------------------------------------</div><div>    // Allocate</div><div><br></div><div>    // Fill in the arguments for the IOCTL. Note that we only support 32bpp</div><div>    // dumb buffers so that is hard coded here. </div><div>    create_arg.width = width;</div><div>    create_arg.height = height;</div><div>    create_arg.bpp = 32;</div><div><br></div><div>    // Allocate the dumb buffer</div><div>    if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg))</div><div>    {</div><div>        printf("Failed: DRM_IOCTL_MODE_CREATE_DUMB\r\n");</div><div>        return;</div><div>    }</div><div><br></div><div>    // Store the dumb buffer properties. </div><div>    mSize = create_arg.size;</div><div>    mStride = create_arg.pitch;</div><div>    mHandle = create_arg.handle;</div><div><br></div><div>    // ------------------------------------------------------------------------</div><div>    // Map</div><div><br></div><div>    // Fill in the arguments for the IOCTL. </div><div>    map_arg.handle = mHandle;</div><div><br></div><div>    // Allocate the dumb buffer</div><div>    if (drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg))</div><div>    {</div><div>        printf("Failed: DRM_IOCTL_MODE_MAP_DUMB\r\n");</div><div>        return;</div><div>    }</div><div><br></div><div>    // Store the mapped memory</div><div>    if ((mVaddr = (unsigned int *)mmap(0, mSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_arg.offset)) == MAP_FAILED)</div><div>    {</div><div>        // Need to clear out the address so that we don't try to use it. </div><div>        mVaddr = NULL;</div><div><br></div><div>        // Error out.</div><div>        printf("Failed: mmap\r\n");</div><div>        return;</div><div>    }</div><div><br></div><div>    // ------------------------------------------------------------------------</div><div>    // Add to DRM</div><div>    </div><div>    if(drmModeAddFB(fd, width, height, 24, 32, mStride, mHandle, &mFb))</div><div>    {</div><div>        printf("Failed: drmModeAddFB\r\n");</div><div>        return;</div><div>    }</div><div><br></div><div>    printf("allocated buffer: (%p) width=%d height=%d\r\n", mVaddr, width, height);</div><div>    mVaddr[0] = 0x10101010;</div><div>    printf("  - touched buffer: (%p)\r\n", mVaddr);</div><div><br></div><div>}</div><div><br></div><div>main()</div><div>{</div><div><span class="" style="white-space:pre"> </span>if ((fd = open("/dev/dri/card1", O_RDWR)) == -1)</div><div><span class="" style="white-space:pre"> </span>{</div><div><span class="" style="white-space:pre">          </span>printf("open failed\r\n");</div><div><span class="" style="white-space:pre">               </span>exit(1);</div><div><span class="" style="white-space:pre">   </span>}</div><div><br></div><div>    allocate_buffer(4096, 4096);</div><div>    allocate_buffer(4096, 4096);</div><div>    allocate_buffer(4096, 4096);</div><div>    allocate_buffer(4096, 4096);</div><div>    allocate_buffer(4096, 4096);</div><div>    allocate_buffer(4096, 4096);</div><div>    allocate_buffer(4096, 4096);</div><div>    allocate_buffer(4096, 4096);</div><div><br></div><div><span class="" style="white-space:pre">        </span>close(fd);</div><div>} </div></div>