diff -aur iwarp-sain/iwarp-1.0/kiwarp/ddp.c iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/ddp.c --- iwarp-sain/iwarp-1.0/kiwarp/ddp.c 2005-12-22 04:13:35.000000000 +1300 +++ iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/ddp.c 2007-06-06 14:34:43.000000000 +1200 @@ -313,8 +313,8 @@ * linear offset in userspace relative to beginning of * tagged buffers. */ - rbuf = rdmap_get_tag_sink(uc, stag, to, payload_len, h->rsvdulp, - &offset); + rbuf = rdmap_get_tag_sink(uc, iwsk, stag, to, payload_len, + h->rsvdulp, &offset); if (!rbuf) { iwarp_info("%s: rdmap_get_tag_sink no buf", __func__); return -ENOBUFS; diff -aur iwarp-sain/iwarp-1.0/kiwarp/iwsk.h iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/iwsk.h --- iwarp-sain/iwarp-1.0/kiwarp/iwsk.h 2005-12-22 04:13:35.000000000 +1300 +++ iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/iwsk.h 2007-06-06 13:55:50.000000000 +1200 @@ -39,6 +39,7 @@ typedef struct { struct list_head buf_qs[3]; /* buf Qs for send, rdma req, & term msg */ struct list_head rwrq; /* q for pend. recv work req; tagged msg */ + struct list_head inc_tag; /* incomming tagged recv buffer */ msn_t sink_msn; /* cur msn at sink. only for untagged messages */ } rdmap_sk_ent_t; diff -aur iwarp-sain/iwarp-1.0/kiwarp/mem.c iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/mem.c --- iwarp-sain/iwarp-1.0/kiwarp/mem.c 2005-12-22 04:13:35.000000000 +1300 +++ iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/mem.c 2007-06-06 13:56:58.000000000 +1200 @@ -100,7 +100,7 @@ mm->stag_ht, mem_stag_free); } } - + ret = ht_destroy(mm->stag_ht); kfree(mm->stag_ht); kfree(mm->mem_region); spin_unlock(&mm->lock); diff -aur iwarp-sain/iwarp-1.0/kiwarp/rdmap.c iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/rdmap.c --- iwarp-sain/iwarp-1.0/kiwarp/rdmap.c 2005-12-22 04:13:35.000000000 +1300 +++ iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/rdmap.c 2007-06-06 14:38:50.000000000 +1200 @@ -137,6 +137,7 @@ INIT_LIST_HEAD(&(iwsk->rdmapsk.buf_qs[RDMAREQ_Q])); INIT_LIST_HEAD(&(iwsk->rdmapsk.buf_qs[TERM_Q])); INIT_LIST_HEAD(&(iwsk->rdmapsk.rwrq)); + INIT_LIST_HEAD(&(iwsk->rdmapsk.inc_tag)); iwsk->rdmapsk.sink_msn = 1; /* 1 mesg is consumed by handshake */ ret = ddp_register_sock(iwsk); @@ -530,9 +531,9 @@ } } -recv_buf_t *rdmap_get_tag_sink(struct user_context *uc, stag_t stag, - tag_offset_t to, size_t len, rdmap_cf_t cf, - uint32_t *offset) +recv_buf_t *rdmap_get_tag_sink(struct user_context *uc, iwsk_t *iwsk, + stag_t stag, tag_offset_t to, size_t len, + rdmap_cf_t cf, uint32_t *offset) { struct stag_desc *sd; recv_buf_t *rb; @@ -558,6 +559,9 @@ rb->sd = sd; rb->len = sd->len; *offset = to - (uint64_t)(unsigned long) sd->start; + /* Keeping a list of the receive buffer to be able to free + * when all segments will be proceeded */ + list_add_tail(&rb->list, &iwsk->rdmapsk.inc_tag); return rb; } @@ -731,6 +735,13 @@ { iwarp_debug("%s", __func__); if (rdmap_get_OPCODE(cf) == RDMA_WRITE) { + recv_buf_t *recv_buf, *rbp; + /* now free recv_buf allocated for ddp_get_sink */ + list_for_each_entry_safe(recv_buf, rbp, &iwsk->rdmapsk.inc_tag, list) + { + list_del(&recv_buf->list); + kfree(recv_buf); + } return 0; } else if (rdmap_get_OPCODE(cf) == RDMA_READ_RESP) { if (list_empty(&iwsk->rdmapsk.rwrq)) diff -aur iwarp-sain/iwarp-1.0/kiwarp/rdmap.h iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/rdmap.h --- iwarp-sain/iwarp-1.0/kiwarp/rdmap.h 2005-12-22 04:13:35.000000000 +1300 +++ iwarp_patched_mem_leaks/iwarp-1.0/kiwarp/rdmap.h 2007-06-06 14:41:18.000000000 +1200 @@ -158,9 +158,9 @@ recv_buf_t *rdmap_get_untag_sink(iwsk_t *iwsk, qnum_t qn, msn_t msn); -recv_buf_t *rdmap_get_tag_sink(struct user_context *uc, stag_t stag, - tag_offset_t to, size_t len, rdmap_cf_t cf, - uint32_t *offset); +recv_buf_t *rdmap_get_tag_sink(struct user_context *uc, iwsk_t *iwsk, + stag_t stag, tag_offset_t to, size_t len, rdmap_cf_t cf, + uint32_t *offset); int rdmap_send(struct user_context *uc, int fd, uint64_t id, void __user *ubuf, size_t len, stag_t stag);