Re: Move PinBuffer and UnpinBuffer to atomics - Mailing list pgsql-hackers

From Andres Freund
Subject Re: Move PinBuffer and UnpinBuffer to atomics
Date
Msg-id 20150911163700.GE4996@alap3.anarazel.de
Whole thread Raw
In response to Re: Move PinBuffer and UnpinBuffer to atomics  (YUriy Zhuravlev <u.zhuravlev@postgrespro.ru>)
Responses Re: Move PinBuffer and UnpinBuffer to atomics  (YUriy Zhuravlev <u.zhuravlev@postgrespro.ru>)
List pgsql-hackers
On 2015-09-11 19:33:26 +0300, YUriy Zhuravlev wrote:
> On Friday 11 September 2015 18:14:21 Andres Freund wrote:
> > This way we can leave the for (;;) loop
> > in BufferAlloc() thinking that the buffer is unused (and can't be further
> > pinned because of the held spinlock!)
> 
> We lost lock after PinBuffer_Locked in BufferAlloc. Therefore, in essence, 
> nothing has changed.

The relevant piece of code is:    /*     * Need to lock the buffer header too in order to change its tag.     */
LockBufHdr(buf);
    /*     * Somebody could have pinned or re-dirtied the buffer while we were     * doing the I/O and making the new
hashtableentry.  If so, we can't     * recycle this buffer; we must undo everything we've done and start     * over
witha new victim buffer.     */    oldFlags = buf->flags;    if (buf->refcount == 1 && !(oldFlags & BM_DIRTY))
break;
    UnlockBufHdr(buf);    BufTableDelete(&newTag, newHash);    if ((oldFlags & BM_TAG_VALID) &&        oldPartitionLock
!=newPartitionLock)        LWLockRelease(oldPartitionLock);    LWLockRelease(newPartitionLock);    UnpinBuffer(buf,
true);}
/* * Okay, it's finally safe to rename the buffer. * * Clearing BM_VALID here is necessary, clearing the dirtybits is
just* paranoia.  We also reset the usage_count since any recency of use of * the old content is no longer relevant.
(Theusage_count starts out at * 1 so that the buffer can survive one clock-sweep pass.) */buf->tag = newTag;buf->flags
&=~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_CHECKPOINT_NEEDED | BM_IO_ERROR | BM_PERMANENT);if (relpersistence ==
RELPERSISTENCE_PERMANENT)   buf->flags |= BM_TAG_VALID | BM_PERMANENT;else    buf->flags |=
BM_TAG_VALID;buf->usage_count= 1;
 
UnlockBufHdr(buf);

so unless I'm missing something, no, we haven't lost the lock.

Greetings,

Andres Freund



pgsql-hackers by date:

Previous
From: YUriy Zhuravlev
Date:
Subject: Re: Move PinBuffer and UnpinBuffer to atomics
Next
From: Robert Haas
Date:
Subject: Re: Foreign join pushdown vs EvalPlanQual