From d61e9aac96317a43c192f1faabfa95d4d675b7ce Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 10 Dec 2008 09:31:02 -0600 Subject: dlm: replace schedule with cond_resched This is a one-liner to use cond_resched() rather than schedule() in the ast delivery loop. It should not be necessary to schedule every time, so this will save some cpu time while continuing to allow scheduling when required. Signed-off-by: Steven Whitehouse Signed-off-by: David Teigland --- fs/dlm/ast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/dlm/ast.c') diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index 8bf31e3fbf0..30c11f3855b 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c @@ -101,7 +101,7 @@ static void process_asts(void) and may result in the lkb being freed */ dlm_put_lkb(lkb); - schedule(); + cond_resched(); } } -- cgit v1.2.3-70-g09d2 From 03339696314fffb95dafb349b84243358e945ce6 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mon, 8 Dec 2008 17:14:10 -0600 Subject: dlm: remove extra blocking callback check Just before delivering a blocking callback (bast), the dlm_astd thread checks again that the granted mode of the lkb actually blocks the mode requested by the bast. The idea behind this was originally that the granted mode may have changed since the bast was queued, making the callback now unnecessary. Reasons for removing this extra check are: - dlm_astd doesn't lock the rsb before reading the lkb grmode, so it's not technically safe (this removes the long standing FIXME) - after running some tests, it doesn't appear the check ever actually eliminates a bast - delivering an unnecessary blocking callback isn't a bad thing and can happen anyway Signed-off-by: David Teigland --- fs/dlm/ast.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'fs/dlm/ast.c') diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index 30c11f3855b..09b167df790 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c @@ -89,13 +89,8 @@ static void process_asts(void) if ((type & AST_COMP) && cast) cast(lkb->lkb_astparam); - /* FIXME: Is it safe to look at lkb_grmode here - without doing a lock_rsb() ? - Look at other checks in v1 to avoid basts. */ - if ((type & AST_BAST) && bast) - if (!dlm_modes_compat(lkb->lkb_grmode, bmode)) - bast(lkb->lkb_astparam, bmode); + bast(lkb->lkb_astparam, bmode); /* this removes the reference added by dlm_add_ast and may result in the lkb being freed */ -- cgit v1.2.3-70-g09d2 From fd22a51bcc0b7b76fc729b02316214fd979f9fe1 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 9 Dec 2008 11:55:46 -0600 Subject: dlm: improve how bast mode handling The lkb bastmode value is set in the context of processing the lock, and read by the dlm_astd thread. Because it's accessed in these two separate contexts, the writing/reading ought to be done under a lock. This is simple to do by setting it and reading it when the lkb is added to and removed from dlm_astd's callback list which is properly locked. Signed-off-by: David Teigland --- fs/dlm/ast.c | 14 ++++++++------ fs/dlm/ast.h | 4 ++-- fs/dlm/lock.c | 8 +++----- fs/dlm/user.c | 4 +++- fs/dlm/user.h | 2 +- 5 files changed, 17 insertions(+), 15 deletions(-) (limited to 'fs/dlm/ast.c') diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index 09b167df790..fbe840d0949 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -33,10 +33,10 @@ void dlm_del_ast(struct dlm_lkb *lkb) spin_unlock(&ast_queue_lock); } -void dlm_add_ast(struct dlm_lkb *lkb, int type) +void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode) { if (lkb->lkb_flags & DLM_IFL_USER) { - dlm_user_add_ast(lkb, type); + dlm_user_add_ast(lkb, type, bastmode); return; } @@ -46,6 +46,8 @@ void dlm_add_ast(struct dlm_lkb *lkb, int type) list_add_tail(&lkb->lkb_astqueue, &ast_queue); } lkb->lkb_ast_type |= type; + if (bastmode) + lkb->lkb_bastmode = bastmode; spin_unlock(&ast_queue_lock); set_bit(WAKE_ASTS, &astd_wakeflags); @@ -59,7 +61,7 @@ static void process_asts(void) struct dlm_lkb *lkb; void (*cast) (void *astparam); void (*bast) (void *astparam, int mode); - int type = 0, found, bmode; + int type = 0, found, bastmode; for (;;) { found = 0; @@ -74,6 +76,7 @@ static void process_asts(void) list_del(&lkb->lkb_astqueue); type = lkb->lkb_ast_type; lkb->lkb_ast_type = 0; + bastmode = lkb->lkb_bastmode; found = 1; break; } @@ -84,13 +87,12 @@ static void process_asts(void) cast = lkb->lkb_astfn; bast = lkb->lkb_bastfn; - bmode = lkb->lkb_bastmode; if ((type & AST_COMP) && cast) cast(lkb->lkb_astparam); if ((type & AST_BAST) && bast) - bast(lkb->lkb_astparam, bmode); + bast(lkb->lkb_astparam, bastmode); /* this removes the reference added by dlm_add_ast and may result in the lkb being freed */ diff --git a/fs/dlm/ast.h b/fs/dlm/ast.h index 6ee276c74c5..1b5fc5f428f 100644 --- a/fs/dlm/ast.h +++ b/fs/dlm/ast.h @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2005 Red Hat, Inc. All rights reserved. +** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -13,7 +13,7 @@ #ifndef __ASTD_DOT_H__ #define __ASTD_DOT_H__ -void dlm_add_ast(struct dlm_lkb *lkb, int type); +void dlm_add_ast(struct dlm_lkb *lkb, int type, int bastmode); void dlm_del_ast(struct dlm_lkb *lkb); void dlm_astd_wake(void); diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 724ddac9153..7b758dadbdd 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -307,7 +307,7 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv) lkb->lkb_lksb->sb_status = rv; lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; - dlm_add_ast(lkb, AST_COMP); + dlm_add_ast(lkb, AST_COMP, 0); } static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb) @@ -320,10 +320,8 @@ static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode) { if (is_master_copy(lkb)) send_bast(r, lkb, rqmode); - else { - lkb->lkb_bastmode = rqmode; - dlm_add_ast(lkb, AST_BAST); - } + else + dlm_add_ast(lkb, AST_BAST, rqmode); } /* diff --git a/fs/dlm/user.c b/fs/dlm/user.c index b3832c67194..065149e84f4 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -175,7 +175,7 @@ static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type) /* we could possibly check if the cancel of an orphan has resulted in the lkb being removed and then remove that lkb from the orphans list and free it */ -void dlm_user_add_ast(struct dlm_lkb *lkb, int type) +void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode) { struct dlm_ls *ls; struct dlm_user_args *ua; @@ -208,6 +208,8 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) ast_type = lkb->lkb_ast_type; lkb->lkb_ast_type |= type; + if (bastmode) + lkb->lkb_bastmode = bastmode; if (!ast_type) { kref_get(&lkb->lkb_ref); diff --git a/fs/dlm/user.h b/fs/dlm/user.h index 35eb6a13d61..1c968649228 100644 --- a/fs/dlm/user.h +++ b/fs/dlm/user.h @@ -9,7 +9,7 @@ #ifndef __USER_DOT_H__ #define __USER_DOT_H__ -void dlm_user_add_ast(struct dlm_lkb *lkb, int type); +void dlm_user_add_ast(struct dlm_lkb *lkb, int type, int bastmode); int dlm_user_init(void); void dlm_user_exit(void); int dlm_device_deregister(struct dlm_ls *ls); -- cgit v1.2.3-70-g09d2 From 722d74219ea21223c74e5e894b0afcc5e4ca75a7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 23 Dec 2008 10:22:56 -0600 Subject: dlm: fs/dlm/ast.c: fix warning fs/dlm/ast.c: In function 'dlm_astd': fs/dlm/ast.c:64: warning: 'bastmode' may be used uninitialized in this function Cleans code up. Signed-off-by: Andrew Morton Signed-off-by: David Teigland --- fs/dlm/ast.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'fs/dlm/ast.c') diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index fbe840d0949..dc2ad6008b2 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c @@ -61,30 +61,23 @@ static void process_asts(void) struct dlm_lkb *lkb; void (*cast) (void *astparam); void (*bast) (void *astparam, int mode); - int type = 0, found, bastmode; - - for (;;) { - found = 0; - spin_lock(&ast_queue_lock); - list_for_each_entry(lkb, &ast_queue, lkb_astqueue) { - r = lkb->lkb_resource; - ls = r->res_ls; - - if (dlm_locking_stopped(ls)) - continue; - - list_del(&lkb->lkb_astqueue); - type = lkb->lkb_ast_type; - lkb->lkb_ast_type = 0; - bastmode = lkb->lkb_bastmode; - found = 1; - break; - } - spin_unlock(&ast_queue_lock); + int type = 0, bastmode; + +repeat: + spin_lock(&ast_queue_lock); + list_for_each_entry(lkb, &ast_queue, lkb_astqueue) { + r = lkb->lkb_resource; + ls = r->res_ls; - if (!found) - break; + if (dlm_locking_stopped(ls)) + continue; + list_del(&lkb->lkb_astqueue); + type = lkb->lkb_ast_type; + lkb->lkb_ast_type = 0; + bastmode = lkb->lkb_bastmode; + + spin_unlock(&ast_queue_lock); cast = lkb->lkb_astfn; bast = lkb->lkb_bastfn; @@ -99,7 +92,9 @@ static void process_asts(void) dlm_put_lkb(lkb); cond_resched(); + goto repeat; } + spin_unlock(&ast_queue_lock); } static inline int no_asts(void) -- cgit v1.2.3-70-g09d2