Lines Matching refs:lgr
189 static void smc_llc_flow_parallel(struct smc_link_group *lgr, u8 flow_type,
195 flow_type != msg_type && !lgr->delayed_event) {
196 lgr->delayed_event = qentry;
203 SMC_LGR_ID_SIZE, &lgr->id,
205 flow_type, lgr->role);
213 struct smc_link_group *lgr = qentry->link->lgr;
215 spin_lock_bh(&lgr->llc_flow_lock);
218 smc_llc_flow_parallel(lgr, flow->type, qentry);
219 spin_unlock_bh(&lgr->llc_flow_lock);
237 spin_unlock_bh(&lgr->llc_flow_lock);
242 int smc_llc_flow_initiate(struct smc_link_group *lgr,
254 if (list_empty(&lgr->list))
256 spin_lock_bh(&lgr->llc_flow_lock);
257 if (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_NONE &&
258 (lgr->llc_flow_rmt.type == SMC_LLC_FLOW_NONE ||
259 lgr->llc_flow_rmt.type == allowed_remote)) {
260 lgr->llc_flow_lcl.type = type;
261 spin_unlock_bh(&lgr->llc_flow_lock);
264 spin_unlock_bh(&lgr->llc_flow_lock);
265 rc = wait_event_timeout(lgr->llc_flow_waiter, (list_empty(&lgr->list) ||
266 (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_NONE &&
267 (lgr->llc_flow_rmt.type == SMC_LLC_FLOW_NONE ||
268 lgr->llc_flow_rmt.type == allowed_remote))),
276 void smc_llc_flow_stop(struct smc_link_group *lgr, struct smc_llc_flow *flow)
278 spin_lock_bh(&lgr->llc_flow_lock);
281 spin_unlock_bh(&lgr->llc_flow_lock);
282 if (!list_empty(&lgr->list) && lgr->delayed_event &&
283 flow == &lgr->llc_flow_lcl)
284 schedule_work(&lgr->llc_event_work);
286 wake_up(&lgr->llc_flow_waiter);
292 struct smc_llc_qentry *smc_llc_wait(struct smc_link_group *lgr,
296 struct smc_llc_flow *flow = &lgr->llc_flow_lcl;
299 wait_event_timeout(lgr->llc_msg_waiter,
302 list_empty(&lgr->list)),
305 (lnk && !smc_link_usable(lnk)) || list_empty(&lgr->list)) {
314 smc_llc_flow_start(&lgr->llc_flow_lcl,
320 SMC_LGR_ID_SIZE, &lgr->id, rcv_msg, exp_msg,
321 flow->type, lgr->role,
434 link = &send_link->lgr->lnk[i];
630 static int smc_llc_alloc_alt_link(struct smc_link_group *lgr,
635 if (lgr->type == SMC_LGR_SYMMETRIC ||
636 (lgr->type != SMC_LGR_SINGLE &&
644 if (lgr->lnk[i].state == SMC_LNK_UNUSED)
648 if (lgr->lnk[i].state == SMC_LNK_UNUSED)
655 static struct smc_buf_desc *_smc_llc_get_next_rmb(struct smc_link_group *lgr,
661 buf_pos = list_first_entry_or_null(&lgr->rmbs[*buf_lst],
671 static struct smc_buf_desc *smc_llc_get_next_rmb(struct smc_link_group *lgr,
677 if (!buf_pos || list_is_last(&buf_pos->list, &lgr->rmbs[*buf_lst])) {
679 return _smc_llc_get_next_rmb(lgr, buf_lst);
685 static struct smc_buf_desc *smc_llc_get_first_rmb(struct smc_link_group *lgr,
689 return smc_llc_get_next_rmb(lgr, buf_lst, NULL);
698 struct smc_link_group *lgr = link->lgr;
720 *buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos);
735 *buf_pos = smc_llc_get_next_rmb(lgr, buf_lst, *buf_pos);
739 if (lgr->role == SMC_CLNT)
751 struct smc_link_group *lgr = link->lgr;
759 mutex_lock(&lgr->rmbs_lock);
760 num_rkeys_send = lgr->conns_num;
761 buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst);
763 qentry = smc_llc_wait(lgr, NULL, SMC_LLC_WAIT_TIME,
773 smc_rtoken_set(lgr, link->link_idx, link_new->link_idx,
779 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
786 mutex_unlock(&lgr->rmbs_lock);
804 struct smc_link_group *lgr = link->lgr;
809 qentry = smc_llc_wait(lgr, NULL, SMC_LLC_WAIT_FIRST_TIME, 0);
820 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
824 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
851 smcr_lgr_set_type_asym(lgr, lgr_new_t, link_new->link_idx);
853 smcr_lgr_set_type(lgr, lgr_new_t);
872 struct smc_link_group *lgr = smc_get_lgr(link);
880 ini.vlan_id = lgr->vlan_id;
881 smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev);
893 lnk_idx = smc_llc_alloc_alt_link(lgr, lgr_new_t);
896 lnk_new = &lgr->lnk[lnk_idx];
897 rc = smcr_link_init(lgr, lnk_new, lnk_idx, &ini);
939 struct smc_link_group *lgr = smc_get_lgr(link);
942 if (lgr->type == SMC_LGR_SYMMETRIC ||
943 lgr->type == SMC_LGR_ASYMMETRIC_PEER)
946 ini.vlan_id = lgr->vlan_id;
947 smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev);
975 static void smc_llc_process_cli_add_link(struct smc_link_group *lgr)
979 qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
981 mutex_lock(&lgr->llc_conf_mutex);
986 mutex_unlock(&lgr->llc_conf_mutex);
989 static int smc_llc_active_link_count(struct smc_link_group *lgr)
994 if (!smc_link_active(&lgr->lnk[i]))
1002 static struct smc_link *smc_llc_find_asym_link(struct smc_link_group *lgr)
1012 if (!smc_link_usable(&lgr->lnk[i]) ||
1013 !smc_link_usable(&lgr->lnk[j]))
1015 if (!memcmp(lgr->lnk[i].gid, lgr->lnk[j].gid,
1027 if (!smc_link_usable(&lgr->lnk[k]))
1030 !memcmp(lgr->lnk[i].peer_gid, lgr->lnk[k].peer_gid,
1036 !memcmp(lgr->lnk[j].peer_gid, lgr->lnk[k].peer_gid,
1043 return (asym_idx < 0) ? NULL : &lgr->lnk[asym_idx];
1046 static void smc_llc_delete_asym_link(struct smc_link_group *lgr)
1052 lnk_asym = smc_llc_find_asym_link(lgr);
1057 lnk_new = smc_switch_conns(lgr, lnk_asym, false);
1062 lgr->llc_flow_lcl.type = SMC_LLC_FLOW_DEL_LINK;
1069 qentry = smc_llc_wait(lgr, lnk_new, SMC_LLC_WAIT_TIME,
1075 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1084 struct smc_link_group *lgr = link->lgr;
1092 mutex_lock(&lgr->rmbs_lock);
1093 num_rkeys_send = lgr->conns_num;
1094 buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst);
1098 qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_TIME,
1108 smc_rtoken_set(lgr, link->link_idx, link_new->link_idx,
1114 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1117 mutex_unlock(&lgr->rmbs_lock);
1125 struct smc_link_group *lgr = link->lgr;
1134 qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_FIRST_TIME, 0);
1141 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1148 smcr_lgr_set_type_asym(lgr, lgr_new_t, link_new->link_idx);
1150 smcr_lgr_set_type(lgr, lgr_new_t);
1151 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1158 struct smc_link_group *lgr = link->lgr;
1166 ini.vlan_id = lgr->vlan_id;
1167 smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev);
1173 lnk_idx = smc_llc_alloc_alt_link(lgr, lgr_new_t);
1177 rc = smcr_link_init(lgr, &lgr->lnk[lnk_idx], lnk_idx, &ini);
1180 link_new = &lgr->lnk[lnk_idx];
1187 qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_TIME, SMC_LLC_ADD_LINK);
1194 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1198 if (lgr->type == SMC_LGR_SINGLE &&
1204 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1228 static void smc_llc_process_srv_add_link(struct smc_link_group *lgr)
1230 struct smc_link *link = lgr->llc_flow_lcl.qentry->link;
1233 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1235 mutex_lock(&lgr->llc_conf_mutex);
1237 if (!rc && lgr->type == SMC_LGR_SYMMETRIC) {
1239 smc_llc_delete_asym_link(lgr);
1241 mutex_unlock(&lgr->llc_conf_mutex);
1258 struct smc_link_group *lgr = container_of(work, struct smc_link_group,
1261 if (list_empty(&lgr->list)) {
1263 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1267 if (lgr->role == SMC_CLNT)
1268 smc_llc_process_cli_add_link(lgr);
1270 smc_llc_process_srv_add_link(lgr);
1272 smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
1290 static void smc_llc_process_cli_delete_link(struct smc_link_group *lgr)
1298 qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
1303 smc_lgr_terminate_sched(lgr);
1306 mutex_lock(&lgr->llc_conf_mutex);
1309 if (lgr->lnk[lnk_idx].link_id != del_llc->link_num)
1311 lnk_del = &lgr->lnk[lnk_idx];
1321 lnk_asym = smc_llc_find_asym_link(lgr);
1327 smc_switch_conns(lgr, lnk_del, false);
1330 active_links = smc_llc_active_link_count(lgr);
1332 /* expected deletion of asym link, don't change lgr state */
1334 smcr_lgr_set_type(lgr, SMC_LGR_SINGLE);
1336 smcr_lgr_set_type(lgr, SMC_LGR_NONE);
1337 smc_lgr_terminate_sched(lgr);
1340 mutex_unlock(&lgr->llc_conf_mutex);
1348 void smc_llc_send_link_delete_all(struct smc_link_group *lgr, bool ord, u32 rsn)
1361 if (!smc_link_sendable(&lgr->lnk[i]))
1363 if (!smc_llc_send_message_wait(&lgr->lnk[i], &delllc))
1368 static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr)
1376 mutex_lock(&lgr->llc_conf_mutex);
1377 qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl);
1382 /* delete entire lgr */
1383 smc_llc_send_link_delete_all(lgr, true, ntohl(
1385 smc_lgr_terminate_sched(lgr);
1391 if (lgr->lnk[i].link_id == del_llc->link_num) {
1392 lnk_del = &lgr->lnk[i];
1400 if (smc_switch_conns(lgr, lnk_del, false))
1403 if (!list_empty(&lgr->list)) {
1411 qentry2 = smc_llc_wait(lgr, lnk, SMC_LLC_WAIT_TIME,
1414 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1419 active_links = smc_llc_active_link_count(lgr);
1421 smcr_lgr_set_type(lgr, SMC_LGR_SINGLE);
1423 smcr_lgr_set_type(lgr, SMC_LGR_NONE);
1424 smc_lgr_terminate_sched(lgr);
1427 if (lgr->type == SMC_LGR_SINGLE && !list_empty(&lgr->list)) {
1432 mutex_unlock(&lgr->llc_conf_mutex);
1438 struct smc_link_group *lgr = container_of(work, struct smc_link_group,
1441 if (list_empty(&lgr->list)) {
1443 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1447 if (lgr->role == SMC_CLNT)
1448 smc_llc_process_cli_delete_link(lgr);
1450 smc_llc_process_srv_delete_link(lgr);
1452 smc_llc_flow_stop(lgr, &lgr->llc_flow_lcl);
1456 static void smc_llc_rmt_conf_rkey(struct smc_link_group *lgr)
1465 qentry = lgr->llc_flow_rmt.qentry;
1478 smc_rtoken_set2(lgr, rk_idx, llc->rtoken[i].link_id,
1489 smc_llc_flow_qentry_del(&lgr->llc_flow_rmt);
1493 static void smc_llc_rmt_delete_rkey(struct smc_link_group *lgr)
1501 qentry = lgr->llc_flow_rmt.qentry;
1516 smc_llc_flow_qentry_del(&lgr->llc_flow_rmt);
1519 static void smc_llc_protocol_violation(struct smc_link_group *lgr, u8 type)
1522 "llc_type %d\n", SMC_LGR_ID_SIZE, &lgr->id, type);
1523 smc_llc_set_termination_rsn(lgr, SMC_LLC_DEL_PROT_VIOL);
1524 smc_lgr_terminate_sched(lgr);
1528 static void smc_llc_event_flush(struct smc_link_group *lgr)
1532 spin_lock_bh(&lgr->llc_event_q_lock);
1533 list_for_each_entry_safe(qentry, q, &lgr->llc_event_q, list) {
1537 spin_unlock_bh(&lgr->llc_event_q_lock);
1544 struct smc_link_group *lgr = link->lgr;
1555 if (list_empty(&lgr->list))
1556 goto out; /* lgr is terminating */
1557 if (lgr->role == SMC_CLNT) {
1559 if (lgr->llc_flow_lcl.type ==
1562 if (smc_llc_flow_start(&lgr->llc_flow_lcl,
1564 schedule_work(&lgr->llc_add_link_work);
1568 if (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_ADD_LINK &&
1569 !lgr->llc_flow_lcl.qentry) {
1571 smc_llc_flow_qentry_set(&lgr->llc_flow_lcl,
1573 wake_up(&lgr->llc_msg_waiter);
1574 } else if (smc_llc_flow_start(&lgr->llc_flow_lcl,
1576 schedule_work(&lgr->llc_add_link_work);
1578 } else if (smc_llc_flow_start(&lgr->llc_flow_lcl, qentry)) {
1580 schedule_work(&lgr->llc_add_link_work);
1585 if (lgr->llc_flow_lcl.type != SMC_LLC_FLOW_NONE) {
1587 smc_llc_flow_qentry_set(&lgr->llc_flow_lcl, qentry);
1588 wake_up(&lgr->llc_msg_waiter);
1593 if (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_ADD_LINK &&
1594 !lgr->llc_flow_lcl.qentry) {
1596 smc_llc_flow_qentry_set(&lgr->llc_flow_lcl, qentry);
1597 wake_up(&lgr->llc_msg_waiter);
1598 } else if (smc_llc_flow_start(&lgr->llc_flow_lcl, qentry)) {
1599 schedule_work(&lgr->llc_del_link_work);
1604 if (smc_llc_flow_start(&lgr->llc_flow_rmt, qentry)) {
1606 smc_llc_rmt_conf_rkey(lgr);
1607 smc_llc_flow_stop(lgr, &lgr->llc_flow_rmt);
1617 if (smc_llc_flow_start(&lgr->llc_flow_rmt, qentry)) {
1619 smc_llc_rmt_delete_rkey(lgr);
1620 smc_llc_flow_stop(lgr, &lgr->llc_flow_rmt);
1624 smc_llc_protocol_violation(lgr, llc->raw.hdr.common.type);
1634 struct smc_link_group *lgr = container_of(work, struct smc_link_group,
1638 if (!lgr->llc_flow_lcl.type && lgr->delayed_event) {
1639 qentry = lgr->delayed_event;
1640 lgr->delayed_event = NULL;
1648 spin_lock_bh(&lgr->llc_event_q_lock);
1649 if (!list_empty(&lgr->llc_event_q)) {
1650 qentry = list_first_entry(&lgr->llc_event_q,
1653 spin_unlock_bh(&lgr->llc_event_q_lock);
1657 spin_unlock_bh(&lgr->llc_event_q_lock);
1664 enum smc_llc_flowtype flowtype = link->lgr->llc_flow_lcl.type;
1665 struct smc_llc_flow *flow = &link->lgr->llc_flow_lcl;
1692 smc_llc_protocol_violation(link->lgr, llc_type);
1699 smc_llc_flow_qentry_set(&link->lgr->llc_flow_lcl, qentry);
1700 wake_up(&link->lgr->llc_msg_waiter);
1705 struct smc_link_group *lgr = link->lgr;
1723 spin_lock_irqsave(&lgr->llc_event_q_lock, flags);
1724 list_add_tail(&qentry->list, &lgr->llc_event_q);
1725 spin_unlock_irqrestore(&lgr->llc_event_q_lock, flags);
1726 queue_work(system_highpri_wq, &lgr->llc_event_work);
1777 void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc)
1781 INIT_WORK(&lgr->llc_event_work, smc_llc_event_work);
1782 INIT_WORK(&lgr->llc_add_link_work, smc_llc_add_link_work);
1783 INIT_WORK(&lgr->llc_del_link_work, smc_llc_delete_link_work);
1784 INIT_LIST_HEAD(&lgr->llc_event_q);
1785 spin_lock_init(&lgr->llc_event_q_lock);
1786 spin_lock_init(&lgr->llc_flow_lock);
1787 init_waitqueue_head(&lgr->llc_flow_waiter);
1788 init_waitqueue_head(&lgr->llc_msg_waiter);
1789 mutex_init(&lgr->llc_conf_mutex);
1790 lgr->llc_testlink_time = READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
1793 /* called after lgr was removed from lgr_list */
1794 void smc_llc_lgr_clear(struct smc_link_group *lgr)
1796 smc_llc_event_flush(lgr);
1797 wake_up_all(&lgr->llc_flow_waiter);
1798 wake_up_all(&lgr->llc_msg_waiter);
1799 cancel_work_sync(&lgr->llc_event_work);
1800 cancel_work_sync(&lgr->llc_add_link_work);
1801 cancel_work_sync(&lgr->llc_del_link_work);
1802 if (lgr->delayed_event) {
1803 kfree(lgr->delayed_event);
1804 lgr->delayed_event = NULL;
1819 SMC_LGR_ID_SIZE, &link->lgr->id,
1824 if (link->lgr->llc_testlink_time) {
1825 link->llc_testlink_time = link->lgr->llc_testlink_time;
1837 SMC_LGR_ID_SIZE, &link->lgr->id,
1849 struct smc_link_group *lgr = send_link->lgr;
1857 qentry = smc_llc_wait(lgr, send_link, SMC_LLC_WAIT_TIME,
1863 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1868 int smc_llc_do_delete_rkey(struct smc_link_group *lgr,
1875 send_link = smc_llc_usable_link(lgr);
1884 qentry = smc_llc_wait(lgr, send_link, SMC_LLC_WAIT_TIME,
1890 smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
1898 link_uid = htonl(*((u32 *)link->lgr->id) + link->link_id);