diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index e82a53a..fb9e0a0 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -621,6 +621,7 @@ CREATE VIEW pg_stat_activity AS
             S.query_start,
             S.state_change,
             S.waiting,
+			S.wait_event,
             S.state,
             S.backend_xid,
             s.backend_xmin,
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index e9fbc38..1ab711f 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -2918,6 +2918,59 @@ pgstat_report_waiting(bool waiting)
 	beentry->st_waiting = waiting;
 }
 
+/*
+ * read_string_from_waitevent() -
+ *
+ * Return wait event name for the given WaitEventType; if no valid
+ * WaitEventType code exists, an error is thrown.
+ */
+const char *
+read_string_from_waitevent(uint8 wait_event)
+{
+	const char	*wait_event_name;
+	int			i;
+
+	for (i = 0; i < lengthof(WaitEventTypeMap); i++)
+	{
+		if (WaitEventTypeMap[i].we_type == wait_event)
+		{
+			wait_event_name = WaitEventTypeMap[i].we_name;
+			break;
+		}
+	}
+
+	if (i >= lengthof(WaitEventTypeMap))
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("unrecognized wait event type: %d", wait_event)));
+
+	return wait_event_name;
+}
+
+/* ----------
+ * pgstat_report_wait_event() -
+ *
+ *	Called from lock manager to report wait event type information.
+ *
+ * NB: this *must* be able to survive being called before MyBEEntry has been
+ * initialized.
+ * ----------
+ */
+void
+pgstat_report_wait_event(uint8 wait_event)
+{
+	volatile PgBackendStatus *beentry = MyBEEntry;
+
+	if (!pgstat_track_activities || !beentry)
+		return;
+
+	/*
+	 * Since this is a single-byte field in a struct that only this process
+	 * may modify, there seems no need to bother with the st_changecount
+	 * protocol.  The update must appear atomic in any case.
+	 */
+	beentry->st_wait_event = wait_event;
+}
 
 /* ----------
  * pgstat_read_current_status() -
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index cc973b5..2f1b8fb 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -3264,6 +3264,9 @@ LockBufferForCleanup(Buffer buffer)
 		UnlockBufHdr(bufHdr);
 		LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
 
+		/* Report the wait */
+		pgstat_report_wait_event(WaitEvent_BufferCleanupLock);
+
 		/* Wait to be signaled by UnpinBuffer() */
 		if (InHotStandby)
 		{
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 1eb2d4b..269e1e3 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -1591,6 +1591,7 @@ WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner)
 		new_status[len] = '\0'; /* truncate off " waiting" */
 	}
 	pgstat_report_waiting(true);
+	pgstat_report_wait_event(LockTypeToWaitEvent(locallock->tag.lock.locktag_type));
 
 	awaitedLock = locallock;
 	awaitedOwner = owner;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 46cab49..f4a798c 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -80,6 +80,7 @@
 #include "access/subtrans.h"
 #include "commands/async.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "pg_trace.h"
 #include "postmaster/postmaster.h"
 #include "replication/slot.h"
@@ -152,6 +153,7 @@ static bool lock_addin_request_allowed = true;
 
 static inline bool LWLockAcquireCommon(LWLock *l, LWLockMode mode,
 					uint64 *valptr, uint64 val);
+static void LWLockReportStat(LWLock *lock);
 
 #ifdef LWLOCK_STATS
 typedef struct lwlock_stats_key
