Track asynchronous events on a work queue

Add support to track asynchronous events on a work queue object.
For now only IBV_EVENT_WQ_FATAL is applicable.

Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h
index 88ac4bb..eab5d1b 100644
--- a/include/infiniband/verbs.h
+++ b/include/infiniband/verbs.h
@@ -341,6 +341,7 @@
 	IBV_EVENT_QP_LAST_WQE_REACHED,
 	IBV_EVENT_CLIENT_REREGISTER,
 	IBV_EVENT_GID_CHANGE,
+	IBV_EVENT_WQ_FATAL,
 };
 
 struct ibv_async_event {
@@ -348,6 +349,7 @@
 		struct ibv_cq  *cq;
 		struct ibv_qp  *qp;
 		struct ibv_srq *srq;
+		struct ibv_wq  *wq;
 		int		port_num;
 	} element;
 	enum ibv_event_type	event_type;
diff --git a/src/device.c b/src/device.c
index e520295..82d928a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -298,6 +298,9 @@
 		event->element.srq = (void *) (uintptr_t) ev.element;
 		break;
 
+	case IBV_EVENT_WQ_FATAL:
+		event->element.wq = (void *) (uintptr_t) ev.element;
+		break;
 	default:
 		event->element.port_num = ev.element;
 		break;
@@ -357,6 +360,18 @@
 		return;
 	}
 
+	case IBV_EVENT_WQ_FATAL:
+	{
+		struct ibv_wq *wq = event->element.wq;
+
+		pthread_mutex_lock(&wq->mutex);
+		++wq->events_completed;
+		pthread_cond_signal(&wq->cond);
+		pthread_mutex_unlock(&wq->mutex);
+
+		return;
+	}
+
 	default:
 		return;
 	}