summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
950c511)
When tx credits are returned if there are pending messages they
need to be sent. Messages could have different tx_cpts, so the
correct one needs to be locked. After lnet_post_send_locked(),
if we locked a different CPT then we need to relock the correct one
However, as part of lnet_post_send_locked(), lnet_finalze() can
be called which can free the message. Therefore, the cpt of the
message being passed must be cached in order to prevent access to
freed memory.
Signed-off-by: Amir Shehata <amir.shehata@intel.com>
Change-Id: I959fdc30daf87b5575d8371da20d5cf6f64e7d3c
Reviewed-on: https://review.whamcloud.com/28308
Tested-by: Jenkins
Reviewed-by: Olaf Weber <olaf.weber@hpe.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Sonia Sharma <sonia.sharma@intel.com>
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
txpeer->lpni_txcredits++;
if (txpeer->lpni_txcredits <= 0) {
txpeer->lpni_txcredits++;
if (txpeer->lpni_txcredits <= 0) {
msg2 = list_entry(txpeer->lpni_txq.next,
struct lnet_msg, msg_list);
list_del(&msg2->msg_list);
msg2 = list_entry(txpeer->lpni_txq.next,
struct lnet_msg, msg_list);
list_del(&msg2->msg_list);
LASSERT(msg2->msg_txpeer == txpeer);
LASSERT(msg2->msg_tx_delayed);
LASSERT(msg2->msg_txpeer == txpeer);
LASSERT(msg2->msg_tx_delayed);
- if (msg2->msg_tx_cpt != msg->msg_tx_cpt) {
+ msg2_cpt = msg2->msg_tx_cpt;
+
+ /*
+ * The msg_cpt can be different from the msg2_cpt
+ * so we need to make sure we lock the correct cpt
+ * for msg2.
+ * Once we call lnet_post_send_locked() it is no
+ * longer safe to access msg2, since it could've
+ * been freed by lnet_finalize(), but we still
+ * need to relock the correct cpt, so we cache the
+ * msg2_cpt for the purpose of the check that
+ * follows the call to lnet_pose_send_locked().
+ */
+ if (msg2_cpt != msg->msg_tx_cpt) {
lnet_net_unlock(msg->msg_tx_cpt);
lnet_net_unlock(msg->msg_tx_cpt);
- lnet_net_lock(msg2->msg_tx_cpt);
+ lnet_net_lock(msg2_cpt);
}
(void) lnet_post_send_locked(msg2, 1);
}
(void) lnet_post_send_locked(msg2, 1);
- if (msg2->msg_tx_cpt != msg->msg_tx_cpt) {
- lnet_net_unlock(msg2->msg_tx_cpt);
+ if (msg2_cpt != msg->msg_tx_cpt) {
+ lnet_net_unlock(msg2_cpt);
lnet_net_lock(msg->msg_tx_cpt);
}
} else {
lnet_net_lock(msg->msg_tx_cpt);
}
} else {