@@ -572,6 +574,47 @@ LWLockInitialize(LWLock *lock, int tranche_id)
 }
 
 /*
+ * Report wait event for light-weight locks.
+ *
+ * This function will be used by all the light-weight lock calls which
+ * needs to wait to acquire the lock.  This function distinguishes wait
+ * event based on trance name and lock id.
+ */
+static void
+LWLockReportStat(LWLock *lock)
+{
+	int			lockid;
+	const char	*tranche_name;
+
+	tranche_name = T_NAME(lock);
+
+	if (strcmp(tranche_name, "main") == 0)
+	{
+		lockid = T_ID(lock);
+
+		if (lockid < NUM_INDIVIDUAL_LWLOCKS)
+			pgstat_report_wait_event(LWLockTypeToWaitEvent(lockid));
+		else if (lockid >= BUFFER_MAPPING_LWLOCK_OFFSET &&
+				 lockid <  LOCK_MANAGER_LWLOCK_OFFSET)
+			pgstat_report_wait_event(WaitEvent_BufferMappingLock);
+		else if (lockid >= LOCK_MANAGER_LWLOCK_OFFSET &&
+				 lockid <  PREDICATELOCK_MANAGER_LWLOCK_OFFSET)
+			pgstat_report_wait_event(WaitEvent_LockManagerLock);
+		else if (lockid >= PREDICATELOCK_MANAGER_LWLOCK_OFFSET&&
+				 lockid <  NUM_FIXED_LWLOCKS)
+			pgstat_report_wait_event(WaitEvent_PredicateManagerLock);
+		else
+			pgstat_report_wait_event(WaitEvent_OtherLWLock);
+	}
+	else if (strcmp(tranche_name, "WALInsertLocks") == 0)
+		pgstat_report_wait_event(WaitEvent_WALInsertLocks);
+	else if (strcmp(tranche_name, "ReplicationOrigins") == 0)
+		pgstat_report_wait_event(WaitEvent_ReplicationOrigins);
+	else
+		pgstat_report_wait_event(WaitEvent_OtherTrancheLWLock);
+}
+
+/*
  * Internal function that tries to atomically acquire the lwlock in the passed
  * in mode.
  *
@@ -1037,6 +1080,9 @@ LWLockAcquireCommon(LWLock *lock, LWLockMode mode, uint64 *valptr, uint64 val)
 
 		TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock), mode);
 
+		/* Report the wait */
+		LWLockReportStat(lock);
+
 		for (;;)
 		{
 			PGSemaphoreLock(&proc->sem);
@@ -1199,6 +1245,9 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
 #endif
 			TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock), mode);
 
+			/* Report the wait */
+			LWLockReportStat(lock);
+
 			for (;;)
 			{
 				PGSemaphoreLock(&proc->sem);
@@ -1401,6 +1450,9 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
 		TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock),
 										   LW_EXCLUSIVE);
 
+		/* Report the wait */
+		LWLockReportStat(lock);
+
 		for (;;)
 		{
 			PGSemaphoreLock(&proc->sem);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index f7c9bf6..0301bc5 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -530,7 +530,7 @@ pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
 Datum
 pg_stat_get_activity(PG_FUNCTION_ARGS)
 {
-#define PG_STAT_GET_ACTIVITY_COLS	22
+#define PG_STAT_GET_ACTIVITY_COLS	23
 	int			num_backends = pgstat_fetch_stat_numbackends();
 	int			curr_backend;
 	int			pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
@@ -617,28 +617,28 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 			nulls[3] = true;
 
 		if (TransactionIdIsValid(local_beentry->backend_xid))
-			values[14] = TransactionIdGetDatum(local_beentry->backend_xid);
+			values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
 		else
-			nulls[14] = true;
+			nulls[15] = true;
 
 		if (TransactionIdIsValid(local_beentry->backend_xmin))
-			values[15] = TransactionIdGetDatum(local_beentry->backend_xmin);
+			values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
 		else
-			nulls[15] = true;
+			nulls[16] = true;
 
 		if (beentry->st_ssl)
 		{
-			values[16] = BoolGetDatum(true);	/* ssl */
-			values[17] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
-			values[18] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
-			values[19] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
-			values[20] = BoolGetDatum(beentry->st_sslstatus->ssl_compression);
-			values[21] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn);
+			values[17] = BoolGetDatum(true);	/* ssl */
+			values[18] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
+			values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
+			values[20] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
+			values[21] = BoolGetDatum(beentry->st_sslstatus->ssl_compression);
+			values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn);
 		}
 		else
 		{
-			values[16] = BoolGetDatum(false);	/* ssl */
-			nulls[17] = nulls[18] = nulls[19] = nulls[20] = nulls[21] = true;
+			values[17] = BoolGetDatum(false);	/* ssl */
+			nulls[18] = nulls[19] = nulls[20] = nulls[21] = nulls[22] = true;
 		}
 
 		/* Values only available to role member */
