2008-08-21 02:37:56

by Shaohua Li

[permalink] [raw]
Subject: [3/4] add agp_generic_destroy_pages()

Add agp_generic_destroy_pages(), it uses new pageattr array interface API.

Signed-off-by: Dave Airlie <[email protected]>
Signed-off-by: Shaohua Li <[email protected]>
---
drivers/char/agp/agp.h | 2 +
drivers/char/agp/generic.c | 55 ++++++++++++++++++++++++++++++++++++-------
drivers/char/agp/intel-agp.c | 14 ++++++++++
3 files changed, 63 insertions(+), 8 deletions(-)

Index: linux/drivers/char/agp/agp.h
===================================================================
--- linux.orig/drivers/char/agp/agp.h 2008-08-21 10:00:05.000000000 +0800
+++ linux/drivers/char/agp/agp.h 2008-08-21 10:01:40.000000000 +0800
@@ -118,6 +118,7 @@ struct agp_bridge_driver {
void *(*agp_alloc_page)(struct agp_bridge_data *);
int (*agp_alloc_pages)(struct agp_bridge_data *, struct agp_memory *, size_t);
void (*agp_destroy_page)(void *, int flags);
+ void (*agp_destroy_pages)(struct agp_memory *);
int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
void (*chipset_flush)(struct agp_bridge_data *);
};
@@ -281,6 +282,7 @@ void *agp_generic_alloc_page(struct agp_
int agp_generic_alloc_pages(struct agp_bridge_data *agp_bridge,
struct agp_memory *memory, size_t page_count);
void agp_generic_destroy_page(void *addr, int flags);
+void agp_generic_destroy_pages(struct agp_memory *memory);
void agp_free_key(int key);
int agp_num_entries(void);
u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command);
Index: linux/drivers/char/agp/generic.c
===================================================================
--- linux.orig/drivers/char/agp/generic.c 2008-08-21 10:01:34.000000000 +0800
+++ linux/drivers/char/agp/generic.c 2008-08-21 10:01:40.000000000 +0800
@@ -201,14 +201,22 @@ void agp_free_memory(struct agp_memory *
return;
}
if (curr->page_count != 0) {
- for (i = 0; i < curr->page_count; i++) {
- curr->memory[i] = (unsigned long)gart_to_virt(curr->memory[i]);
- curr->bridge->driver->agp_destroy_page((void *)curr->memory[i],
- AGP_PAGE_DESTROY_UNMAP);
- }
- for (i = 0; i < curr->page_count; i++) {
- curr->bridge->driver->agp_destroy_page((void *)curr->memory[i],
- AGP_PAGE_DESTROY_FREE);
+ if (curr->bridge->driver->agp_destroy_pages) {
+ curr->bridge->driver->agp_destroy_pages(curr);
+ } else {
+
+ for (i = 0; i < curr->page_count; i++) {
+ curr->memory[i] = (unsigned long)gart_to_virt(
+ curr->memory[i]);
+ curr->bridge->driver->agp_destroy_page(
+ (void *)curr->memory[i],
+ AGP_PAGE_DESTROY_UNMAP);
+ }
+ for (i = 0; i < curr->page_count; i++) {
+ curr->bridge->driver->agp_destroy_page(
+ (void *)curr->memory[i],
+ AGP_PAGE_DESTROY_FREE);
+ }
}
}
agp_free_key(curr->key);
@@ -1261,6 +1269,37 @@ void *agp_generic_alloc_page(struct agp_
}
EXPORT_SYMBOL(agp_generic_alloc_page);

+void agp_generic_destroy_pages(struct agp_memory *mem)
+{
+ int i;
+ void *addr;
+ struct page *page;
+
+ if (!mem)
+ return;
+
+ for (i = 0; i < mem->page_count; i++)
+ mem->memory[i] = (unsigned long)gart_to_virt(mem->memory[i]);
+
+#ifdef CONFIG_X86
+ set_memory_array_wb(mem->memory, mem->page_count);
+#endif
+
+ for (i = 0; i < mem->page_count; i++) {
+ addr = (void *)mem->memory[i];
+ page = virt_to_page(addr);
+
+#ifndef CONFIG_X86
+ unmap_page_from_agp(page);
+#endif
+
+ put_page(page);
+ free_page((unsigned long)addr);
+ atomic_dec(&agp_bridge->current_memory_agp);
+ mem->memory[i] = 0;
+ }
+}
+EXPORT_SYMBOL(agp_generic_destroy_pages);

void agp_generic_destroy_page(void *addr, int flags)
{
Index: linux/drivers/char/agp/intel-agp.c
===================================================================
--- linux.orig/drivers/char/agp/intel-agp.c 2008-08-21 10:00:05.000000000 +0800
+++ linux/drivers/char/agp/intel-agp.c 2008-08-21 10:01:41.000000000 +0800
@@ -1713,6 +1713,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1739,6 +1740,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1764,6 +1766,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1790,6 +1793,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
.chipset_flush = intel_i830_chipset_flush,
};
@@ -1816,6 +1820,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1841,6 +1846,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1866,6 +1872,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1891,6 +1898,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
.chipset_flush = intel_i830_chipset_flush,
};
@@ -1917,6 +1925,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1942,6 +1951,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -1968,6 +1978,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
.chipset_flush = intel_i915_chipset_flush,
};
@@ -1995,6 +2006,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
.chipset_flush = intel_i915_chipset_flush,
};
@@ -2021,6 +2033,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

