Hi, Right, the per IO check puts the spinlock in the hot path.
On dropping SHAREDINVALSMGR_ID, one thing to check first. The barrier is only emitted by DROP and ALTER DATABASE and by DROP TABLESPACE. Plain DROP TABLE and TRUNCATE go through CacheInvalidateSmgr, from smgrdounlinkall and smgrtruncate. With only the barrier left, a backend would hold descriptors for dropped relations until someone drops a database or a tablespace. That is a behavior change, not a cleanup. The barrier also only releases, it does not destroy, so it does not fix what Nazir reported. The hash table in the IO worker keeps growing either way. Nothing pins those entries in an IO worker, and smgrdestroyall only zaps unpinned ones, so destroying them there should be safe. That suggests a version with no lock at all. Keep the cleanup where Nazir put it, at a safe point in the worker loop, but trigger it on a local condition, the number of unpinned entries being over a cap, rather than on a checkpoint generation. No shared state, and it also covers a worker that never goes idle. What this does not answer is how an IO worker finds out that a relation was unlinked, so it can close the descriptor without waiting for its own eviction. That is the sinval question you raised, and it looks separate from Nazir's patch to me. Thanks, Shihao
