Historically both TX and RX have assumed the same per-QP MW slice (tx_max_entry == remote rx_max_entry), while those are calculated separately in different places (pre and post the link-up negotiation point). This has been safe because nt->link_is_up is never set to true unless the pre-determined qp_count are the same among them, and qp_count is typically limited to nt->mw_count, which should be carefully configured by admin.
However, setup_qp_mw can actually split mw and handle multi-qps in one MW properly, so qp_count needs not to be limited by nt->mw_count. Once we relax the limitation, pre-determined qp_count can differ among host side and endpoint, and link-up negotiation can easily fail. Move the TX MW configuration (per-QP offset and size) into ntb_transport_setup_qp_mw() so that both RX and TX layout decisions are centralized in a single helper. ntb_transport_init_queue() now deals only with per-QP software state, not with MW layout. This keeps the previous behavior, while preparing for relaxing the qp_count limitation and improving readability. No functional change is intended. Signed-off-by: Koichiro Den <[email protected]> --- drivers/ntb/ntb_transport.c | 76 ++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index d5a544bf8fd6..57a21f2daac6 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -569,7 +569,10 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt, struct ntb_transport_mw *mw; struct ntb_dev *ndev = nt->ndev; struct ntb_queue_entry *entry; - unsigned int rx_size, num_qps_mw; + phys_addr_t mw_base; + resource_size_t mw_size; + unsigned int rx_size, tx_size, num_qps_mw; + u64 qp_offset; unsigned int mw_num, mw_count, qp_count; unsigned int i; int node; @@ -588,13 +591,38 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt, else num_qps_mw = qp_count / mw_count; - rx_size = (unsigned int)mw->xlat_size / num_qps_mw; - qp->rx_buff = mw->virt_addr + rx_size * (qp_num / mw_count); - rx_size -= sizeof(struct ntb_rx_info); + mw_base = nt->mw_vec[mw_num].phys_addr; + mw_size = nt->mw_vec[mw_num].phys_size; + + if (mw_size > mw->xlat_size) + mw_size = mw->xlat_size; + if (max_mw_size && mw_size > max_mw_size) + mw_size = max_mw_size; + + tx_size = (unsigned int)mw_size / num_qps_mw; + qp_offset = tx_size * (qp_num / mw_count); + + qp->rx_buff = mw->virt_addr + qp_offset; + + qp->tx_mw_size = tx_size; + qp->tx_mw = nt->mw_vec[mw_num].vbase + qp_offset; + if (!qp->tx_mw) + return -EINVAL; + + qp->tx_mw_phys = mw_base + qp_offset; + if (!qp->tx_mw_phys) + return -EINVAL; + rx_size = tx_size; + rx_size -= sizeof(struct ntb_rx_info); qp->remote_rx_info = qp->rx_buff + rx_size; + tx_size -= sizeof(struct ntb_rx_info); + qp->rx_info = qp->tx_mw + tx_size; + /* Due to housekeeping, there must be atleast 2 buffs */ + qp->tx_max_frame = min(transport_mtu, tx_size / 2); + qp->tx_max_entry = tx_size / qp->tx_max_frame; qp->rx_max_frame = min(transport_mtu, rx_size / 2); qp->rx_max_entry = rx_size / qp->rx_max_frame; qp->rx_index = 0; @@ -1132,16 +1160,6 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt, unsigned int qp_num) { struct ntb_transport_qp *qp; - phys_addr_t mw_base; - resource_size_t mw_size; - unsigned int num_qps_mw, tx_size; - unsigned int mw_num, mw_count, qp_count; - u64 qp_offset; - - mw_count = nt->mw_count; - qp_count = nt->qp_count; - - mw_num = QP_TO_MW(nt, qp_num); qp = &nt->qp_vec[qp_num]; qp->qp_num = qp_num; @@ -1151,36 +1169,6 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt, qp->event_handler = NULL; ntb_qp_link_context_reset(qp); - if (mw_num < qp_count % mw_count) - num_qps_mw = qp_count / mw_count + 1; - else - num_qps_mw = qp_count / mw_count; - - mw_base = nt->mw_vec[mw_num].phys_addr; - mw_size = nt->mw_vec[mw_num].phys_size; - - if (max_mw_size && mw_size > max_mw_size) - mw_size = max_mw_size; - - tx_size = (unsigned int)mw_size / num_qps_mw; - qp_offset = tx_size * (qp_num / mw_count); - - qp->tx_mw_size = tx_size; - qp->tx_mw = nt->mw_vec[mw_num].vbase + qp_offset; - if (!qp->tx_mw) - return -EINVAL; - - qp->tx_mw_phys = mw_base + qp_offset; - if (!qp->tx_mw_phys) - return -EINVAL; - - tx_size -= sizeof(struct ntb_rx_info); - qp->rx_info = qp->tx_mw + tx_size; - - /* Due to housekeeping, there must be atleast 2 buffs */ - qp->tx_max_frame = min(transport_mtu, tx_size / 2); - qp->tx_max_entry = tx_size / qp->tx_max_frame; - if (nt->debugfs_node_dir) { char debugfs_name[8]; -- 2.51.0
