+int lnet_push_target_post(struct lnet_ping_buffer *pbuf,
+ struct lnet_handle_md *mdhp)
+{
+ struct lnet_process_id id = { LNET_NID_ANY, LNET_PID_ANY };
+ struct lnet_md md = { NULL };
+ struct lnet_me *me;
+ int rc;
+
+ me = LNetMEAttach(LNET_RESERVED_PORTAL, id,
+ LNET_PROTO_PING_MATCHBITS, 0,
+ LNET_UNLINK, LNET_INS_AFTER);
+ if (IS_ERR(me)) {
+ rc = PTR_ERR(me);
+ CERROR("Can't create push target ME: %d\n", rc);
+ return rc;
+ }
+
+ pbuf->pb_needs_post = false;
+
+ /* This reference is dropped by lnet_push_target_event_handler() */
+ lnet_ping_buffer_addref(pbuf);
+
+ /* initialize md content */
+ md.start = &pbuf->pb_info;
+ md.length = LNET_PING_INFO_SIZE(pbuf->pb_nnis);
+ md.threshold = 1;
+ md.max_size = 0;
+ md.options = LNET_MD_OP_PUT | LNET_MD_TRUNCATE;
+ md.user_ptr = pbuf;
+ md.eq_handle = the_lnet.ln_push_target_eq;
+
+ rc = LNetMDAttach(me, md, LNET_UNLINK, mdhp);
+ if (rc) {
+ CERROR("Can't attach push MD: %d\n", rc);
+ LNetMEUnlink(me);
+ lnet_ping_buffer_decref(pbuf);
+ pbuf->pb_needs_post = true;
+ return rc;
+ }
+
+ CDEBUG(D_NET, "posted push target %p\n", pbuf);
+
+ return 0;