NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

re: kern/41715



The following reply was made to PR kern/41715; it has been noted by GNATS.

From: matthew green <mrg%eterna.com.au@localhost>
To: kern-bug-people%netbsd.org@localhost, gnats-admin%netbsd.org@localhost,
    netbsd-bugs%netbsd.org@localhost, Thomas Klausner 
<wiz%NetBSD.org@localhost>,
    gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: re: kern/41715
Date: Fri, 07 Aug 2009 11:48:53 +1000

 OK, the problem is that mmio regs are being access when the device
 isn't open by the vblank callout.
 
 i've stopped it from doing that, and now i can't seem to get any
 crashes.
 
 my patch is below.  it inclues a work-around for drm_ioctl.c to
 get past a -current issue.  it also contains additional code to
 call drm_rmmap() when these mappings are throw away.. (this was
 the key to the dev_priv->mmio changing issue i was seeing.  there
 was no corruption.)
 
 
 there's a couple of other changes in there as well.  i need to
 look more closely at the callout_drain() change, and possible
 make it use the dev->vbl_lock.  and the callout* usage in
 vblank_disable_fn() could use some looking at.
 
 
 .mrg.
 
 
 Index: bsd-core/drmP.h
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drmP.h,v
 retrieving revision 1.12
 diff -p -r1.12 drmP.h
 *** bsd-core/drmP.h    20 Jun 2009 01:07:09 -0000      1.12
 --- bsd-core/drmP.h    7 Aug 2009 01:45:49 -0000
 *************** struct drm_file;
 *** 133,139 ****
   #define DRM_KASSERT(x,y)    KASSERT(x)
   #define device_get_softc(x)  device_private(x)
   #define callout_deactivate(x)        callout_stop(x)
 ! #define callout_drain(x)     callout_stop(x)
   #endif
   
   #if defined(DRM_LINUX) && DRM_LINUX && !defined(__amd64__)
 --- 133,139 ----
   #define DRM_KASSERT(x,y)    KASSERT(x)
   #define device_get_softc(x)  device_private(x)
   #define callout_deactivate(x)        callout_stop(x)
 ! #define callout_drain(x)     callout_halt(x, NULL)
   #endif
   
   #if defined(DRM_LINUX) && DRM_LINUX && !defined(__amd64__)
 *************** struct drm_file {
 *** 582,590 ****
        int               minor;
        pid_t             pid;
        uid_t             uid;
 - #if defined(__NetBSD__)
 -      int refs;
 - #endif
        drm_magic_t       magic;
        unsigned long     ioctl_count;
        void             *driver_priv;
 --- 582,587 ----
 Index: bsd-core/drm_fops.c
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drm_fops.c,v
 retrieving revision 1.5
 diff -p -r1.5 drm_fops.c
 *** bsd-core/drm_fops.c        20 Jun 2009 01:07:09 -0000      1.5
 --- bsd-core/drm_fops.c        7 Aug 2009 01:45:49 -0000
 *************** int drm_open_helper(dev_t kdev, int flag
 *** 70,78 ****
   
        DRM_LOCK();
        priv = drm_find_file_by_proc(dev, p);
 !      if (priv) {
 !              priv->refs++;
 !      } else {
                priv = malloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO);
                if (priv == NULL) {
                        DRM_UNLOCK();
 --- 70,76 ----
   
        DRM_LOCK();
        priv = drm_find_file_by_proc(dev, p);
 !      if (!priv) {
                priv = malloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO);
                if (priv == NULL) {
                        DRM_UNLOCK();
 *************** int drm_open_helper(dev_t kdev, int flag
 *** 81,87 ****
                priv->uid               = kauth_cred_getsvuid(p->p_cred);
                priv->pid               = p->p_pid;
   
 -              priv->refs              = 1;
                priv->minor             = m;
                priv->ioctl_count       = 0;
   
 --- 79,84 ----
 Index: bsd-core/drm_ioctl.c
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drm_ioctl.c,v
 retrieving revision 1.4
 diff -p -r1.4 drm_ioctl.c
 *** bsd-core/drm_ioctl.c       20 Jun 2009 01:07:09 -0000      1.4
 --- bsd-core/drm_ioctl.c       7 Aug 2009 01:45:49 -0000
 *************** drm_set_busid(struct drm_device *dev)
 *** 135,142 ****
 --- 135,147 ----
                return ENOMEM;
        }
   
 + #if 0
        snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x",
            dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
 + #else
 +      snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x",
 +          dev->pci_bus, dev->pci_bus, dev->pci_slot, dev->pci_func);
 + #endif
   
        DRM_UNLOCK();
   
 Index: bsd-core/drm_irq.c
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drm_irq.c,v
 retrieving revision 1.10
 diff -p -r1.10 drm_irq.c
 *** bsd-core/drm_irq.c 20 Jun 2009 01:07:09 -0000      1.10
 --- bsd-core/drm_irq.c 7 Aug 2009 01:45:49 -0000
 *************** void drm_vblank_cleanup(struct drm_devic
 *** 139,144 ****
 --- 139,148 ----
   
        vblank_disable_fn((void *)dev);
   
 + #if defined(__NetBSD__)
 +      callout_destroy(&dev->vblank_disable_timer);
 + #endif
 + 
        free(dev->vblank, DRM_MEM_DRIVER);
   
        dev->num_crtcs = 0;
 *************** void drm_vblank_put(struct drm_device *d
 *** 366,372 ****
   #if defined(__FreeBSD__)
                (timeout_t *)
   #endif
 !         vblank_disable_fn, (void *)dev);
        DRM_SPINUNLOCK_IRQRESTORE(&dev->vbl_lock, irqflags);
   }
   
 --- 370,376 ----
   #if defined(__FreeBSD__)
                (timeout_t *)
   #endif
 !                           vblank_disable_fn, (void *)dev);
        DRM_SPINUNLOCK_IRQRESTORE(&dev->vbl_lock, irqflags);
   }
   
 Index: bsd-core/drm_scatter.c
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drm_scatter.c,v
 retrieving revision 1.3
 diff -p -r1.3 drm_scatter.c
 *** bsd-core/drm_scatter.c     20 Jun 2009 01:07:09 -0000      1.3
 --- bsd-core/drm_scatter.c     7 Aug 2009 01:45:49 -0000
 *************** drm_sg_alloc(struct drm_device *dev, str
 *** 127,132 ****
 --- 127,133 ----
   
        dmah->tag = dev->pa.pa_dmat;
   
 +      DRM_DEBUG("going to bus_dmamem_alloc size=%lx pages=%lx\n", 
request->size, pages);
        if ((ret = bus_dmamem_alloc(dmah->tag, request->size, PAGE_SIZE, 0,
                                    dmah->segs, pages, &nsegs,
                                    BUS_DMA_WAITOK) != 0)) {
 Index: shared-core/radeon_cp.c
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/shared-core/radeon_cp.c,v
 retrieving revision 1.5
 diff -p -r1.5 radeon_cp.c
 *** shared-core/radeon_cp.c    20 Jun 2009 01:07:10 -0000      1.5
 --- shared-core/radeon_cp.c    7 Aug 2009 01:45:49 -0000
 *************** static int radeon_do_cleanup_cp(struct d
 *** 1401,1406 ****
 --- 1401,1412 ----
                        dev_priv->gart_info.addr = 0;
                }
        }
 + 
 +      if (dev_priv->mmio)
 +              drm_rmmap(dev, dev_priv->mmio);
 +      if (dev_priv->fb_map)
 +              drm_rmmap(dev, dev_priv->fb_map);
 + 
        /* only clear to the start of flags */
        memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
   
 *************** int radeon_driver_load(struct drm_device
 *** 2021,2027 ****
   int radeon_driver_firstopen(struct drm_device *dev)
   {
        int ret;
 -      drm_local_map_t *map;
        drm_radeon_private_t *dev_priv = dev->dev_private;
   
        dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
 --- 2027,2032 ----
 *************** int radeon_driver_firstopen(struct drm_d
 *** 2035,2041 ****
        dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
        ret = drm_addmap(dev, dev_priv->fb_aper_offset,
                         drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
 !                       _DRM_WRITE_COMBINING, &map);
        if (ret != 0)
                return ret;
   
 --- 2040,2046 ----
        dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
        ret = drm_addmap(dev, dev_priv->fb_aper_offset,
                         drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
 !                       _DRM_WRITE_COMBINING, &dev_priv->fb_map);
        if (ret != 0)
                return ret;
   
 Index: shared-core/radeon_drv.h
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/shared-core/radeon_drv.h,v
 retrieving revision 1.5
 diff -p -r1.5 radeon_drv.h
 *** shared-core/radeon_drv.h   19 Jun 2009 03:50:05 -0000      1.5
 --- shared-core/radeon_drv.h   7 Aug 2009 01:45:49 -0000
 *************** typedef struct drm_radeon_private {
 *** 296,301 ****
 --- 296,302 ----
   
        drm_local_map_t *sarea;
        drm_local_map_t *mmio;
 +      drm_local_map_t *fb_map;
        drm_local_map_t *cp_ring;
        drm_local_map_t *ring_rptr;
        drm_local_map_t *gart_textures;
 Index: shared-core/radeon_irq.c
 ===================================================================
 RCS file: /cvsroot/src/sys/external/bsd/drm/dist/shared-core/radeon_irq.c,v
 retrieving revision 1.2
 diff -p -r1.2 radeon_irq.c
 *** shared-core/radeon_irq.c   19 Jun 2009 03:50:05 -0000      1.2
 --- shared-core/radeon_irq.c   7 Aug 2009 01:45:49 -0000
 *************** int radeon_enable_vblank(struct drm_devi
 *** 65,70 ****
 --- 65,73 ----
   {
        drm_radeon_private_t *dev_priv = dev->dev_private;
   
 +      if (!dev_priv->mmio)
 +              return 0;
 + 
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {     
                switch (crtc) {
                case 0:
 *************** void radeon_disable_vblank(struct drm_de
 *** 100,105 ****
 --- 103,111 ----
   {
        drm_radeon_private_t *dev_priv = dev->dev_private;
   
 +      if (!dev_priv->mmio)
 +              return;
 + 
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {     
                switch (crtc) {
                case 0:
 *************** u32 radeon_get_vblank_counter(struct drm
 *** 289,294 ****
 --- 295,302 ----
                DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
 +      if (!dev_priv->mmio)
 +              return 0;
   
        if (crtc < 0 || crtc > 1) {
                DRM_ERROR("Invalid crtc %d\n", crtc);
 *************** int radeon_irq_emit(struct drm_device *d
 *** 322,327 ****
 --- 330,337 ----
                DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
 +      if (!dev_priv->mmio)
 +              return 0;
   
        result = radeon_emit_irq(dev);
   
 *************** int radeon_irq_wait(struct drm_device *d
 *** 344,349 ****
 --- 354,361 ----
                DRM_ERROR("called with no initialization\n");
                return -EINVAL;
        }
 +      if (!dev_priv->mmio)
 +              return 0;
   
        return radeon_wait_irq(dev, irqwait->irq_seq);
   }
 


Home | Main Index | Thread Index | Old Index