mxlnd.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 938 行 · 第 1/3 页

C
938
字号
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2004 Cluster File Systems, Inc. *   Author: Eric Barton <eric@bartonsoftware.com> * Copyright (C) 2006 Myricom, Inc. *   Author: Scott Atchley <atchley at myri.com> * *   This file is part of Lustre, http://www.lustre.org. * *   Lustre is free software; you can redistribute it and/or *   modify it under the terms of version 2 of the GNU General Public *   License as published by the Free Software Foundation. * *   Lustre is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with Lustre; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "mxlnd.h"lnd_t the_kmxlnd = {        .lnd_type       = MXLND,        .lnd_startup    = mxlnd_startup,        .lnd_shutdown   = mxlnd_shutdown,        .lnd_ctl        = mxlnd_ctl,        .lnd_send       = mxlnd_send,        .lnd_recv       = mxlnd_recv,};kmx_data_t               kmxlnd_data;/** * mxlnd_ctx_free - free ctx struct * @ctx - a kmx_peer pointer * * The calling function should remove the ctx from the ctx list first * then free it. */voidmxlnd_ctx_free(struct kmx_ctx *ctx){        if (ctx == NULL) return;        if (ctx->mxc_page != NULL) {                __free_page(ctx->mxc_page);                spin_lock(&kmxlnd_data.kmx_global_lock);                kmxlnd_data.kmx_mem_used -= MXLND_EAGER_SIZE;                spin_unlock(&kmxlnd_data.kmx_global_lock);        }        if (ctx->mxc_seg_list != NULL) {                LASSERT(ctx->mxc_nseg > 0);                MXLND_FREE(ctx->mxc_seg_list, ctx->mxc_nseg * sizeof(mx_ksegment_t));        }        MXLND_FREE (ctx, sizeof (*ctx));        return;}/** * mxlnd_ctx_alloc - allocate and initialize a new ctx struct * @ctxp - address of a kmx_ctx pointer * * Returns 0 on success and -EINVAL, -ENOMEM on failure */intmxlnd_ctx_alloc(struct kmx_ctx **ctxp, enum kmx_req_type type){        int             ret     = 0;        struct kmx_ctx  *ctx    = NULL;        if (ctxp == NULL) return -EINVAL;        MXLND_ALLOC(ctx, sizeof (*ctx));        if (ctx == NULL) {                CDEBUG(D_NETERROR, "Cannot allocate ctx\n");                return -ENOMEM;        }        memset(ctx, 0, sizeof(*ctx));        spin_lock_init(&ctx->mxc_lock);        ctx->mxc_type = type;        ctx->mxc_page = alloc_page (GFP_KERNEL);        if (ctx->mxc_page == NULL) {                CDEBUG(D_NETERROR, "Can't allocate page\n");                ret = -ENOMEM;                goto failed;        }        spin_lock(&kmxlnd_data.kmx_global_lock);        kmxlnd_data.kmx_mem_used += MXLND_EAGER_SIZE;        spin_unlock(&kmxlnd_data.kmx_global_lock);        ctx->mxc_msg = (struct kmx_msg *)((char *)page_address(ctx->mxc_page));        ctx->mxc_seg.segment_ptr = MX_PA_TO_U64(lnet_page2phys(ctx->mxc_page));        ctx->mxc_state = MXLND_CTX_IDLE;        *ctxp = ctx;        return 0;failed:        mxlnd_ctx_free(ctx);        return ret;}/** * mxlnd_ctx_init - reset ctx struct to the default values * @ctx - a kmx_ctx pointer */voidmxlnd_ctx_init(struct kmx_ctx *ctx){        if (ctx == NULL) return;        /* do not change mxc_type */        ctx->mxc_incarnation = 0;        ctx->mxc_deadline = 0;        ctx->mxc_state = MXLND_CTX_IDLE;        /* ignore mxc_global_list */        if (ctx->mxc_list.next != NULL && !list_empty(&ctx->mxc_list)) {                if (ctx->mxc_peer != NULL) spin_lock(&ctx->mxc_lock);                list_del_init(&ctx->mxc_list);                if (ctx->mxc_peer != NULL) spin_unlock(&ctx->mxc_lock);        }        /* ignore mxc_rx_list */        /* ignore mxc_lock */        ctx->mxc_nid = 0;        ctx->mxc_peer = NULL;        ctx->mxc_conn = NULL;        /* ignore mxc_msg */        /* ignore mxc_page */        ctx->mxc_lntmsg[0] = NULL;        ctx->mxc_lntmsg[1] = NULL;        ctx->mxc_msg_type = 0;        ctx->mxc_cookie = 0LL;        ctx->mxc_match = 0LL;        /* ctx->mxc_seg.segment_ptr points to mxc_page */        ctx->mxc_seg.segment_length = 0;        if (ctx->mxc_seg_list != NULL) {                LASSERT(ctx->mxc_nseg > 0);                MXLND_FREE(ctx->mxc_seg_list, ctx->mxc_nseg * sizeof(mx_ksegment_t));        }        ctx->mxc_seg_list = NULL;        ctx->mxc_nseg = 0;        ctx->mxc_nob = 0;        ctx->mxc_mxreq = NULL;        memset(&ctx->mxc_status, 0, sizeof(mx_status_t));        /* ctx->mxc_get */        /* ctx->mxc_put */        ctx->mxc_msg->mxm_type = 0;        ctx->mxc_msg->mxm_credits = 0;        ctx->mxc_msg->mxm_nob = 0;        ctx->mxc_msg->mxm_seq = 0;        return;}/** * mxlnd_free_txs - free kmx_txs and associated pages * * Called from mxlnd_shutdown() */voidmxlnd_free_txs(void){        struct kmx_ctx          *tx     = NULL;        struct kmx_ctx          *next   = NULL;        list_for_each_entry_safe(tx, next, &kmxlnd_data.kmx_txs, mxc_global_list) {                list_del_init(&tx->mxc_global_list);                mxlnd_ctx_free(tx);        }        return;}/** * mxlnd_init_txs - allocate tx descriptors then stash on txs and idle tx lists * * Called from mxlnd_startup() * returns 0 on success, else -ENOMEM */intmxlnd_init_txs(void){        int             ret     = 0;        int             i       = 0;        struct kmx_ctx  *tx      = NULL;        for (i = 0; i < *kmxlnd_tunables.kmx_ntx; i++) {                ret = mxlnd_ctx_alloc(&tx, MXLND_REQ_TX);                if (ret != 0) {                        mxlnd_free_txs();                        return ret;                }                mxlnd_ctx_init(tx);                /* in startup(), no locks required */                list_add_tail(&tx->mxc_global_list, &kmxlnd_data.kmx_txs);                list_add_tail(&tx->mxc_list, &kmxlnd_data.kmx_tx_idle);        }        return 0;}/** * mxlnd_free_rxs - free initial kmx_rx descriptors and associated pages * * Called from mxlnd_shutdown() */voidmxlnd_free_rxs(void){        struct kmx_ctx          *rx     = NULL;        struct kmx_ctx          *next   = NULL;        list_for_each_entry_safe(rx, next, &kmxlnd_data.kmx_rxs, mxc_global_list) {                list_del_init(&rx->mxc_global_list);                mxlnd_ctx_free(rx);        }        return;}/** * mxlnd_init_rxs - allocate initial rx descriptors  * * Called from startup(). We create MXLND_MAX_PEERS plus MXLND_NTX * rx descriptors. We create one for each potential peer to handle  * the initial connect request. We create on for each tx in case the  * send requires a non-eager receive. * * Returns 0 on success, else -ENOMEM */intmxlnd_init_rxs(void){        int             ret     = 0;        int             i       = 0;        struct kmx_ctx  *rx      = NULL;        for (i = 0; i < (*kmxlnd_tunables.kmx_ntx + *kmxlnd_tunables.kmx_max_peers); i++) {                ret = mxlnd_ctx_alloc(&rx, MXLND_REQ_RX);                if (ret != 0) {                        mxlnd_free_rxs();                        return ret;                }                mxlnd_ctx_init(rx);                /* in startup(), no locks required */                list_add_tail(&rx->mxc_global_list, &kmxlnd_data.kmx_rxs);                list_add_tail(&rx->mxc_list, &kmxlnd_data.kmx_rx_idle);        }        return 0;}/** * mxlnd_free_peers - free peers * * Called from mxlnd_shutdown() */voidmxlnd_free_peers(void){        int                      i      = 0;        struct kmx_peer         *peer   = NULL;        struct kmx_peer         *next   = NULL;        for (i = 0; i < MXLND_HASH_SIZE; i++) {                list_for_each_entry_safe(peer, next, &kmxlnd_data.kmx_peers[i], mxp_peers) {                        list_del_init(&peer->mxp_peers);                        if (peer->mxp_conn) mxlnd_conn_decref(peer->mxp_conn);                        mxlnd_peer_decref(peer);                }        }}intmxlnd_host_alloc(struct kmx_host **hostp){        struct kmx_host *host   = NULL;        MXLND_ALLOC(host, sizeof (*host));        if (host == NULL) {                CDEBUG(D_NETERROR, "Cannot allocate host\n");                return -1;        }        memset(host, 0, sizeof(*host));        spin_lock_init(&host->mxh_lock);        *hostp = host;        return 0;}voidmxlnd_host_free(struct kmx_host *host){        if (host == NULL) return;        if (host->mxh_hostname != NULL)                MXLND_FREE(host->mxh_hostname, strlen(host->mxh_hostname) + 1);        MXLND_FREE(host, sizeof(*host));        return;}/** * mxlnd_free_hosts - free kmx_hosts * * Called from mxlnd_shutdown() */void

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?