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

📄 mxlnd_cb.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
                                rx->mxc_peer = peer;                                rx->mxc_nid = peer->mxp_nid;                        }                        read_unlock(&kmxlnd_data.kmx_peers_lock);                } else {                        CDEBUG(D_NETERROR, "could not post receive\n");                        mxlnd_put_idle_rx(rx);                }        }        if (rx == NULL || ret != 0) {                if (rx == NULL) {                        CDEBUG(D_NETERROR, "no idle rxs available - dropping rx\n");                } else {                        /* ret != 0 */                        CDEBUG(D_NETERROR, "disconnected peer - dropping rx\n");                }                seg.segment_ptr = 0LL;                seg.segment_length = 0;                mx_kirecv(kmxlnd_data.kmx_endpt, &seg, 1, MX_PIN_PHYSICAL,                          match_value, 0xFFFFFFFFFFFFFFFFLL, NULL, NULL);        }        return MX_RECV_CONTINUE;}intmxlnd_get_peer_info(int index, lnet_nid_t *nidp, int *count){        int                      i      = 0;        int                      ret    = -ENOENT;        struct kmx_peer         *peer   = NULL;        read_lock(&kmxlnd_data.kmx_peers_lock);        for (i = 0; i < MXLND_HASH_SIZE; i++) {                list_for_each_entry(peer, &kmxlnd_data.kmx_peers[i], mxp_peers) {                        if (index-- > 0)                                continue;                        *nidp = peer->mxp_nid;                        *count = atomic_read(&peer->mxp_refcount);                        ret = 0;                        break;                }        }        read_unlock(&kmxlnd_data.kmx_peers_lock);        return ret;}voidmxlnd_del_peer_locked(struct kmx_peer *peer){        list_del_init(&peer->mxp_peers); /* remove from the global list */        if (peer->mxp_conn) mxlnd_conn_disconnect(peer->mxp_conn, 1, 0);        mxlnd_peer_decref(peer); /* drop global list ref */        return;}intmxlnd_del_peer(lnet_nid_t nid){        int             i       = 0;        int             ret     = 0;        struct kmx_peer *peer   = NULL;        struct kmx_peer *next   = NULL;        if (nid != LNET_NID_ANY) {                peer = mxlnd_find_peer_by_nid(nid); /* adds peer ref */        }        write_lock(&kmxlnd_data.kmx_peers_lock);        if (nid != LNET_NID_ANY) {                if (peer == NULL) {                        ret = -ENOENT;                } else {                        mxlnd_peer_decref(peer); /* and drops it */                        mxlnd_del_peer_locked(peer);                }        } else { /* LNET_NID_ANY */                for (i = 0; i < MXLND_HASH_SIZE; i++) {                        list_for_each_entry_safe(peer, next,                                                 &kmxlnd_data.kmx_peers[i], mxp_peers) {                                mxlnd_del_peer_locked(peer);                        }                }        }        write_unlock(&kmxlnd_data.kmx_peers_lock);        return ret;}struct kmx_conn *mxlnd_get_conn_by_idx(int index){        int                      i      = 0;        struct kmx_peer         *peer   = NULL;        struct kmx_conn         *conn   = NULL;        read_lock(&kmxlnd_data.kmx_peers_lock);        for (i = 0; i < MXLND_HASH_SIZE; i++) {                list_for_each_entry(peer, &kmxlnd_data.kmx_peers[i], mxp_peers) {                        spin_lock(&peer->mxp_lock);                        list_for_each_entry(conn, &peer->mxp_conns, mxk_list) {                                if (index-- > 0) {                                        continue;                                }                                mxlnd_conn_addref(conn); /* add ref here, dec in ctl() */                                spin_unlock(&peer->mxp_lock);                                read_unlock(&kmxlnd_data.kmx_peers_lock);                                return conn;                        }                        spin_unlock(&peer->mxp_lock);                }        }        read_unlock(&kmxlnd_data.kmx_peers_lock);        return NULL;}voidmxlnd_close_matching_conns_locked(struct kmx_peer *peer){        struct kmx_conn *conn   = NULL;        struct kmx_conn *next   = NULL;        spin_lock(&peer->mxp_lock);        list_for_each_entry_safe(conn, next, &peer->mxp_conns, mxk_list) {                mxlnd_conn_disconnect(conn, 0 , 0);        }        spin_unlock(&peer->mxp_lock);        return;}intmxlnd_close_matching_conns(lnet_nid_t nid){        int             i       = 0;        int             ret     = 0;        struct kmx_peer *peer   = NULL;        read_lock(&kmxlnd_data.kmx_peers_lock);        if (nid != LNET_NID_ANY) {                peer = mxlnd_find_peer_by_nid(nid); /* adds peer ref */                if (peer == NULL) {                        ret = -ENOENT;                } else {                        mxlnd_close_matching_conns_locked(peer);                        mxlnd_peer_decref(peer); /* and drops it here */                }        } else { /* LNET_NID_ANY */                for (i = 0; i < MXLND_HASH_SIZE; i++) {                        list_for_each_entry(peer, &kmxlnd_data.kmx_peers[i], mxp_peers)                                mxlnd_close_matching_conns_locked(peer);                }        }        read_unlock(&kmxlnd_data.kmx_peers_lock);        return ret;}/** * mxlnd_ctl - modify MXLND parameters * @ni - LNET interface handle * @cmd - command to change * @arg - the ioctl data * * Not implemented yet. */intmxlnd_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg){        struct libcfs_ioctl_data *data  = arg;        int                       ret   = -EINVAL;        LASSERT (ni == kmxlnd_data.kmx_ni);        switch (cmd) {        case IOC_LIBCFS_GET_PEER: {                lnet_nid_t      nid     = 0;                int             count   = 0;                ret = mxlnd_get_peer_info(data->ioc_count, &nid, &count);                data->ioc_nid    = nid;                data->ioc_count  = count;                break;        }        case IOC_LIBCFS_DEL_PEER: {                ret = mxlnd_del_peer(data->ioc_nid);                break;        }        case IOC_LIBCFS_GET_CONN: {                struct kmx_conn *conn = NULL;                conn = mxlnd_get_conn_by_idx(data->ioc_count);                if (conn == NULL) {                        ret = -ENOENT;                } else {                        ret = 0;                        data->ioc_nid = conn->mxk_peer->mxp_nid;                        mxlnd_conn_decref(conn); /* dec ref taken in get_conn_by_idx() */                }                break;        }        case IOC_LIBCFS_CLOSE_CONNECTION: {                ret = mxlnd_close_matching_conns(data->ioc_nid);                break;        }        default:                CDEBUG(D_NETERROR, "unknown ctl(%d)\n", cmd);                break;        }        return ret;}/** * mxlnd_peer_queue_tx_locked - add the tx to the global tx queue * @tx * * Add the tx to the peer's msg or data queue. The caller has locked the peer. */voidmxlnd_peer_queue_tx_locked(struct kmx_ctx *tx){        u8                      msg_type        = tx->mxc_msg_type;        //struct kmx_peer         *peer           = tx->mxc_peer;        struct kmx_conn         *conn           = tx->mxc_conn;        LASSERT (msg_type != 0);        LASSERT (tx->mxc_nid != 0);        LASSERT (tx->mxc_peer != NULL);        LASSERT (tx->mxc_conn != NULL);        tx->mxc_incarnation = conn->mxk_incarnation;        if (msg_type != MXLND_MSG_PUT_DATA &&            msg_type != MXLND_MSG_GET_DATA) {                /* msg style tx */                if (mxlnd_tx_requires_credit(tx)) {                        list_add_tail(&tx->mxc_list, &conn->mxk_tx_credit_queue);                        conn->mxk_ntx_msgs++;                } else if (msg_type == MXLND_MSG_CONN_REQ ||                           msg_type == MXLND_MSG_CONN_ACK) {                        /* put conn msgs at the front of the queue */                        list_add(&tx->mxc_list, &conn->mxk_tx_free_queue);                } else {                        /* PUT_ACK, PUT_NAK */                        list_add_tail(&tx->mxc_list, &conn->mxk_tx_free_queue);                        conn->mxk_ntx_msgs++;                }        } else {                /* data style tx */                list_add_tail(&tx->mxc_list, &conn->mxk_tx_free_queue);                conn->mxk_ntx_data++;        }        return;}/** * mxlnd_peer_queue_tx - add the tx to the global tx queue * @tx * * Add the tx to the peer's msg or data queue */static inline voidmxlnd_peer_queue_tx(struct kmx_ctx *tx){        LASSERT(tx->mxc_peer != NULL);        LASSERT(tx->mxc_conn != NULL);        spin_lock(&tx->mxc_conn->mxk_lock);        mxlnd_peer_queue_tx_locked(tx);        spin_unlock(&tx->mxc_conn->mxk_lock);        return;}/** * mxlnd_queue_tx - add the tx to the global tx queue * @tx * * Add the tx to the global queue and up the tx_queue_sem */voidmxlnd_queue_tx(struct kmx_ctx *tx){        struct kmx_peer *peer   = tx->mxc_peer;        LASSERT (tx->mxc_nid != 0);        if (peer != NULL) {                if (peer->mxp_incompatible &&                    tx->mxc_msg_type != MXLND_MSG_CONN_ACK) {                        /* let this fail now */                        tx->mxc_status.code = -ECONNABORTED;                        mxlnd_conn_decref(peer->mxp_conn);                        mxlnd_put_idle_tx(tx);                        return;                }                if (tx->mxc_conn == NULL) {                        int             ret     = 0;                        struct kmx_conn *conn   = NULL;                        ret = mxlnd_conn_alloc(&conn, peer); /* adds 2nd ref for tx... */                        if (ret != 0) {                                tx->mxc_status.code = ret;                                mxlnd_put_idle_tx(tx);                                goto done;                        }                        tx->mxc_conn = conn;                        mxlnd_peer_decref(peer); /* and takes it from peer */                }                LASSERT(tx->mxc_conn != NULL);                mxlnd_peer_queue_tx(tx);                mxlnd_check_sends(peer);        } else {                spin_lock(&kmxlnd_data.kmx_tx_queue_lock);                list_add_tail(&tx->mxc_list, &kmxlnd_data.kmx_tx_queue);                spin_unlock(&kmxlnd_data.kmx_tx_queue_lock);                up(&kmxlnd_data.kmx_tx_queue_sem);        }done:        return;}intmxlnd_setup_iov(struct kmx_ctx *ctx, u32 niov, struct iovec *iov, u32 offset, u32 nob){        int             i                       = 0;        int             sum                     = 0;        int             old_sum                 = 0;        int             nseg                    = 0;        int             first_iov               = -1;        int             first_iov_offset        = 0;        int             first_found             = 0;        int             last_iov                = -1;        int             last_iov_length         = 0;        mx_ksegment_t  *seg                     = NULL;        if (niov == 0) return 0;        LASSERT(iov != NULL);        for (i = 0; i < niov; i++) {                sum = old_sum + (u32) iov[i].iov_len;                if (!first_found && (sum > offset)) {                        first_iov = i;                        first_iov_offset = offset - old_sum;                        first_found = 1;                        sum = (u32) iov[i].iov_len - first_iov_offset;                        old_sum = 0;                }                if (sum >= nob) {                        last_iov = i;                        last_iov_length = (u32) iov[i].iov_len - (sum - nob);                        if (first_iov == last_iov) last_iov_length -= first_iov_offset;                        break;                }                old_sum = sum;        }        LASSERT(first_iov >= 0 && last_iov >= first_iov);        nseg = last_iov - first_iov + 1;        LASSERT(nseg > 0);        MXLND_ALLOC (seg, nseg * sizeof(*seg));

⌨️ 快捷键说明

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