* RE: [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS schedule afterstate processing
@ 2007-12-10 2:05 Graham, Simon
2007-12-10 8:56 ` Lars Ellenberg
2007-12-11 22:35 ` [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS scheduleafterstate processing Graham, Simon
0 siblings, 2 replies; 3+ messages in thread
From: Graham, Simon @ 2007-12-10 2:05 UTC (permalink / raw)
To: Graham, Simon, drbd-dev
> As you may recall, I ran into a problem recently with some state
> changes
> being delivered via netlink out of order because some state changes do
> not get their after-state-change processing deferred to the worker
> thread - this is a big problem if you have code trying to track the
> state changes via the netlink mechanism. The suggested solution was to
> make the change to schedule ALL after state change processing to the
> worker thread and the attached patch does this, including the
> following:
We have found one issue with this patch -- we are now seeing occasional
messages:
BUG! md_sync_timer expired! Worker calls drbd_md_sync()
I _think_ this is because the meta data can be marked dirty in the after
state change processing and we now have some situations where this
happens after the code runs that writes the meta data -- I'm not sure
how terrible it is, but I think we should move the code that marks the
meta data dirty into _drbd_set_state() so it happens inline -- I don't
see any reason why it has to be done in the worker thread... what do you
think?
Simon
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS schedule afterstate processing
2007-12-10 2:05 [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS schedule afterstate processing Graham, Simon
@ 2007-12-10 8:56 ` Lars Ellenberg
2007-12-11 22:35 ` [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS scheduleafterstate processing Graham, Simon
1 sibling, 0 replies; 3+ messages in thread
From: Lars Ellenberg @ 2007-12-10 8:56 UTC (permalink / raw)
To: drbd-dev
On Sun, Dec 09, 2007 at 09:05:10PM -0500, Graham, Simon wrote:
> > As you may recall, I ran into a problem recently with some state
> > changes
> > being delivered via netlink out of order because some state changes do
> > not get their after-state-change processing deferred to the worker
> > thread - this is a big problem if you have code trying to track the
> > state changes via the netlink mechanism. The suggested solution was to
> > make the change to schedule ALL after state change processing to the
> > worker thread and the attached patch does this, including the
> > following:
>
> We have found one issue with this patch -- we are now seeing occasional
> messages:
>
> BUG! md_sync_timer expired! Worker calls drbd_md_sync()
the "BUG!" already got remove out of that message, it is no bug,
but only some sloppy timing of certain things on our part.
> I _think_ this is because the meta data can be marked dirty in the after
> state change processing and we now have some situations where this
> happens after the code runs that writes the meta data -- I'm not sure
> how terrible it is, but I think we should move the code that marks the
> meta data dirty into _drbd_set_state() so it happens inline -- I don't
> see any reason why it has to be done in the worker thread... what do you
> think?
my design proposal was to set the meta-data dirty flag _implicitly_,
once something is changed that should be recorded on disk. this
"dirtying" would also schedule the timer to alert us of code pathes that
take too long to actually get these changes on disk. unfortunately we
never got around to implementing the "implicit" part of it.
yes, this "dirtying" should happen as early as possible.
--
: Lars Ellenberg Tel +43-1-8178292-55 :
: LINBIT Information Technologies GmbH Fax +43-1-8178292-82 :
: Vivenotgasse 48, A-1120 Vienna/Europe http://www.linbit.com :
^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS scheduleafterstate processing
2007-12-10 2:05 [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS schedule afterstate processing Graham, Simon
2007-12-10 8:56 ` Lars Ellenberg
@ 2007-12-11 22:35 ` Graham, Simon
1 sibling, 0 replies; 3+ messages in thread
From: Graham, Simon @ 2007-12-11 22:35 UTC (permalink / raw)
To: Lars Ellenberg, drbd-dev
[-- Attachment #1: Type: text/plain, Size: 1521 bytes --]
> >
> > We have found one issue with this patch -- we are now seeing
> occasional
> > messages:
> >
> > BUG! md_sync_timer expired! Worker calls drbd_md_sync()
>
> the "BUG!" already got remove out of that message, it is no bug,
> but only some sloppy timing of certain things on our part.
>
> > I _think_ this is because the meta data can be marked dirty in the
> after
> > state change processing and we now have some situations where this
> > happens after the code runs that writes the meta data -- I'm not
sure
> > how terrible it is, but I think we should move the code that marks
> the
> > meta data dirty into _drbd_set_state() so it happens inline -- I
> don't
> > see any reason why it has to be done in the worker thread... what do
> you
> > think?
>
> my design proposal was to set the meta-data dirty flag _implicitly_,
> once something is changed that should be recorded on disk. this
> "dirtying" would also schedule the timer to alert us of code pathes
> that
> take too long to actually get these changes on disk. unfortunately we
> never got around to implementing the "implicit" part of it.
>
> yes, this "dirtying" should happen as early as possible.
>
I made the proposed change and also fixed one other small bugette in my
original patch that caused a device that went to the PausedSync state
initially to actually go ahead and sync anyway! Attached is the final
patch for the proposed changes to ALWAYS schedule after state change
processing.
Simon
[-- Attachment #2: drbd-sched.patch --]
[-- Type: application/octet-stream, Size: 19083 bytes --]
Index: drbd-8.0.6/drbd/drbd_receiver.c
===================================================================
--- drbd-8.0.6/drbd/drbd_receiver.c (revision 21721)
+++ drbd-8.0.6/drbd/drbd_receiver.c (working copy)
@@ -717,7 +717,7 @@
D_ASSERT(!mdev->data.socket);
- if (_drbd_request_state(mdev,NS(conn,WFConnection),0) < SS_Success )
+ if (_drbd_request_state(mdev,NS(conn,WFConnection),ChgStateVerbose) < SS_Success )
return -2;
clear_bit(DISCARD_CONCURRENT, &mdev->flags);
@@ -815,7 +815,7 @@
mdev->meta.socket = msock;
mdev->last_received = jiffies;
- if(drbd_request_state(mdev,NS(conn,WFReportParams)) < SS_Success) return 0;
+ if(_drbd_request_state(mdev,NS(conn,WFReportParams),ChgStateVerbose) < SS_Success) return 0;
D_ASSERT(mdev->asender.task == NULL);
h = drbd_do_handshake(mdev);
@@ -2284,7 +2284,7 @@
if(nconn == conn_mask) return FALSE;
- if(drbd_request_state(mdev,NS(conn,nconn)) < SS_Success) {
+ if(_drbd_request_state(mdev,NS(conn,nconn),ChgStateVerbose) < SS_Success) {
drbd_force_state(mdev,NS(conn,Disconnecting));
return FALSE;
}
@@ -2396,7 +2396,7 @@
{
Drbd_State_Packet *p = (Drbd_State_Packet*)h;
drbd_conns_t nconn,oconn;
- drbd_state_t os,ns,peer_state;
+ drbd_state_t ns,peer_state;
int rv;
ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
@@ -2423,7 +2423,6 @@
spin_lock_irq(&mdev->req_lock);
if( mdev->state.conn != oconn ) goto retry;
- os = mdev->state;
ns.i = mdev->state.i;
ns.conn = nconn;
ns.peer = peer_state.role;
@@ -2433,7 +2432,7 @@
ns.disk == Negotiating ) ns.disk = UpToDate;
if((nconn == Connected || nconn == WFBitMapT) &&
ns.pdsk == Negotiating ) ns.pdsk = UpToDate;
- rv = _drbd_set_state(mdev,ns,ChgStateVerbose | ChgStateHard);
+ rv = _drbd_set_state(mdev,ns,ChgStateVerbose|ChgStateHard);
spin_unlock_irq(&mdev->req_lock);
if(rv < SS_Success) {
@@ -2453,10 +2452,6 @@
}
}
- if (rv==SS_Success) {
- after_state_ch(mdev,os,ns,ChgStateVerbose | ChgStateHard);
- }
-
mdev->net_conf->want_lose = 0;
/* FIXME assertion for (gencounts do not diverge) */
@@ -2529,7 +2524,7 @@
} else if (mdev->state.conn == WFBitMapT) {
ok = drbd_send_bitmap(mdev);
if (!ok) goto out;
- ok = drbd_request_state(mdev,NS(conn,WFSyncUUID));
+ ok = _drbd_request_state(mdev,NS(conn,WFSyncUUID),ChgStateVerbose);
D_ASSERT( ok == SS_Success );
} else {
ERR("unexpected cstate (%s) in receive_bitmap\n",
@@ -2771,7 +2766,7 @@
if( fp >= Resource &&
mdev->state.pdsk >= DUnknown ) {
drbd_disks_t nps = drbd_try_outdate_peer(mdev);
- drbd_request_state(mdev,NS(pdsk,nps));
+ _drbd_request_state(mdev,NS(pdsk,nps),ChgStateVerbose);
}
}
@@ -2784,9 +2779,6 @@
rv=_drbd_set_state(mdev,ns,ChgStateVerbose);
}
spin_unlock_irq(&mdev->req_lock);
- if (rv == SS_Success) {
- after_state_ch(mdev,os,ns,ChgStateVerbose);
- }
if(os.conn == Disconnecting) {
wait_event( mdev->misc_wait,atomic_read(&mdev->net_cnt) == 0 );
@@ -2807,7 +2799,7 @@
}
kfree(mdev->net_conf);
mdev->net_conf=NULL;
- drbd_request_state(mdev, NS(conn,StandAlone));
+ _drbd_request_state(mdev, NS(conn,StandAlone),ChgStateVerbose);
}
/* they do trigger all the time.
Index: drbd-8.0.6/drbd/drbd_worker.c
===================================================================
--- drbd-8.0.6/drbd/drbd_worker.c (revision 21721)
+++ drbd-8.0.6/drbd/drbd_worker.c (working copy)
@@ -544,9 +544,7 @@
drbd_bm_recount_bits(mdev);
- drbd_request_state(mdev,NS3(conn,Connected,
- disk,dstate,
- pdsk,pdstate));
+ _drbd_request_state(mdev,NS3(conn,Connected,disk,dstate,pdsk,pdstate),ChgStateVerbose);
drbd_md_sync(mdev);
@@ -799,8 +797,7 @@
for (i=0; i < minor_count; i++) {
if( !(odev = minor_to_mdev(i)) ) continue;
if (! _drbd_may_sync_now(odev)) {
- rv |= ( _drbd_set_state(_NS(odev,aftr_isp,1),
- ChgStateHard|ScheduleAfter)
+ rv |= ( _drbd_set_state(_NS(odev,aftr_isp,1),ChgStateHard)
!= SS_NothingToDo ) ;
}
}
@@ -823,8 +820,7 @@
if( !(odev = minor_to_mdev(i)) ) continue;
if ( odev->state.aftr_isp ) {
if (_drbd_may_sync_now(odev)) {
- rv |= ( _drbd_set_state(_NS(odev,aftr_isp,0),
- ChgStateHard|ScheduleAfter)
+ rv |= ( _drbd_set_state(_NS(odev,aftr_isp,0),ChgStateHard)
!= SS_NothingToDo ) ;
}
}
@@ -871,7 +867,7 @@
*/
void drbd_start_resync(drbd_dev *mdev, drbd_conns_t side)
{
- drbd_state_t os,ns;
+ drbd_state_t ns;
int r=0;
MTRACE(TraceTypeResync, TraceLvlSummary,
@@ -897,7 +893,7 @@
}
drbd_global_lock();
- ns = os = mdev->state;
+ ns = mdev->state;
ns.aftr_isp = !_drbd_may_sync_now(mdev);
@@ -924,8 +920,6 @@
drbd_global_unlock();
if ( r == SS_Success ) {
- after_state_ch(mdev,os,ns,ChgStateVerbose);
-
INFO("Began resync as %s (will sync %lu KB [%lu bits set]).\n",
conns_to_name(ns.conn),
(unsigned long) mdev->rs_total << (BM_BLOCK_SIZE_B-10),
Index: drbd-8.0.6/drbd/drbd_nl.c
===================================================================
--- drbd-8.0.6/drbd/drbd_nl.c (revision 21721)
+++ drbd-8.0.6/drbd/drbd_nl.c (working copy)
@@ -194,7 +194,7 @@
D_ASSERT( fp > DontCare );
- if( fp == Stonith ) drbd_request_state(mdev,NS(susp,1));
+ if( fp == Stonith ) _drbd_request_state(mdev,NS(susp,1),ChgStateVerbose);
r=drbd_khelper(mdev,"outdate-peer");
@@ -212,7 +212,7 @@
case 6: /* Peer is primary, voluntarily outdate myself */
WARN("Peer is primary, outdating myself.\n");
nps = DUnknown;
- drbd_request_state(mdev,NS(disk,Outdated));
+ _drbd_request_state(mdev,NS(disk,Outdated),ChgStateVerbose);
break;
case 7:
if( fp != Stonith ) {
@@ -223,7 +223,7 @@
default:
/* The script is broken ... */
nps = DUnknown;
- drbd_request_state(mdev,NS(disk,Outdated));
+ _drbd_request_state(mdev,NS(disk,Outdated),ChgStateVerbose);
ERR("outdate-peer helper broken, returned %d \n",(r>>8)&0xff);
return nps;
}
@@ -295,13 +295,13 @@
continue;
}
if ( r < SS_Success ) {
- r = drbd_request_state(mdev,mask,val); // Be verbose.
+ r = _drbd_request_state(mdev,mask,val,ChgStateVerbose); // Be verbose.
if( r < SS_Success ) goto fail;
}
break;
}
- if(forced) WARN("Forced to conisder local data as UpToDate!\n");
+ if(forced) WARN("Forced to consider local data as UpToDate!\n");
drbd_sync_me(mdev);
@@ -843,7 +843,7 @@
goto release_bdev2_fail;
}
- if((retcode = drbd_request_state(mdev,NS(disk,Attaching))) < SS_Success ) {
+ if((retcode = _drbd_request_state(mdev,NS(disk,Attaching),ChgStateVerbose)) < SS_Success ) {
goto release_bdev2_fail;
}
@@ -975,7 +975,7 @@
/* All tests on MDF_PrimaryInd, MDF_ConnectedInd,
MDF_Consistent and MDF_WasUpToDate must happen before
- this point, because drbd_request_state() modifies these
+ this point, because _drbd_request_state() modifies these
flags. */
/* In case we are Connected postpone any desicion on the new disk
@@ -989,7 +989,6 @@
rv = _drbd_set_state(mdev, ns, ChgStateVerbose);
ns = mdev->state;
spin_unlock_irq(&mdev->req_lock);
- if (rv==SS_Success) after_state_ch(mdev,os,ns,ChgStateVerbose);
if (rv < SS_Success) {
goto unlock_bm;
@@ -1033,7 +1032,7 @@
struct drbd_nl_cfg_reply *reply)
{
drbd_sync_me(mdev);
- reply->ret_code = drbd_request_state(mdev,NS(disk,Diskless));
+ reply->ret_code = _drbd_request_state(mdev,NS(disk,Diskless),ChgStateVerbose);
return 0;
}
@@ -1211,7 +1210,7 @@
}
mdev->cram_hmac_tfm = tfm;
- retcode = drbd_request_state(mdev,NS(conn,Unconnected));
+ retcode = _drbd_request_state(mdev,NS(conn,Unconnected),ChgStateVerbose);
reply->ret_code = retcode;
return 0;
@@ -1236,9 +1235,8 @@
if ( retcode == SS_NothingToDo ) goto done;
else if ( retcode == SS_AlreadyStandAlone ) goto done;
else if ( retcode == SS_PrimaryNOP ) {
- // Our statche checking code wants to see the peer outdated.
- retcode = drbd_request_state(mdev,NS2(conn,Disconnecting,
- pdsk,Outdated));
+ // Our state checking code wants to see the peer outdated.
+ retcode = _drbd_request_state(mdev,NS2(conn,Disconnecting,pdsk,Outdated),ChgStateVerbose);
} else if (retcode == SS_CW_FailedByPeer) {
// The peer probabely wants to see us outdated.
retcode = _drbd_request_state(mdev,NS2(conn,Disconnecting,
@@ -1247,7 +1245,7 @@
// We are diskless and our peer wants to outdate us.
// So, simply go away, and let the peer try to
// outdate us with its 'outdate-peer' handler later.
- retcode = drbd_request_state(mdev,NS(conn,StandAlone));
+ retcode = _drbd_request_state(mdev,NS(conn,StandAlone),ChgStateVerbose);
}
}
@@ -1383,8 +1381,8 @@
STATIC int drbd_nl_invalidate(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
struct drbd_nl_cfg_reply *reply)
{
- reply->ret_code = drbd_request_state(mdev,NS2(conn,StartingSyncT,
- disk,Inconsistent));
+ reply->ret_code = _drbd_request_state(mdev,NS2(conn,StartingSyncT,disk,Inconsistent),
+ ChgStateVerbose);
return 0;
}
@@ -1392,8 +1390,8 @@
struct drbd_nl_cfg_reply *reply)
{
- reply->ret_code = drbd_request_state(mdev,NS2(conn,StartingSyncS,
- pdsk,Inconsistent));
+ reply->ret_code = _drbd_request_state(mdev,NS2(conn,StartingSyncS,pdsk,Inconsistent),
+ ChgStateVerbose);
return 0;
}
@@ -1403,7 +1401,7 @@
{
int retcode=NoError;
- if(drbd_request_state(mdev,NS(user_isp,1)) == SS_NothingToDo)
+ if(_drbd_request_state(mdev,NS(user_isp,1),ChgStateVerbose) == SS_NothingToDo)
retcode = PauseFlagAlreadySet;
reply->ret_code = retcode;
@@ -1415,7 +1413,7 @@
{
int retcode=NoError;
- if(drbd_request_state(mdev,NS(user_isp,0)) == SS_NothingToDo)
+ if(_drbd_request_state(mdev,NS(user_isp,0),ChgStateVerbose) == SS_NothingToDo)
retcode = PauseFlagAlreadyClear;
reply->ret_code = retcode;
@@ -1425,7 +1423,7 @@
STATIC int drbd_nl_suspend_io(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
struct drbd_nl_cfg_reply *reply)
{
- reply->ret_code = drbd_request_state(mdev,NS(susp,1));
+ reply->ret_code = _drbd_request_state(mdev,NS(susp,1),ChgStateVerbose);
return 0;
}
@@ -1433,7 +1431,7 @@
STATIC int drbd_nl_resume_io(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
struct drbd_nl_cfg_reply *reply)
{
- reply->ret_code = drbd_request_state(mdev,NS(susp,0));
+ reply->ret_code = _drbd_request_state(mdev,NS(susp,0),ChgStateVerbose);
return 0;
}
@@ -1441,18 +1439,14 @@
struct drbd_nl_cfg_reply *reply)
{
int retcode;
- drbd_state_t os,ns;
spin_lock_irq(&mdev->req_lock);
- os = mdev->state;
if( mdev->state.disk < Outdated ) {
retcode = -999;
} else {
retcode = _drbd_set_state(_NS(mdev,disk,Outdated),ChgStateVerbose);
}
- ns = mdev->state;
spin_unlock_irq(&mdev->req_lock);
- if (retcode==SS_Success) after_state_ch(mdev,os,ns, ChgStateVerbose);
if( retcode == -999 ) {
retcode = DiskLowerThanOutdated;
Index: drbd-8.0.6/drbd/drbd_main.c
===================================================================
--- drbd-8.0.6/drbd/drbd_main.c (revision 21721)
+++ drbd-8.0.6/drbd/drbd_main.c (working copy)
@@ -75,6 +75,8 @@
STATIC int drbd_open(struct inode *inode, struct file *file);
STATIC int drbd_close(struct inode *inode, struct file *file);
STATIC int w_after_state_ch(drbd_dev *mdev, struct drbd_work *w, int unused);
+STATIC void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns,
+ enum chg_state_flags flags);
STATIC int w_md_sync(drbd_dev *mdev, struct drbd_work *w, int unused);
STATIC void md_sync_timer_fn(unsigned long data);
@@ -335,8 +337,7 @@
spin_lock_irqsave(&mdev->req_lock,flags);
if( (send = (mdev->state.disk == Failed)) ) {
- _drbd_set_state(_NS(mdev,disk,Diskless),
- ChgStateHard|ScheduleAfter);
+ _drbd_set_state(_NS(mdev,disk,Diskless),ChgStateHard);
}
spin_unlock_irqrestore(&mdev->req_lock,flags);
@@ -390,14 +391,13 @@
rv = _drbd_set_state(mdev, ns, f);
ns = mdev->state;
spin_unlock_irqrestore(&mdev->req_lock,flags);
- if (rv==SS_Success && !(f&ScheduleAfter)) after_state_ch(mdev,os,ns,f);
return rv;
}
void drbd_force_state(drbd_dev* mdev, drbd_state_t mask, drbd_state_t val)
{
- drbd_change_state(mdev,ChgStateHard,mask,val);
+ drbd_change_state(mdev,ChgStateVerbose|ChgStateHard,mask,val);
}
STATIC int is_valid_state(drbd_dev* mdev, drbd_state_t ns);
@@ -437,7 +437,6 @@
* _drbd_request_state:
* This function is the most gracefull way to change state. For some state
* transition this function even does a cluster wide transaction.
- * It has a cousin named drbd_request_state(), which is always verbose.
*/
int _drbd_request_state(drbd_dev* mdev, drbd_state_t mask, drbd_state_t val,
enum chg_state_flags f)
@@ -486,8 +485,6 @@
ns = mdev->state;
spin_unlock_irqrestore(&mdev->req_lock,flags);
- if (rv==SS_Success && !(f&ScheduleAfter)) after_state_ch(mdev,os,ns,f);
-
return rv;
}
@@ -606,6 +603,7 @@
drbd_state_t os;
int rv=SS_Success, warn_sync_abort=0;
enum fencing_policy fp;
+ struct after_state_chg_work* ascw;
MUST_HOLD(&mdev->req_lock);
@@ -801,28 +799,48 @@
}
}
- if ( os.disk == Diskless && os.conn == StandAlone &&
+ if ( os.disk == Diskless && os.conn <= Disconnecting &&
(ns.disk > Diskless || ns.conn >= Unconnected) ) {
int i;
i = try_module_get(THIS_MODULE);
D_ASSERT(i);
+ if(!drbd_thread_start(&mdev->worker)) {
+ module_put(THIS_MODULE);
+ }
}
- if( flags & ScheduleAfter ) {
- struct after_state_chg_work* ascw;
+ if(inc_local(mdev)) {
+ u32 mdf = mdev->bc->md.flags & ~(MDF_Consistent|MDF_PrimaryInd|
+ MDF_ConnectedInd|MDF_WasUpToDate|
+ MDF_PeerOutDated );
- ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC);
- if(ascw) {
- ascw->os = os;
- ascw->ns = ns;
- ascw->flags = flags;
- ascw->w.cb = w_after_state_ch;
- drbd_queue_work(&mdev->data.work,&ascw->w);
- } else {
- WARN("Could not kmalloc an ascw\n");
+ if (test_bit(CRASHED_PRIMARY,&mdev->flags) ||
+ mdev->state.role == Primary ||
+ ( mdev->state.pdsk < Inconsistent &&
+ mdev->state.peer == Primary ) ) mdf |= MDF_PrimaryInd;
+ if (mdev->state.conn > WFReportParams) mdf |= MDF_ConnectedInd;
+ if (mdev->state.disk > Inconsistent) mdf |= MDF_Consistent;
+ if (mdev->state.disk > Outdated) mdf |= MDF_WasUpToDate;
+ if (mdev->state.pdsk <= Outdated &&
+ mdev->state.pdsk >= Inconsistent) mdf |= MDF_PeerOutDated;
+ if( mdf != mdev->bc->md.flags) {
+ mdev->bc->md.flags = mdf;
+ drbd_md_mark_dirty(mdev);
}
+ dec_local(mdev);
}
+ ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC);
+ if(ascw) {
+ ascw->os = os;
+ ascw->ns = ns;
+ ascw->flags = flags;
+ ascw->w.cb = w_after_state_ch;
+ drbd_queue_work(&mdev->data.work,&ascw->w);
+ } else {
+ WARN("Could not kmalloc an ascw\n");
+ }
+
return rv;
}
@@ -837,11 +855,10 @@
return 1;
}
-void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns,
- enum chg_state_flags flags)
+STATIC void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns,
+ enum chg_state_flags flags)
{
enum fencing_policy fp;
- u32 mdf;
if ( (os.conn != Connected && ns.conn == Connected) ) {
clear_bit(CRASHED_PRIMARY, &mdev->flags);
@@ -853,24 +870,6 @@
fp = DontCare;
if(inc_local(mdev)) {
fp = mdev->bc->dc.fencing;
-
- mdf = mdev->bc->md.flags & ~(MDF_Consistent|MDF_PrimaryInd|
- MDF_ConnectedInd|MDF_WasUpToDate|
- MDF_PeerOutDated );
-
- if (test_bit(CRASHED_PRIMARY,&mdev->flags) ||
- mdev->state.role == Primary ||
- ( mdev->state.pdsk < Inconsistent &&
- mdev->state.peer == Primary ) ) mdf |= MDF_PrimaryInd;
- if (mdev->state.conn > WFReportParams) mdf |= MDF_ConnectedInd;
- if (mdev->state.disk > Inconsistent) mdf |= MDF_Consistent;
- if (mdev->state.disk > Outdated) mdf |= MDF_WasUpToDate;
- if (mdev->state.pdsk <= Outdated &&
- mdev->state.pdsk >= Inconsistent) mdf |= MDF_PeerOutDated;
- if( mdf != mdev->bc->md.flags) {
- mdev->bc->md.flags = mdf;
- drbd_md_mark_dirty(mdev);
- }
dec_local(mdev);
}
@@ -887,8 +886,7 @@
(os.conn < Connected && ns.conn >= Connected) ) {
tl_clear(mdev);
spin_lock_irq(&mdev->req_lock);
- _drbd_set_state(_NS(mdev,susp,0),
- ChgStateVerbose | ScheduleAfter );
+ _drbd_set_state(_NS(mdev,susp,0),ChgStateVerbose);
spin_unlock_irq(&mdev->req_lock);
}
}
@@ -989,8 +987,7 @@
if (ns.conn == StartingSyncT) {
spin_lock_irq(&mdev->req_lock);
- _drbd_set_state(_NS(mdev,conn,WFSyncUUID),
- ChgStateVerbose | ScheduleAfter );
+ _drbd_set_state(_NS(mdev,conn,WFSyncUUID),ChgStateVerbose);
spin_unlock_irq(&mdev->req_lock);
} else /* StartingSyncS */ {
drbd_start_resync(mdev,SyncSource);
@@ -1052,13 +1049,6 @@
drbd_thread_start(&mdev->receiver);
}
- if ( os.disk == Diskless && os.conn <= Disconnecting &&
- (ns.disk > Diskless || ns.conn >= Unconnected) ) {
- if(!drbd_thread_start(&mdev->worker)) {
- module_put(THIS_MODULE);
- }
- }
-
/* FIXME what about Primary, Diskless, and then losing
* the connection? since we survive that "somehow",
* maybe we may not stop the worker yet,
@@ -2835,7 +2825,7 @@
STATIC int w_md_sync(drbd_dev *mdev, struct drbd_work *w, int unused)
{
- WARN("BUG! md_sync_timer expired! Worker calls drbd_md_sync().\n");
+ INFO("md_sync_timer expired - worker calls drbd_md_sync().\n");
drbd_md_sync(mdev);
return 1;
Index: drbd-8.0.6/drbd/drbd_int.h
===================================================================
--- drbd-8.0.6/drbd/drbd_int.h (revision 21721)
+++ drbd-8.0.6/drbd/drbd_int.h (working copy)
@@ -916,7 +916,6 @@
enum chg_state_flags {
ChgStateHard = 1,
ChgStateVerbose = 2,
- ScheduleAfter = 4,
};
extern int drbd_change_state(drbd_dev* mdev, enum chg_state_flags f,
@@ -926,8 +925,6 @@
enum chg_state_flags);
extern int _drbd_set_state(drbd_dev*, drbd_state_t, enum chg_state_flags );
extern void print_st_err(drbd_dev*, drbd_state_t, drbd_state_t, int );
-extern void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns,
- enum chg_state_flags);
extern int drbd_thread_start(struct Drbd_thread *thi);
extern void _drbd_thread_stop(struct Drbd_thread *thi, int restart, int wait);
extern void drbd_thread_signal(struct Drbd_thread *thi);
@@ -1461,12 +1458,6 @@
wake_up(&mdev->misc_wait);
}
-static inline int drbd_request_state(drbd_dev* mdev, drbd_state_t mask,
- drbd_state_t val)
-{
- return _drbd_request_state(mdev, mask, val, ChgStateVerbose);
-}
-
/**
* drbd_chk_io_error: Handles the on_io_error setting, should be called from
* all io completion handlers. See also drbd_io_error().
@@ -1484,8 +1475,7 @@
case Detach:
case CallIOEHelper:
if (mdev->state.disk > Failed) {
- _drbd_set_state(_NS(mdev,disk,Failed),
- ChgStateHard|ScheduleAfter);
+ _drbd_set_state(_NS(mdev,disk,Failed),ChgStateHard);
ERR("Local IO failed. Detaching...\n");
}
break;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-12-11 22:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-10 2:05 [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS schedule afterstate processing Graham, Simon
2007-12-10 8:56 ` Lars Ellenberg
2007-12-11 22:35 ` [Drbd-dev] [PATCH] Proposed fix to 8.0.x to ALWAYS scheduleafterstate processing Graham, Simon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox