aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/block
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-03 18:58:55 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-03 18:58:55 +0000
commit91e1345d1c287e4798ecc2fc8ed20b0dd70e28c6 (patch)
treea07d9ed121ea2fa819347cba5e60cfbe00bc76ff /xen/drivers/block
parent40d269696c5de58c38df86d11f7debfb970c474d (diff)
downloadxen-91e1345d1c287e4798ecc2fc8ed20b0dd70e28c6.tar.gz
xen-91e1345d1c287e4798ecc2fc8ed20b0dd70e28c6.tar.bz2
xen-91e1345d1c287e4798ecc2fc8ed20b0dd70e28c6.zip
bitkeeper revision 1.160.1.1 (3e8c846fQSuOz1Dd8MgUzwG5rj3bDQ)
Many files: Free DOM0 kernel memory to Xen allocation pool after DOM0 is created. Fixed page-type handling -- we now correctly flush TLB if a page is unpinned after a disk read and refcnt falls to zero.
Diffstat (limited to 'xen/drivers/block')
-rw-r--r--xen/drivers/block/xen_block.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/xen/drivers/block/xen_block.c b/xen/drivers/block/xen_block.c
index 156dcbb94c..8901ee59fb 100644
--- a/xen/drivers/block/xen_block.c
+++ b/xen/drivers/block/xen_block.c
@@ -277,7 +277,8 @@ static int __buffer_is_valid(struct task_struct *p,
/* If reading into the frame, the frame must be writeable. */
if ( writeable_buffer &&
- ((page->flags & PG_type_mask) != PGT_writeable_page) )
+ ((page->flags & PG_type_mask) != PGT_writeable_page) &&
+ (page->type_count != 0) )
{
DPRINTK("non-writeable page passed for block read\n");
goto out;
@@ -301,7 +302,16 @@ static void __lock_buffer(unsigned long buffer,
pfn++ )
{
page = frame_table + pfn;
- if ( writeable_buffer ) get_page_type(page);
+ if ( writeable_buffer )
+ {
+ if ( page->type_count == 0 )
+ {
+ page->flags &= ~PG_type_mask;
+ /* NB. This ref alone won't cause a TLB flush. */
+ page->flags |= PGT_writeable_page | PG_noflush;
+ }
+ get_page_type(page);
+ }
get_page_tot(page);
}
}
@@ -320,8 +330,13 @@ static void unlock_buffer(struct task_struct *p,
pfn++ )
{
page = frame_table + pfn;
- if ( writeable_buffer && (put_page_type(page) == 0) )
- page->flags &= ~PG_type_mask;
+ if ( writeable_buffer &&
+ (put_page_type(page) == 0) &&
+ !(page->flags & PG_noflush) )
+ {
+ __flush_tlb();
+ }
+ page->flags &= ~PG_noflush;
put_page_tot(page);
}
spin_unlock_irqrestore(&p->page_lock, flags);