aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/agp.h
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2007-10-14 20:19:16 -0400
committerDave Airlie <airlied@optimus.(none)>2007-10-14 20:32:15 -0400
commita2721e998ede079db10f65e4b42310f79dc8f135 (patch)
tree32963c9bf40f3e0871d4d549bb6c3cf13abbb24c /drivers/char/agp/agp.h
parent23fd50450a34f2558070ceabb0bfebc1c9604af5 (diff)
AGP fix race condition between unmapping and freeing pages
With Andi's clflush fixup, we were getting hangs on server exit, flushing the mappings after freeing each page helped. This showed up a race condition where the pages after being freed could be reused before the agp mappings had been flushed. Flushing after each single page is a bad thing for future drm work, so make the page destroy a two pass unmapping all the pages, flushing the mappings, and then destroying the pages. Signed-off-by: Dave Airlie <airlied@linux.ie> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'drivers/char/agp/agp.h')
-rw-r--r--drivers/char/agp/agp.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 8955e7ff759a..b83824c41329 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -58,6 +58,9 @@ struct gatt_mask {
58 * devices this will probably be ignored */ 58 * devices this will probably be ignored */
59}; 59};
60 60
61#define AGP_PAGE_DESTROY_UNMAP 1
62#define AGP_PAGE_DESTROY_FREE 2
63
61struct aper_size_info_8 { 64struct aper_size_info_8 {
62 int size; 65 int size;
63 int num_entries; 66 int num_entries;
@@ -113,7 +116,7 @@ struct agp_bridge_driver {
113 struct agp_memory *(*alloc_by_type) (size_t, int); 116 struct agp_memory *(*alloc_by_type) (size_t, int);
114 void (*free_by_type)(struct agp_memory *); 117 void (*free_by_type)(struct agp_memory *);
115 void *(*agp_alloc_page)(struct agp_bridge_data *); 118 void *(*agp_alloc_page)(struct agp_bridge_data *);
116 void (*agp_destroy_page)(void *); 119 void (*agp_destroy_page)(void *, int flags);
117 int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); 120 int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
118}; 121};
119 122
@@ -267,7 +270,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type);
267struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); 270struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
268void agp_generic_free_by_type(struct agp_memory *curr); 271void agp_generic_free_by_type(struct agp_memory *curr);
269void *agp_generic_alloc_page(struct agp_bridge_data *bridge); 272void *agp_generic_alloc_page(struct agp_bridge_data *bridge);
270void agp_generic_destroy_page(void *addr); 273void agp_generic_destroy_page(void *addr, int flags);
271void agp_free_key(int key); 274void agp_free_key(int key);
272int agp_num_entries(void); 275int agp_num_entries(void);
273u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); 276u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command);