@@ -2047,6 +2060,7 @@ static const struct agp_bridge_driver in
.agp_alloc_page = agp_generic_alloc_page,
.agp_alloc_pages = agp_generic_alloc_pages,
.agp_destroy_page = agp_generic_destroy_page,
+ .agp_destroy_pages = agp_generic_destroy_pages,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
.chipset_flush = intel_i915_chipset_flush,
};


2008-08-21 03:08:51

by Andrew Morton

[permalink] [raw]
Subject: Re: [3/4] add agp_generic_destroy_pages()

On Thu, 21 Aug 2008 10:46:17 +0800 Shaohua Li <[email protected]> wrote:

> --- linux.orig/drivers/char/agp/generic.c 2008-08-21 10:01:34.000000000 +0800
> +++ linux/drivers/char/agp/generic.c 2008-08-21 10:01:40.000000000 +0800
> @@ -201,14 +201,22 @@ void agp_free_memory(struct agp_memory *
> return;
> }
> if (curr->page_count != 0) {
> - for (i = 0; i < curr->page_count; i++) {
> - curr->memory[i] = (unsigned long)gart_to_virt(curr->memory[i]);
> - curr->bridge->driver->agp_destroy_page((void *)curr->memory[i],
> - AGP_PAGE_DESTROY_UNMAP);
> - }
> - for (i = 0; i < curr->page_count; i++) {
> - curr->bridge->driver->agp_destroy_page((void *)curr->memory[i],
> - AGP_PAGE_DESTROY_FREE);
> + if (curr->bridge->driver->agp_destroy_pages) {
> + curr->bridge->driver->agp_destroy_pages(curr);
> + } else {

stylistic nit:

> +
> + for (i = 0; i < curr->page_count; i++) {
> + curr->memory[i] = (unsigned long)gart_to_virt(
> + curr->memory[i]);
> + curr->bridge->driver->agp_destroy_page(
> + (void *)curr->memory[i],
> + AGP_PAGE_DESTROY_UNMAP);
> + }
> + for (i = 0; i < curr->page_count; i++) {
> + curr->bridge->driver->agp_destroy_page(
> + (void *)curr->memory[i],
> + AGP_PAGE_DESTROY_FREE);
> + }

Make the above code a standalone function and call it here.

Then convert all drivers over so their .agp_destroy_pages points at
that new function.

Then remove the `if'.

2008-08-21 11:50:22

by Ingo Molnar

[permalink] [raw]
Subject: Re: [3/4] add agp_generic_destroy_pages()


* Andrew Morton <[email protected]> wrote:

> stylistic nit:
>
> > +
> > + for (i = 0; i < curr->page_count; i++) {
> > + curr->memory[i] = (unsigned long)gart_to_virt(
> > + curr->memory[i]);
> > + curr->bridge->driver->agp_destroy_page(
> > + (void *)curr->memory[i],
> > + AGP_PAGE_DESTROY_UNMAP);
> > + }
> > + for (i = 0; i < curr->page_count; i++) {
> > + curr->bridge->driver->agp_destroy_page(
> > + (void *)curr->memory[i],
> > + AGP_PAGE_DESTROY_FREE);
> > + }
>
> Make the above code a standalone function and call it here.
>
> Then convert all drivers over so their .agp_destroy_pages points at
> that new function.
>
> Then remove the `if'.

good point.

[ Shaohua, when you fix this, please do it as a delta patch against your
current patchset (or against tip/master). Thanks. ]

Ingo