@@ -674,34 +674,37 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 			values[5] = CStringGetTextDatum(beentry->st_activity);
 			values[6] = BoolGetDatum(beentry->st_waiting);
 
+			values[7] =
+				CStringGetTextDatum(read_string_from_waitevent(beentry->st_wait_event));
+
 			if (beentry->st_xact_start_timestamp != 0)
-				values[7] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
+				values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
 			else
-				nulls[7] = true;
+				nulls[8] = true;
 
 			if (beentry->st_activity_start_timestamp != 0)
-				values[8] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
+				values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
 			else
-				nulls[8] = true;
+				nulls[9] = true;
 
 			if (beentry->st_proc_start_timestamp != 0)
-				values[9] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
+				values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
 			else
-				nulls[9] = true;
+				nulls[10] = true;
 
 			if (beentry->st_state_start_timestamp != 0)
-				values[10] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
+				values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
 			else
-				nulls[10] = true;
+				nulls[11] = true;
 
 			/* A zeroed client addr means we don't know */
 			memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
 			if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
 					   sizeof(zero_clientaddr)) == 0)
 			{
-				nulls[11] = true;
 				nulls[12] = true;
 				nulls[13] = true;
+				nulls[14] = true;
 			}
 			else
 			{
@@ -725,20 +728,20 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 					if (ret == 0)
 					{
 						clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
-						values[11] = DirectFunctionCall1(inet_in,
+						values[12] = DirectFunctionCall1(inet_in,
 											   CStringGetDatum(remote_host));
 						if (beentry->st_clienthostname &&
 							beentry->st_clienthostname[0])
-							values[12] = CStringGetTextDatum(beentry->st_clienthostname);
+							values[13] = CStringGetTextDatum(beentry->st_clienthostname);
 						else
-							nulls[12] = true;
-						values[13] = Int32GetDatum(atoi(remote_port));
+							nulls[13] = true;
+						values[14] = Int32GetDatum(atoi(remote_port));
 					}
 					else
 					{
-						nulls[11] = true;
 						nulls[12] = true;
 						nulls[13] = true;
+						nulls[14] = true;
 					}
 				}
 				else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
@@ -749,16 +752,16 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 					 * connections we have no permissions to view, or with
 					 * errors.
 					 */
-					nulls[11] = true;
 					nulls[12] = true;
-					values[13] = DatumGetInt32(-1);
+					nulls[13] = true;
+					values[14] = DatumGetInt32(-1);
 				}
 				else
 				{
 					/* Unknown address type, should never happen */
-					nulls[11] = true;
 					nulls[12] = true;
 					nulls[13] = true;
+					nulls[14] = true;
 				}
 			}
 		}
@@ -775,6 +778,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 			nulls[11] = true;
 			nulls[12] = true;
 			nulls[13] = true;
