ib_req_notify_cq(ic->i_scq, IB_CQ_SOLICITED);
poll_cq(ic, ic->i_scq, ic->i_send_wc, &ack_state);
- if (rds_conn_up(conn)) {
- clear_bit(RDS_LL_SEND_FULL, &conn->c_flags);
+ if (rds_conn_up(conn) && !test_bit(RDS_LL_SEND_FULL, &conn->c_flags))
rds_send_xmit(ic->conn);
- }
}
void rds_ib_tasklet_fn_recv(unsigned long data)
work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, i, &pos);
if (work_alloc == 0) {
+ /* there is a window right here where someone could
+ * have freed up entries on the ring. Lets make
+ * sure it really really really is full.
+ */
set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
- rds_ib_stats_inc(s_ib_tx_ring_full);
- ret = -ENOMEM;
- goto out;
+ smp_mb();
+ work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, i, &pos);
+ if (work_alloc == 0) {
+ rds_ib_stats_inc(s_ib_tx_ring_full);
+ ret = -ENOMEM;
+ goto out;
+ }
+ clear_bit(RDS_LL_SEND_FULL, &conn->c_flags);
}
if (ic->i_flowctl) {