From 6490222e0252dde0220eaa5337a25c66aa49fc88 Mon Sep 17 00:00:00 2001 From: Chuck Fossen Date: Tue, 5 Apr 2016 16:38:37 +0000 Subject: [PATCH] LU-8368 gnilnd: Use kgnilnd_vzalloc() to avoid stalls Use kgnilnd_vzalloc() for copy buffer allocation in kgnilnd_rdma so we don't stall allocating in low memory situations. Clean up freeing of memory that uses kgnilnd_vzalloc to make sure we call vfree. Booted on test node and verify we don't break anything. Ran IOR tests. Test-Parameters: trivial Signed-off-by: Chris Horn Change-Id: Icb1dfe5f91f20195cd3a1093c57dc1157e127e9b Reviewed-on: http://review.whamcloud.com/21154 Reviewed-by: James Shimek Reviewed-by: Chuck Fossen Reviewed-by: James Simmons Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lnet/klnds/gnilnd/gnilnd.c | 7 ++++--- lnet/klnds/gnilnd/gnilnd.h | 6 ++++++ lnet/klnds/gnilnd/gnilnd_cb.c | 9 +++++---- lnet/klnds/gnilnd/gnilnd_conn.c | 4 ++-- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lnet/klnds/gnilnd/gnilnd.c b/lnet/klnds/gnilnd/gnilnd.c index 7ccfbf2..ac8c3f5 100644 --- a/lnet/klnds/gnilnd/gnilnd.c +++ b/lnet/klnds/gnilnd/gnilnd.c @@ -319,7 +319,8 @@ kgnilnd_create_conn(kgn_conn_t **connp, kgn_device_t *dev) failed: atomic_dec(&kgnilnd_data.kgn_nconns); - LIBCFS_FREE(conn->gnc_tx_ref_table, GNILND_MAX_MSG_ID * sizeof(void *)); + kgnilnd_vfree(conn->gnc_tx_ref_table, + GNILND_MAX_MSG_ID * sizeof(void *)); LIBCFS_FREE(conn, sizeof(*conn)); return rc; } @@ -493,8 +494,8 @@ kgnilnd_destroy_conn(kgn_conn_t *conn) kgnilnd_peer_decref(conn->gnc_peer); if (conn->gnc_tx_ref_table != NULL) { - LIBCFS_FREE(conn->gnc_tx_ref_table, - GNILND_MAX_MSG_ID * sizeof(void *)); + kgnilnd_vfree(conn->gnc_tx_ref_table, + GNILND_MAX_MSG_ID * sizeof(void *)); } LIBCFS_FREE(conn, sizeof(*conn)); diff --git a/lnet/klnds/gnilnd/gnilnd.h b/lnet/klnds/gnilnd/gnilnd.h index 01d790c..f887d4b 100644 --- a/lnet/klnds/gnilnd/gnilnd.h +++ b/lnet/klnds/gnilnd/gnilnd.h @@ -977,6 +977,12 @@ static inline void *kgnilnd_vzalloc(int size) return ret; } +static inline void kgnilnd_vfree(void *ptr, int size) +{ + libcfs_kmem_dec(ptr, size); + vfree(ptr); +} + /* Copied from DEBUG_REQ in Lustre - the dance is needed to save stack space */ extern void diff --git a/lnet/klnds/gnilnd/gnilnd_cb.c b/lnet/klnds/gnilnd/gnilnd_cb.c index bce8194..f29fb73 100644 --- a/lnet/klnds/gnilnd/gnilnd_cb.c +++ b/lnet/klnds/gnilnd/gnilnd_cb.c @@ -237,7 +237,7 @@ kgnilnd_free_tx(kgn_tx_t *tx) /* Only free the buffer if we used it */ if (tx->tx_buffer_copy != NULL) { - vfree(tx->tx_buffer_copy); + kgnilnd_vfree(tx->tx_buffer_copy, tx->tx_rdma_desc.length); tx->tx_buffer_copy = NULL; CDEBUG(D_MALLOC, "vfreed buffer2\n"); } @@ -1936,7 +1936,7 @@ kgnilnd_rdma(kgn_tx_t *tx, int type, if (tx->tx_buffer_copy == NULL) { /* Allocate the largest copy buffer we will need, this will prevent us from overwriting data * and require at most we allocate a few extra bytes. */ - tx->tx_buffer_copy = vmalloc(desc_nob); + tx->tx_buffer_copy = kgnilnd_vzalloc(desc_nob); if (!tx->tx_buffer_copy) { /* allocation of buffer failed nak the rdma */ @@ -1948,7 +1948,8 @@ kgnilnd_rdma(kgn_tx_t *tx, int type, rc = kgnilnd_mem_register(conn->gnc_device->gnd_handle, (__u64)tx->tx_buffer_copy, desc_nob, NULL, GNI_MEM_READWRITE, &tx->tx_buffer_copy_map_key); if (rc != GNI_RC_SUCCESS) { /* Registration Failed nak rdma and kill the tx. */ - vfree(tx->tx_buffer_copy); + kgnilnd_vfree(tx->tx_buffer_copy, + desc_nob); tx->tx_buffer_copy = NULL; kgnilnd_nak_rdma(tx->tx_conn, tx->tx_msg.gnm_type, -EFAULT, cookie, tx->tx_msg.gnm_srcnid); kgnilnd_tx_done(tx, -EFAULT); @@ -2014,7 +2015,7 @@ kgnilnd_rdma(kgn_tx_t *tx, int type, kgnilnd_unmap_buffer(tx, 0); if (tx->tx_buffer_copy != NULL) { - vfree(tx->tx_buffer_copy); + kgnilnd_vfree(tx->tx_buffer_copy, desc_nob); tx->tx_buffer_copy = NULL; } diff --git a/lnet/klnds/gnilnd/gnilnd_conn.c b/lnet/klnds/gnilnd/gnilnd_conn.c index 066fe1e..f9e78ee 100644 --- a/lnet/klnds/gnilnd/gnilnd_conn.c +++ b/lnet/klnds/gnilnd/gnilnd_conn.c @@ -243,7 +243,7 @@ free_bit: LIBCFS_FREE(fma_blk->gnm_bit_array, BITS_TO_LONGS(num_mbox) * sizeof (unsigned long)); free_blk: if (fma_blk->gnm_state == GNILND_FMABLK_VIRT) { - LIBCFS_FREE(fma_blk->gnm_block, fma_blk->gnm_blk_size); + kgnilnd_vfree(fma_blk->gnm_block, fma_blk->gnm_blk_size); } else { kmem_cache_free(kgnilnd_data.kgn_mbox_cache, fma_blk->gnm_block); } @@ -347,7 +347,7 @@ kgnilnd_free_fmablk_locked(kgn_device_t *dev, kgn_fma_memblock_t *fma_blk) if (fma_blk->gnm_state == GNILND_FMABLK_PHYS) { kmem_cache_free(kgnilnd_data.kgn_mbox_cache, fma_blk->gnm_block); } else { - LIBCFS_FREE(fma_blk->gnm_block, fma_blk->gnm_blk_size); + kgnilnd_vfree(fma_blk->gnm_block, fma_blk->gnm_blk_size); } fma_blk->gnm_state = GNILND_FMABLK_FREED; -- 1.8.3.1