Skip to content

Commit ea8994c

Browse files
sowminivdavem330
authored andcommitted
rds: hold a sock ref from rds_message to the rds_sock
The existing model holds a reference from the rds_sock to the rds_message, but the rds_message does not itself hold a sock_put() on the rds_sock. Instead the m_rs field in the rds_message is assigned when the message is queued on the sock, and nulled when the message is dequeued from the sock. We want to be able to notify userspace when the rds_message is actually freed (from rds_message_purge(), after the refcounts to the rds_message go to 0). At the time that rds_message_purge() is called, the message is no longer on the rds_sock retransmit queue. Thus the explicit reference for the m_rs is needed to send a notification that will signal to userspace that it is now safe to free/reuse any pages that may have been pinned down for zerocopy. This patch manages the m_rs assignment in the rds_message with the necessary refcount book-keeping. Signed-off-by: Sowmini Varadhan <[email protected]> Acked-by: Santosh Shilimkar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6f89dbc commit ea8994c

File tree

2 files changed

+8
-7
lines changed

2 files changed

+8
-7
lines changed

net/rds/message.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(rds_message_addref);
5858
*/
5959
static void rds_message_purge(struct rds_message *rm)
6060
{
61-
unsigned long i;
61+
unsigned long i, flags;
6262

6363
if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags)))
6464
return;
@@ -69,6 +69,12 @@ static void rds_message_purge(struct rds_message *rm)
6969
__free_page(sg_page(&rm->data.op_sg[i]));
7070
}
7171
rm->data.op_nents = 0;
72+
spin_lock_irqsave(&rm->m_rs_lock, flags);
73+
if (rm->m_rs) {
74+
sock_put(rds_rs_to_sk(rm->m_rs));
75+
rm->m_rs = NULL;
76+
}
77+
spin_unlock_irqrestore(&rm->m_rs_lock, flags);
7278

7379
if (rm->rdma.op_active)
7480
rds_rdma_free_op(&rm->rdma);

net/rds/send.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,6 @@ static void rds_send_remove_from_sock(struct list_head *messages, int status)
649649
rm->rdma.op_notifier = NULL;
650650
}
651651
was_on_sock = 1;
652-
rm->m_rs = NULL;
653652
}
654653
spin_unlock(&rs->rs_lock);
655654

@@ -756,9 +755,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
756755
*/
757756
if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) {
758757
spin_unlock_irqrestore(&cp->cp_lock, flags);
759-
spin_lock_irqsave(&rm->m_rs_lock, flags);
760-
rm->m_rs = NULL;
761-
spin_unlock_irqrestore(&rm->m_rs_lock, flags);
762758
continue;
763759
}
764760
list_del_init(&rm->m_conn_item);
@@ -774,7 +770,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
774770
__rds_send_complete(rs, rm, RDS_RDMA_CANCELED);
775771
spin_unlock(&rs->rs_lock);
776772

777-
rm->m_rs = NULL;
778773
spin_unlock_irqrestore(&rm->m_rs_lock, flags);
779774

780775
rds_message_put(rm);
@@ -798,7 +793,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
798793
__rds_send_complete(rs, rm, RDS_RDMA_CANCELED);
799794
spin_unlock(&rs->rs_lock);
800795

801-
rm->m_rs = NULL;
802796
spin_unlock_irqrestore(&rm->m_rs_lock, flags);
803797

804798
rds_message_put(rm);
@@ -849,6 +843,7 @@ static int rds_send_queue_rm(struct rds_sock *rs, struct rds_connection *conn,
849843
list_add_tail(&rm->m_sock_item, &rs->rs_send_queue);
850844
set_bit(RDS_MSG_ON_SOCK, &rm->m_flags);
851845
rds_message_addref(rm);
846+
sock_hold(rds_rs_to_sk(rs));
852847
rm->m_rs = rs;
853848

854849
/* The code ordering is a little weird, but we're

0 commit comments

Comments
 (0)