diff --git a/lnet/ChangeLog b/lnet/ChangeLog
index 48ac8c9da0da50648978cbd8d4b40ad4eddd6880..b09869ea75c0c9c03fe924c9c64f0bb5f8abb000 100644
--- a/lnet/ChangeLog
+++ b/lnet/ChangeLog
@@ -17,6 +17,11 @@ Bugzilla   :
 Description: 
 Details    : 
 
+Severity   : normal
+Bugzilla   : 15272
+Description: ptl_send_rpc hits LASSERT when ptl_send_buf fails
+Details    : only hits under out-of-memory situations
+
 
 -------------------------------------------------------------------------------
 
diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h
index 37dc5d49f1acc41942817d628b3df7fafec07be9..a93354babb31969154fed7a3d371572e8957c751 100644
--- a/lnet/include/lnet/lib-lnet.h
+++ b/lnet/include/lnet/lib-lnet.h
@@ -548,6 +548,7 @@ lnet_remotenet_t *lnet_find_net_locked (__u32 net);
 int lnet_islocalnid(lnet_nid_t nid);
 int lnet_islocalnet(__u32 net);
 
+void lnet_build_unlink_event(lnet_libmd_t *md, lnet_event_t *ev);
 void lnet_enq_event_locked(lnet_eq_t *eq, lnet_event_t *ev);
 void lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target,
                     unsigned int offset, unsigned int len);
diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c
index b8a994a4122d89c43d3619620211240874e15561..f4bc2901b87766a4394857644609adbc47f3ae84 100644
--- a/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/lnet/klnds/o2iblnd/o2iblnd.c
@@ -1185,20 +1185,20 @@ kiblnd_alloc_tx_descs (lnet_ni_t *ni)
                         return -ENOMEM;
                 }
 #else
-                LIBCFS_ALLOC(tx->tx_wrq, 
-                             (1 + IBLND_MAX_RDMA_FRAGS) * 
+                LIBCFS_ALLOC(tx->tx_wrq,
+                             (1 + IBLND_MAX_RDMA_FRAGS) *
                              sizeof(*tx->tx_wrq));
                 if (tx->tx_wrq == NULL)
                         return -ENOMEM;
-                
-                LIBCFS_ALLOC(tx->tx_sge, 
-                             (1 + IBLND_MAX_RDMA_FRAGS) * 
+
+                LIBCFS_ALLOC(tx->tx_sge,
+                             (1 + IBLND_MAX_RDMA_FRAGS) *
                              sizeof(*tx->tx_sge));
                 if (tx->tx_sge == NULL)
                         return -ENOMEM;
-                
-                LIBCFS_ALLOC(tx->tx_rd, 
-                             offsetof(kib_rdma_desc_t, 
+
+                LIBCFS_ALLOC(tx->tx_rd,
+                             offsetof(kib_rdma_desc_t,
                                       rd_frags[IBLND_MAX_RDMA_FRAGS]));
                 if (tx->tx_rd == NULL)
                         return -ENOMEM;
diff --git a/lnet/lnet/lib-md.c b/lnet/lnet/lib-md.c
index ecd8f0734e251ca521f3486851193746e2e98854..731db566bc3726191fd02c607d6fa2b9f995f95e 100644
--- a/lnet/lnet/lib-md.c
+++ b/lnet/lnet/lib-md.c
@@ -284,7 +284,7 @@ LNetMDUnlink (lnet_handle_md_t mdh)
 
         LASSERT (the_lnet.ln_init);
         LASSERT (the_lnet.ln_refcount > 0);
-        
+
         LNET_LOCK();
 
         md = lnet_handle2md(&mdh);
@@ -299,14 +299,7 @@ LNetMDUnlink (lnet_handle_md_t mdh)
 
         if (md->md_eq != NULL &&
             md->md_refcount == 0) {
-                memset(&ev, 0, sizeof(ev));
-
-                ev.type = LNET_EVENT_UNLINK;
-                ev.status = 0;
-                ev.unlinked = 1;
-                lnet_md_deconstruct(md, &ev.md);
-                lnet_md2handle(&ev.md_handle, md);
-
+                lnet_build_unlink_event(md, &ev);
                 lnet_enq_event_locked(md->md_eq, &ev);
         }
 
diff --git a/lnet/lnet/lib-me.c b/lnet/lnet/lib-me.c
index edfb8a830c61322455b99d762482da49ddfde98a..c5b12866c935db6c3672627f6e4f69851440f814 100644
--- a/lnet/lnet/lib-me.c
+++ b/lnet/lnet/lib-me.c
@@ -119,25 +119,33 @@ LNetMEInsert(lnet_handle_me_t current_meh,
 int
 LNetMEUnlink(lnet_handle_me_t meh)
 {
-        lnet_me_t     *me;
-        int           rc;
+        lnet_me_t    *me;
+        lnet_libmd_t *md;
+        lnet_event_t  ev;
 
-        LASSERT (the_lnet.ln_init);        
+        LASSERT (the_lnet.ln_init);
         LASSERT (the_lnet.ln_refcount > 0);
-        
+
         LNET_LOCK();
 
         me = lnet_handle2me(&meh);
         if (me == NULL) {
-                rc = -ENOENT;
-        } else {
-                lnet_me_unlink(me);
-                rc = 0;
+                LNET_UNLOCK();
+                return -ENOENT;
         }
 
-        LNET_UNLOCK();
+        md = me->me_md;
+        if (md != NULL &&
+            md->md_eq != NULL &&
+            md->md_refcount == 0) {
+                lnet_build_unlink_event(md, &ev);
+                lnet_enq_event_locked(md->md_eq, &ev);
+        }
 
-        return (rc);
+        lnet_me_unlink(me);
+
+        LNET_UNLOCK();
+        return 0;
 }
 
 /* call with LNET_LOCK please */
diff --git a/lnet/lnet/lib-msg.c b/lnet/lnet/lib-msg.c
index c46ad1a4c6a4ccad7b89113484d492e87a09ec70..c5dfc2cfa44ff8a0a8d56651378fce89859e5532 100644
--- a/lnet/lnet/lib-msg.c
+++ b/lnet/lnet/lib-msg.c
@@ -26,6 +26,18 @@
 
 #include <lnet/lib-lnet.h>
 
+void
+lnet_build_unlink_event (lnet_libmd_t *md, lnet_event_t *ev)
+{
+        memset(ev, 0, sizeof(*ev));
+
+        ev->status   = 0;
+        ev->unlinked = 1;
+        ev->type     = LNET_EVENT_UNLINK;
+        lnet_md_deconstruct(md, &ev->md);
+        lnet_md2handle(&ev->md_handle, md);
+}
+
 void
 lnet_enq_event_locked (lnet_eq_t *eq, lnet_event_t *ev)
 {
@@ -167,12 +179,12 @@ lnet_finalize (lnet_ni_t *ni, lnet_msg_t *msg, int status)
                 LASSERT (md->md_refcount >= 0);
 
                 unlink = lnet_md_unlinkable(md);
-                
+
                 msg->msg_ev.unlinked = unlink;
-                
+
                 if (md->md_eq != NULL)
                         lnet_enq_event_locked(md->md_eq, &msg->msg_ev);
-                
+
                 if (unlink)
                         lnet_md_unlink(md);