From 0cf1887139eb1ce18d09f7be0567aa93d802040d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 19 Oct 2003 23:35:58 +0000 Subject: - SMPng lock the DRM. This is only partial -- there are a few code paths used by root (the X Server) which are not locked. However, it should deal with lost-IRQ issues on -current which I think people have been experiencing but I am unable to reproduce (though I understand why they would occur, because of a bug of mine). Note that most of the locking (DRM_LOCK()/UNLOCK()) is all covered by Giant still, so it doesn't matter yet. - Remove locking on FreeBSD-stable and NetBSD. These are covered by the fact that there is no reentrancy of the kernel except by interrupts, which are locked using spldrm()/splx() instead. --- bsd-core/drmP.h | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'bsd-core/drmP.h') diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index c39df162..67915374 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -180,7 +180,6 @@ typedef struct drm_freelist { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ - DRM_SPINTYPE lock; } drm_freelist_t; typedef struct drm_buf_entry { @@ -216,10 +215,17 @@ struct drm_file { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ - wait_queue_head_t lock_queue; /* Queue of blocked processes */ + int lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; +/* This structure, in the drm_device_t, is always initialized while the device + * is open. dev->dma_lock protects the incrementing of dev->buf_use, which + * when set marks that no further bufs may be allocated until device teardown + * occurs (when the last open of the device has closed). The high/low + * watermarks of bufs are only touched by the X Server, and thus not + * concurrently accessed, so no locking is needed. + */ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; @@ -311,8 +317,15 @@ struct drm_device { int flags; /* Flags to open(2) */ /* Locks */ - DRM_SPINTYPE count_lock; /* For open_count, buf_use, buf_alloc */ - struct lock dev_lock; /* For others */ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 +#if __HAVE_DMA + struct mtx dma_lock; /* protects dev->dma */ +#endif +#if __HAVE_IRQ + struct mtx irq_lock; /* protects irq condition checks */ +#endif + struct mtx dev_lock; /* protects everything else */ +#endif /* Usage Counters */ int open_count; /* Outstanding files open */ int buf_use; /* Buffers in use -- cannot alloc */ @@ -327,8 +340,8 @@ struct drm_device { drm_file_list_t files; drm_magic_head_t magiclist[DRM_HASH_SIZE]; - /* Memory management */ - drm_map_list_t *maplist; /* Linked list of regions */ + /* Linked list of mappable regions. Protected by dev_lock */ + drm_map_list_t *maplist; drm_local_map_t **context_sareas; int max_context; @@ -349,18 +362,13 @@ struct drm_device { #endif void *irqh; /* Handle from bus_setup_intr */ atomic_t context_flag; /* Context swapping flag */ - struct callout timer; /* Timer for delaying ctx switch */ int last_context; /* Last current context */ #if __FreeBSD_version >= 400005 struct task task; #endif #if __HAVE_VBL_IRQ - wait_queue_head_t vbl_queue; /* vbl wait channel */ + int vbl_queue; /* vbl wait channel */ atomic_t vbl_received; -#if 0 /* vbl signals are untested */ - struct drm_vbl_sig_list vbl_sig_list; - DRM_SPINTYPE vbl_lock; -#endif #endif #ifdef __FreeBSD__ @@ -382,11 +390,6 @@ struct drm_device { extern int DRM(flags); - /* Authentication (drm_auth.h) */ -extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, - drm_magic_t magic); -extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); - /* Driver support (drm_drv.h) */ extern int DRM(version)( DRM_IOCTL_ARGS ); -- cgit v1.2.3