+			nulls[14] = true;
 		}
 
 		tuplestore_putvalues(tupstore, tupdesc, values, nulls);
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 6b3d194..edf87d6 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -2777,7 +2777,7 @@ DATA(insert OID = 3057 ( pg_stat_get_autoanalyze_count PGNSP PGUID 12 1 0 0 0 f
 DESCR("statistics: number of auto analyzes for a table");
 DATA(insert OID = 1936 (  pg_stat_get_backend_idset		PGNSP PGUID 12 1 100 0 0 f f f f t t s 0 0 23 "" _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_idset _null_ _null_ _null_ ));
 DESCR("statistics: currently active backend IDs");
-DATA(insert OID = 2022 (  pg_stat_get_activity			PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,25,16,1184,1184,1184,1184,869,25,23,28,28,16,25,25,23,16,25}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,waiting,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,ssl,sslversion,sslcipher,sslbits,sslcompression,sslclientdn}" _null_ _null_ pg_stat_get_activity _null_ _null_ _null_ ));
+DATA(insert OID = 2022 (  pg_stat_get_activity			PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,25,16,25,1184,1184,1184,1184,869,25,23,28,28,16,25,25,23,16,25}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,waiting,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,ssl,sslversion,sslcipher,sslbits,sslcompression,sslclientdn}" _null_ _null_ pg_stat_get_activity _null_ _null_ _null_ ));
 DESCR("statistics: information about currently active backends");
 DATA(insert OID = 3099 (  pg_stat_get_wal_senders	PGNSP PGUID 12 1 10 0 0 f f f f f t s 0 0 2249 "" "{23,25,3220,3220,3220,3220,23,25}" "{o,o,o,o,o,o,o,o}" "{pid,state,sent_location,write_location,flush_location,replay_location,sync_priority,sync_state}" _null_ _null_ pg_stat_get_wal_senders _null_ _null_ _null_ ));
 DESCR("statistics: information about currently active replication");
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 9ecc163..acf8594 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -695,6 +695,288 @@ typedef enum BackendState
 	STATE_DISABLED
 } BackendState;
 
+typedef enum WaitEventType
+{
+	WaitEvent_NONE,		/* not waiting for any resource, this is default */
+
+	/* wait events for heavy-weight locks */
+	WaitEvent_RELATION,			/* whole relation */
+	WaitEvent_RELATION_EXTEND,	/* the right to extend a relation */
+	WaitEvent_PAGE,				/* one page of a relation */
+	WaitEvent_TUPLE,				/* one physical tuple */
+	WaitEvent_TRANSACTION,		/* transaction (for waiting for xact done) */
+	WaitEvent_VIRTUALTRANSACTION, /* virtual transaction (ditto) */
+	WaitEvent_SPECULATIVE_TOKEN,	/* speculative insertion Xid and token */
+	WaitEvent_OBJECT,				/* non-relation database object */
+	WaitEvent_USERLOCK,			/* reserved for old contrib/userlock code */
+	WaitEvent_ADVISORY,			/* advisory user locks */
+
+	/* wait events for fixed light-weight locks */
+	WaitEvent_ShmemIndexLock,
+	WaitEvent_OidGenLock,
+	WaitEvent_XidGenLock,
+	WaitEvent_ProcArrayLock,
+	WaitEvent_SInvalReadLock,
+	WaitEvent_SInvalWriteLock,
+	WaitEvent_WALBufMappingLock,
+	WaitEvent_WALWriteLock,
+	WaitEvent_ControlFileLock,
+	WaitEvent_CheckpointLock,
+	WaitEvent_CLogControlLock,
+	WaitEvent_SubtransControlLock,
+	WaitEvent_MultiXactGenLock,
+	WaitEvent_MultiXactOffsetControlLock,
+	WaitEvent_MultiXactMemberControlLock,
+	WaitEvent_RelCacheInitLock,
+	WaitEvent_CheckpointerCommLock,
+	WaitEvent_TwoPhaseStateLock,
+	WaitEvent_TablespaceCreateLock,
+	WaitEvent_BtreeVacuumLock,
+	WaitEvent_AddinShmemInitLock,
+	WaitEvent_AutovacuumLock,
+	WaitEvent_AutovacuumScheduleLock,
+	WaitEvent_SyncScanLock,
+	WaitEvent_RelationMappingLock,
+	WaitEvent_AsyncCtlLock,
+	WaitEvent_AsyncQueueLock,
+	WaitEvent_SerializableXactHashLock,
+	WaitEvent_SerializableFinishedListLock,
+	WaitEvent_SerializablePredicateLockListLock,
+	WaitEvent_OldSerXidLock,
+	WaitEvent_SyncRepLock,
+	WaitEvent_BackgroundWorkerLock,
+	WaitEvent_DynamicSharedMemoryControlLock,
+	WaitEvent_AutoFileLock,
+	WaitEvent_ReplicationSlotAllocationLock,
+	WaitEvent_ReplicationSlotControlLock,
+	WaitEvent_CommitTsControlLock,
+	WaitEvent_CommitTsLock,
+	WaitEvent_ReplicationOriginLock,
+
+	/*
+	 * wait events for variable number of LWLocks, map one type of locks
+	 * to single lock wait type.
+	 */
+	WaitEvent_BufferMappingLock,
+	WaitEvent_LockManagerLock,
+	WaitEvent_PredicateManagerLock,
+
+	/*
+	 * wait events for other variable number of light-weight locks, this
+	 * include all other LWlocks (for other type of LWLocks, refer
+	 * NumLWLocks()).
+	 */
+	WaitEvent_OtherLWLock,
+
+	/* wait events for LWLock types for tranche's other than "main" */
+	WaitEvent_WALInsertLocks,
+	WaitEvent_ReplicationOrigins,
+	/*
+	 * this wait event type is for the tranches registered by the
+	 * extensions if any.
+	 */
+	WaitEvent_OtherTrancheLWLock,
+
+	/* Buffer cleanup lock */
+	WaitEvent_BufferCleanupLock
+
+} WaitEventType;
+
+static const struct waitevent_type_map
+{
+	WaitEventType	we_type;
+	const char *we_name;
+}
+
+WaitEventTypeMap[] =
+{
+	{
+		WaitEvent_NONE, "No Wait"
+	},
+	{
+		WaitEvent_RELATION, "Lock (Relation)"
+	},
+	{
+		WaitEvent_RELATION_EXTEND, "Lock (Relation Extension)"
+	},
+	{
+		WaitEvent_PAGE, "Lock (Page)"
+	},
+	{
+		WaitEvent_TUPLE, "Lock (Tuple)"
+	},
+	{
+		WaitEvent_TRANSACTION, "Lock (Transaction)"
+	},
+	{
+		WaitEvent_VIRTUALTRANSACTION, "Lock (Virtual Transaction)"
+	},
+	{
+		WaitEvent_SPECULATIVE_TOKEN, "Lock (Speculative Token)"
+	},
+	{
+		WaitEvent_OBJECT, "Lock (Object)"
+	},
+	{
+		WaitEvent_USERLOCK,	"Lock (User Lock)"
+	},
+	{
+		WaitEvent_ADVISORY, "Lock (Advisory)"
+	},
+	{
+		WaitEvent_ShmemIndexLock, "LWLock (ShmemIndexLock)"
+	},
+	{
+		WaitEvent_OidGenLock, "LWLock (OidGenLock)"
+	},
+	{
+		WaitEvent_XidGenLock, "LWLock (XidGenLock)"
+	},
+	{
+		WaitEvent_ProcArrayLock, "LWLock (ProcArrayLock)"
+	},
+	{
+		WaitEvent_SInvalReadLock, "LWLock (SInvalReadLock)"
+	},
+	{
+		WaitEvent_SInvalWriteLock, "LWLock (SInvalWriteLock)"
+	},
+	{
+		WaitEvent_WALBufMappingLock, "LWLock (WALBufMappingLock)"
+	},
+	{
+		WaitEvent_WALWriteLock, "LWLock (WALWriteLock)"
+	},
+	{
+		WaitEvent_ControlFileLock, "LWLock (ControlFileLock)"
+	},
+	{
+		WaitEvent_CheckpointLock, "LWLock (CheckpointLock)"
+	},
+	{
+		WaitEvent_CLogControlLock, "LWLock (CLogControlLock)"
+	},
+	{
+		WaitEvent_SubtransControlLock, "LWLock (SubtransControlLock)"
+	},
+	{
+		WaitEvent_MultiXactGenLock, "LWLock (MultiXactGenLock)"
+	},
+	{
+		WaitEvent_MultiXactOffsetControlLock, "LWLock (MultiXactOffsetControlLock)"
+	},
+	{
+		WaitEvent_MultiXactMemberControlLock, "LWLock (MultiXactMemberControlLock)"
+	},
+	{
+		WaitEvent_RelCacheInitLock, "LWLock (RelCacheInitLock)"
+	},
+	{
+		WaitEvent_CheckpointerCommLock, "LWLock (CheckpointerCommLock)"
+	},
+	{
+		WaitEvent_TwoPhaseStateLock, "LWLock (TwoPhaseStateLock)"
+	},
+	{
+		WaitEvent_TablespaceCreateLock, "LWLock (TablespaceCreateLock)"
+	},
+	{
+		WaitEvent_BtreeVacuumLock, "LWLock (BtreeVacuumLock)"
+	},
+	{
+		WaitEvent_AddinShmemInitLock, "LWLock (AddinShmemInitLock)"
+	},
+	{
+		WaitEvent_AutovacuumLock, "LWLock (AutovacuumLock)"
+	},
+	{
+		WaitEvent_AutovacuumScheduleLock, "LWLock (AutovacuumScheduleLock)"
+	},
+	{
+		WaitEvent_SyncScanLock, "LWLock (SyncScanLock)"
+	},
+	{
+		WaitEvent_RelationMappingLock, "LWLock (RelationMappingLock)"
+	},
+	{
+		WaitEvent_AsyncCtlLock, "LWLock (AsyncCtlLock)"
+	},
+	{
+		WaitEvent_AsyncQueueLock, "LWLock (AsyncQueueLock)"
+	},
+	{
+		WaitEvent_SerializableXactHashLock, "LWLock (SerializableXactHashLock)"
+	},
+	{
+		WaitEvent_SerializableFinishedListLock, "LWLock (SerializableFinishedListLock)"
+	},
+	{
+		WaitEvent_SerializablePredicateLockListLock, "LWLock (SerializablePredicateLockListLock)"
+	},
+	{
+		WaitEvent_OldSerXidLock, "LWLock (OldSerXidLock)"
+	},
+	{
+		WaitEvent_SyncRepLock, "LWLock (SyncRepLock)"
+	},
+	{
+		WaitEvent_BackgroundWorkerLock, "LWLock (BackgroundWorkerLock)"
+	},
+	{
+		WaitEvent_DynamicSharedMemoryControlLock, "LWLock (DynamicSharedMemoryControlLock)"
+	},
+	{
+		WaitEvent_AutoFileLock, "LWLock (AutoFileLock)"
+	},
+	{
+		WaitEvent_ReplicationSlotAllocationLock, "LWLock (ReplicationSlotAllocationLock)"
+	},
+	{
+		WaitEvent_ReplicationSlotControlLock, "LWLock (ReplicationSlotControlLock)"
+	},
+	{
+		WaitEvent_CommitTsControlLock, "LWLock (CommitTsControlLock)"
+	},
+	{
+		WaitEvent_CommitTsLock, "LWLock (CommitTsLock)"
+	},
+	{
+		WaitEvent_ReplicationOriginLock, "LWLock (ReplicationOriginLock)"
+	},
+	{
+		WaitEvent_BufferMappingLock, "LWLock (BufferMappingLock)"
+	},
+	{
+		WaitEvent_LockManagerLock, "LWLock (LockManagerLock)"
+	},
+	{
+		WaitEvent_PredicateManagerLock, "LWLock (PredicateManagerLock)"
+	},
+	{
+		WaitEvent_OtherLWLock, "LWLock (OtherLock)"
+	},
+	{
+		WaitEvent_WALInsertLocks, "LWLock (WALInsertLock)"
+	},
+	{
+		WaitEvent_ReplicationOrigins, "LWLock (ReplicationOrigin)"
+	},
+	{
+		WaitEvent_OtherTrancheLWLock, "LWLock (OtherTrancheLock)"
+	},
+	{
+		WaitEvent_BufferCleanupLock, "Buffer Cleanup Lock"
+	}
+};
+
+/*
+ * These defines for locks to wait event mapping is done based on
+ * LockTagType, so if that is changed then we need to change this
+ * mapping.
+ */
+#define LockTypeToWaitEvent(l) (l + 1)
+#define LWLockTypeToWaitEvent(lw) (lw + 10)
+
 /* ----------
  * Shared-memory data structures
  * ----------
@@ -768,6 +1050,9 @@ typedef struct PgBackendStatus
 	/* Is backend currently waiting on an lmgr lock? */
 	bool		st_waiting;
 
+	/* wait event on which backend is waiting */
+	uint8		st_wait_event;
+
 	/* current state */
 	BackendState st_state;
 
@@ -932,6 +1217,8 @@ extern void pgstat_report_tempfile(size_t filesize);
 extern void pgstat_report_appname(const char *appname);
 extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
 extern void pgstat_report_waiting(bool waiting);
+extern void pgstat_report_wait_event(uint8 wait_event);
+extern const char *read_string_from_waitevent(uint8 wait_event);
 extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
 extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
 									int buflen);
