Index: linux/net/rds/ib_send.c =================================================================== --- linux/net/rds/ib_send.c (revision 177) +++ linux/net/rds/ib_send.c (working copy) @@ -24,10 +24,17 @@ #include #include #include +#include #include "rds.h" #include "ib.h" +static u32 rds_send_frag_count; + +static int unsignaled_wrs = 0; +module_param(unsignaled_wrs, int, 0644); +MODULE_PARM_DESC(unsignaled_wrs, "Number of unsignaled work requests."); + void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, struct rds_ib_send_work *send) { @@ -155,6 +162,7 @@ rm->m_count = dma_map_sg(ic->i_cm_id->device->dma_device, rm->m_sg, rm->m_nents, DMA_TO_DEVICE); rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->m_count); + rds_send_frag_count = 0; if (rm->m_count == 0) { rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); ret = -ENOMEM; /* XXX ? */ @@ -211,6 +219,12 @@ /* if there's data reference it with a chain of work reqs */ for(; i < work_alloc && scat != &rm->m_sg[rm->m_count]; i++) { + ++rds_send_frag_count; + if ( unsignaled_wrs > 0 && rds_send_frag_count%unsignaled_wrs == 0 ) + send->s_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED; + else + send->s_wr.send_flags = IB_SEND_SIGNALED; + send->s_wr.next = NULL; if (prev) prev->s_wr.next = &send->s_wr; @@ -237,6 +251,7 @@ /* if we finished the message then send completion owns it */ if (scat == &rm->m_sg[rm->m_count]) { prev->s_rm = ic->i_rm; + prev->s_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_SOLICITED; ic->i_rm = NULL; } Index: linux/net/rds/ib_recv.c =================================================================== --- linux/net/rds/ib_recv.c (revision 177) +++ linux/net/rds/ib_recv.c (working copy) @@ -364,8 +364,8 @@ if (start < RDS_FRAG_SIZE) { addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0); memcpy(&ibinc->ii_inc.i_hdr, - addr + recv->r_frag->f_offset + start, - min(RDS_FRAG_SIZE - start, sizeof(struct rds_header))); + addr + recv->r_frag->f_offset + start, + min((unsigned long)(RDS_FRAG_SIZE - start), sizeof(struct rds_header))); kunmap_atomic(addr, KM_SOFTIRQ0); } @@ -465,7 +465,7 @@ rds_ib_stats_inc(s_ib_rx_cq_call); - ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); + ib_req_notify_cq(cq, IB_CQ_SOLICITED); while (ib_poll_cq(cq, 1, &wc) > 0 ) { rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", Index: linux/net/rds/ib_cm.c =================================================================== --- linux/net/rds/ib_cm.c (revision 177) +++ linux/net/rds/ib_cm.c (working copy) @@ -116,7 +116,7 @@ goto out; } - ret = ib_req_notify_cq(ic->i_recv_cq, IB_CQ_NEXT_COMP); + ret = ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED); if (ret) { rdsdebug("ib_req_notify_cq recv failed: %d\n", ret); goto out;