⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mxlnd.c

📁 非常经典的一个分布式系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- 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() */voidmxlnd_free_hosts(void){        struct kmx_host         *host   = NULL;        struct kmx_host         *next   = NULL;        list_for_each_entry_safe(host, next, &kmxlnd_data.kmx_hosts, mxh_list) {                list_del_init(&host->mxh_list);                mxlnd_host_free(host);        }        return;}#define xstr(s) #s#define str(s) xstr(s)#define MXLND_MAX_BOARD 4       /* we expect hosts to have fewer NICs than this */#define MXLND_MAX_EP_ID 16      /* we expect hosts to have less than this endpoints *//* this parses a line that consists of: *  * IP              HOSTNAME           BOARD        ENDPOINT ID * 169.192.0.113   mds01              0            3 *  * By default MX uses the alias (short hostname). If you override * it using mx_hostname to use the FQDN or some other name, the hostname * here must match exactly. *//* MX_MAX_HOSTNAME_LEN = 80. See myriexpress.h */intmxlnd_parse_line(char *line){        int             i               = 0;        int             ret             = 0;        int             len             = 0;        u32             ip[4]           = { 0, 0, 0, 0 };        char            hostname[MX_MAX_HOSTNAME_LEN];        u32             board           = -1;        u32             ep_id           = -1;        struct kmx_host *host           = NULL;        if (line == NULL) return -1;        len = strlen(line);        if (len == 0) return -1;        /* convert tabs to spaces */        for (i = 0; i < len; i++) {                if (line[i] == '\t') line[i] = ' ';        }        memset(&hostname, 0 , sizeof(hostname));        ret = sscanf(line, "%d.%d.%d.%d %" str(MX_MAX_HOSTNAME_LEN) "s %d %d",                      &ip[0], &ip[1], &ip[2], &ip[3], hostname, &board, &ep_id);        if (ret != 7) {                return -1;        }        /* check for valid values */        /* we assume a valid IP address (all <= 255), number of NICs,         * and number of endpoint IDs */        if (ip[0] > 255 || ip [1] > 255 || ip[2] > 255 || ip[3] > 255 ||            board > MXLND_MAX_BOARD || ep_id > MXLND_MAX_EP_ID) {                CDEBUG(D_NETERROR, "Illegal value in \"%s\". Ignoring "                                   "this host.\n", line);                return -1;        }        ret = mxlnd_host_alloc(&host);        if (ret != 0) return -1;        host->mxh_addr = ((ip[0]<<24)|(ip[1]<<16)|(ip[2]<<8)|ip[3]);        len = strlen(hostname);        MXLND_ALLOC(host->mxh_hostname, len + 1);        memset(host->mxh_hostname, 0, len + 1);        strncpy(host->mxh_hostname, hostname, len);        host->mxh_board = board;        host->mxh_ep_id = ep_id;        spin_lock(&kmxlnd_data.kmx_hosts_lock);        list_add_tail(&host->mxh_list, &kmxlnd_data.kmx_hosts);        spin_unlock(&kmxlnd_data.kmx_hosts_lock);        return 0;}voidmxlnd_print_hosts(void){#if MXLND_DEBUG        struct kmx_host         *host   = NULL;        list_for_each_entry(host, &kmxlnd_data.kmx_hosts, mxh_list) {                int             ip[4];                u32             addr    = host->mxh_addr;                ip[0] = (addr >> 24) & 0xff;                ip[1] = (addr >> 16) & 0xff;                ip[2] = (addr >>  8) & 0xff;                ip[3] = addr & 0xff;                CDEBUG(D_NET, "\tip= %d.%d.%d.%d\n\thost= %s\n\tboard= %d\n\tep_id= %d\n\n",                            ip[0], ip[1], ip[2], ip[3],                            host->mxh_hostname, host->mxh_board, host->mxh_ep_id);        }#endif        return;}#define MXLND_BUFSIZE (PAGE_SIZE - 1)intmxlnd_parse_hosts(char *filename){        int             ret             = 0;        s32             size            = 0;        s32             bufsize         = MXLND_BUFSIZE;        s32             allocd          = 0;        loff_t          offset          = 0;        struct file     *filp           = NULL;        char            *buf            = NULL;        s32             buf_off         = 0;        char            *sep            = NULL;        char            *line           = NULL;        if (filename == NULL) return -1;        filp = filp_open(filename, O_RDONLY, 0);        if (IS_ERR(filp)) {                CERROR("filp_open() failed for %s\n", filename);                return -1;        }        size = (s32) cfs_filp_size(filp);        if (size < MXLND_BUFSIZE) bufsize = size;        allocd = bufsize;        MXLND_ALLOC(buf, allocd + 1);        if (buf == NULL) {                CERROR("Cannot allocate buf\n");                filp_close(filp, current->files);                return -1;        }        while (offset < size) {                memset(buf, 0, bufsize + 1);                ret = kernel_read(filp, (unsigned long) offset, buf, (unsigned long) bufsize);

⌨️ 快捷键说明

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