1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. 7 */ 8 9 /* 10 * Cross Partition Communication (XPC) uv-based functions. 11 * 12 * Architecture specific implementation of common functions. 13 * 14 */ 15 16 #include <linux/kernel.h> 17 #include <linux/mm.h> 18 #include <linux/interrupt.h> 19 #include <linux/delay.h> 20 #include <linux/device.h> 21 #include <linux/cpu.h> 22 #include <linux/module.h> 23 #include <linux/err.h> 24 #include <linux/slab.h> 25 #include <linux/numa.h> 26 #include <asm/uv/uv_hub.h> 27 #include <asm/uv/bios.h> 28 #include <asm/uv/uv_irq.h> 29 #include "../sgi-gru/gru.h" 30 #include "../sgi-gru/grukservices.h" 31 #include "xpc.h" 32 33 static struct xpc_heartbeat_uv *xpc_heartbeat_uv; 34 35 #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES) 36 #define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ 37 XPC_ACTIVATE_MSG_SIZE_UV) 38 #define XPC_ACTIVATE_IRQ_NAME "xpc_activate" 39 40 #define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES) 41 #define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ 42 XPC_NOTIFY_MSG_SIZE_UV) 43 #define XPC_NOTIFY_IRQ_NAME "xpc_notify" 44 45 static int xpc_mq_node = NUMA_NO_NODE; 46 47 static struct xpc_gru_mq_uv *xpc_activate_mq_uv; 48 static struct xpc_gru_mq_uv *xpc_notify_mq_uv; 49 50 static int 51 xpc_setup_partitions_uv(void) 52 { 53 short partid; 54 struct xpc_partition_uv *part_uv; 55 56 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 57 part_uv = &xpc_partitions[partid].sn.uv; 58 59 mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex); 60 spin_lock_init(&part_uv->flags_lock); 61 part_uv->remote_act_state = XPC_P_AS_INACTIVE; 62 } 63 return 0; 64 } 65 66 static void 67 xpc_teardown_partitions_uv(void) 68 { 69 short partid; 70 struct xpc_partition_uv *part_uv; 71 unsigned long irq_flags; 72 73 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 74 part_uv = &xpc_partitions[partid].sn.uv; 75 76 if (part_uv->cached_activate_gru_mq_desc != NULL) { 77 mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex); 78 spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 79 part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; 80 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 81 kfree(part_uv->cached_activate_gru_mq_desc); 82 part_uv->cached_activate_gru_mq_desc = NULL; 83 mutex_unlock(&part_uv-> 84 cached_activate_gru_mq_desc_mutex); 85 } 86 } 87 } 88 89 static int 90 xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) 91 { 92 int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); 93 94 mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, 95 UV_AFFINITY_CPU); 96 if (mq->irq < 0) 97 return mq->irq; 98 99 mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); 100 101 return 0; 102 } 103 104 static void 105 xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq) 106 { 107 uv_teardown_irq(mq->irq); 108 } 109 110 static int 111 xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq) 112 { 113 int ret; 114 115 ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address), 116 mq->order, &mq->mmr_offset); 117 if (ret < 0) { 118 dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, " 119 "ret=%d\n", ret); 120 return ret; 121 } 122 123 mq->watchlist_num = ret; 124 return 0; 125 } 126 127 static void 128 xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq) 129 { 130 int ret; 131 int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); 132 133 ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num); 134 BUG_ON(ret != BIOS_STATUS_SUCCESS); 135 } 136 137 static struct xpc_gru_mq_uv * 138 xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, 139 irq_handler_t irq_handler) 140 { 141 enum xp_retval xp_ret; 142 int ret; 143 int nid; 144 int nasid; 145 int pg_order; 146 struct page *page; 147 struct xpc_gru_mq_uv *mq; 148 struct uv_IO_APIC_route_entry *mmr_value; 149 150 mq = kmalloc_obj(struct xpc_gru_mq_uv); 151 if (mq == NULL) { 152 dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " 153 "a xpc_gru_mq_uv structure\n"); 154 ret = -ENOMEM; 155 goto out_0; 156 } 157 158 mq->gru_mq_desc = kzalloc_obj(struct gru_message_queue_desc); 159 if (mq->gru_mq_desc == NULL) { 160 dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " 161 "a gru_message_queue_desc structure\n"); 162 ret = -ENOMEM; 163 goto out_1; 164 } 165 166 pg_order = get_order(mq_size); 167 mq->order = pg_order + PAGE_SHIFT; 168 mq_size = 1UL << mq->order; 169 170 mq->mmr_blade = uv_cpu_to_blade_id(cpu); 171 172 nid = cpu_to_node(cpu); 173 page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, 174 pg_order); 175 if (page == NULL) { 176 dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " 177 "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); 178 ret = -ENOMEM; 179 goto out_2; 180 } 181 mq->address = page_address(page); 182 183 /* enable generation of irq when GRU mq operation occurs to this mq */ 184 ret = xpc_gru_mq_watchlist_alloc_uv(mq); 185 if (ret != 0) 186 goto out_3; 187 188 ret = xpc_get_gru_mq_irq_uv(mq, cpu, irq_name); 189 if (ret != 0) 190 goto out_4; 191 192 ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL); 193 if (ret != 0) { 194 dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n", 195 mq->irq, -ret); 196 goto out_5; 197 } 198 199 nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu)); 200 201 mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value; 202 ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size, 203 nasid, mmr_value->vector, mmr_value->dest); 204 if (ret != 0) { 205 dev_err(xpc_part, "gru_create_message_queue() returned " 206 "error=%d\n", ret); 207 ret = -EINVAL; 208 goto out_6; 209 } 210 211 /* allow other partitions to access this GRU mq */ 212 xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size); 213 if (xp_ret != xpSuccess) { 214 ret = -EACCES; 215 goto out_6; 216 } 217 218 return mq; 219 220 /* something went wrong */ 221 out_6: 222 free_irq(mq->irq, NULL); 223 out_5: 224 xpc_release_gru_mq_irq_uv(mq); 225 out_4: 226 xpc_gru_mq_watchlist_free_uv(mq); 227 out_3: 228 free_pages((unsigned long)mq->address, pg_order); 229 out_2: 230 kfree(mq->gru_mq_desc); 231 out_1: 232 kfree(mq); 233 out_0: 234 return ERR_PTR(ret); 235 } 236 237 static void 238 xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq) 239 { 240 unsigned int mq_size; 241 int pg_order; 242 int ret; 243 244 /* disallow other partitions to access GRU mq */ 245 mq_size = 1UL << mq->order; 246 ret = xp_restrict_memprotect(xp_pa(mq->address), mq_size); 247 BUG_ON(ret != xpSuccess); 248 249 /* unregister irq handler and release mq irq/vector mapping */ 250 free_irq(mq->irq, NULL); 251 xpc_release_gru_mq_irq_uv(mq); 252 253 /* disable generation of irq when GRU mq op occurs to this mq */ 254 xpc_gru_mq_watchlist_free_uv(mq); 255 256 pg_order = mq->order - PAGE_SHIFT; 257 free_pages((unsigned long)mq->address, pg_order); 258 259 kfree(mq); 260 } 261 262 static enum xp_retval 263 xpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg, 264 size_t msg_size) 265 { 266 enum xp_retval xp_ret; 267 int ret; 268 269 while (1) { 270 ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size); 271 if (ret == MQE_OK) { 272 xp_ret = xpSuccess; 273 break; 274 } 275 276 if (ret == MQE_QUEUE_FULL) { 277 dev_dbg(xpc_chan, "gru_send_message_gpa() returned " 278 "error=MQE_QUEUE_FULL\n"); 279 /* !!! handle QLimit reached; delay & try again */ 280 /* ??? Do we add a limit to the number of retries? */ 281 (void)msleep_interruptible(10); 282 } else if (ret == MQE_CONGESTION) { 283 dev_dbg(xpc_chan, "gru_send_message_gpa() returned " 284 "error=MQE_CONGESTION\n"); 285 /* !!! handle LB Overflow; simply try again */ 286 /* ??? Do we add a limit to the number of retries? */ 287 } else { 288 /* !!! Currently this is MQE_UNEXPECTED_CB_ERR */ 289 dev_err(xpc_chan, "gru_send_message_gpa() returned " 290 "error=%d\n", ret); 291 xp_ret = xpGruSendMqError; 292 break; 293 } 294 } 295 return xp_ret; 296 } 297 298 static void 299 xpc_process_activate_IRQ_rcvd_uv(void) 300 { 301 unsigned long irq_flags; 302 short partid; 303 struct xpc_partition *part; 304 u8 act_state_req; 305 306 DBUG_ON(xpc_activate_IRQ_rcvd == 0); 307 308 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 309 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 310 part = &xpc_partitions[partid]; 311 312 if (part->sn.uv.act_state_req == 0) 313 continue; 314 315 xpc_activate_IRQ_rcvd--; 316 BUG_ON(xpc_activate_IRQ_rcvd < 0); 317 318 act_state_req = part->sn.uv.act_state_req; 319 part->sn.uv.act_state_req = 0; 320 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 321 322 if (act_state_req == XPC_P_ASR_ACTIVATE_UV) { 323 if (part->act_state == XPC_P_AS_INACTIVE) 324 xpc_activate_partition(part); 325 else if (part->act_state == XPC_P_AS_DEACTIVATING) 326 XPC_DEACTIVATE_PARTITION(part, xpReactivating); 327 328 } else if (act_state_req == XPC_P_ASR_REACTIVATE_UV) { 329 if (part->act_state == XPC_P_AS_INACTIVE) 330 xpc_activate_partition(part); 331 else 332 XPC_DEACTIVATE_PARTITION(part, xpReactivating); 333 334 } else if (act_state_req == XPC_P_ASR_DEACTIVATE_UV) { 335 XPC_DEACTIVATE_PARTITION(part, part->sn.uv.reason); 336 337 } else { 338 BUG(); 339 } 340 341 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 342 if (xpc_activate_IRQ_rcvd == 0) 343 break; 344 } 345 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 346 347 } 348 349 static void 350 xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, 351 struct xpc_activate_mq_msghdr_uv *msg_hdr, 352 int part_setup, 353 int *wakeup_hb_checker) 354 { 355 unsigned long irq_flags; 356 struct xpc_partition_uv *part_uv = &part->sn.uv; 357 struct xpc_openclose_args *args; 358 359 part_uv->remote_act_state = msg_hdr->act_state; 360 361 switch (msg_hdr->type) { 362 case XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV: 363 /* syncing of remote_act_state was just done above */ 364 break; 365 366 case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { 367 struct xpc_activate_mq_msg_activate_req_uv *msg; 368 369 /* 370 * ??? Do we deal here with ts_jiffies being different 371 * ??? if act_state != XPC_P_AS_INACTIVE instead of 372 * ??? below? 373 */ 374 msg = container_of(msg_hdr, struct 375 xpc_activate_mq_msg_activate_req_uv, hdr); 376 377 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 378 if (part_uv->act_state_req == 0) 379 xpc_activate_IRQ_rcvd++; 380 part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; 381 part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ 382 part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; 383 part_uv->heartbeat_gpa = msg->heartbeat_gpa; 384 385 if (msg->activate_gru_mq_desc_gpa != 386 part_uv->activate_gru_mq_desc_gpa) { 387 spin_lock(&part_uv->flags_lock); 388 part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; 389 spin_unlock(&part_uv->flags_lock); 390 part_uv->activate_gru_mq_desc_gpa = 391 msg->activate_gru_mq_desc_gpa; 392 } 393 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 394 395 (*wakeup_hb_checker)++; 396 break; 397 } 398 case XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV: { 399 struct xpc_activate_mq_msg_deactivate_req_uv *msg; 400 401 msg = container_of(msg_hdr, struct 402 xpc_activate_mq_msg_deactivate_req_uv, hdr); 403 404 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 405 if (part_uv->act_state_req == 0) 406 xpc_activate_IRQ_rcvd++; 407 part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 408 part_uv->reason = msg->reason; 409 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 410 411 (*wakeup_hb_checker)++; 412 return; 413 } 414 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { 415 struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; 416 417 if (!part_setup) 418 break; 419 420 msg = container_of(msg_hdr, struct 421 xpc_activate_mq_msg_chctl_closerequest_uv, 422 hdr); 423 args = &part->remote_openclose_args[msg->ch_number]; 424 args->reason = msg->reason; 425 426 spin_lock_irqsave(&part->chctl_lock, irq_flags); 427 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREQUEST; 428 spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 429 430 xpc_wakeup_channel_mgr(part); 431 break; 432 } 433 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { 434 struct xpc_activate_mq_msg_chctl_closereply_uv *msg; 435 436 if (!part_setup) 437 break; 438 439 msg = container_of(msg_hdr, struct 440 xpc_activate_mq_msg_chctl_closereply_uv, 441 hdr); 442 443 spin_lock_irqsave(&part->chctl_lock, irq_flags); 444 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREPLY; 445 spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 446 447 xpc_wakeup_channel_mgr(part); 448 break; 449 } 450 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { 451 struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; 452 453 if (!part_setup) 454 break; 455 456 msg = container_of(msg_hdr, struct 457 xpc_activate_mq_msg_chctl_openrequest_uv, 458 hdr); 459 args = &part->remote_openclose_args[msg->ch_number]; 460 args->entry_size = msg->entry_size; 461 args->local_nentries = msg->local_nentries; 462 463 spin_lock_irqsave(&part->chctl_lock, irq_flags); 464 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREQUEST; 465 spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 466 467 xpc_wakeup_channel_mgr(part); 468 break; 469 } 470 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { 471 struct xpc_activate_mq_msg_chctl_openreply_uv *msg; 472 473 if (!part_setup) 474 break; 475 476 msg = container_of(msg_hdr, struct 477 xpc_activate_mq_msg_chctl_openreply_uv, hdr); 478 args = &part->remote_openclose_args[msg->ch_number]; 479 args->remote_nentries = msg->remote_nentries; 480 args->local_nentries = msg->local_nentries; 481 args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa; 482 483 spin_lock_irqsave(&part->chctl_lock, irq_flags); 484 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY; 485 spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 486 487 xpc_wakeup_channel_mgr(part); 488 break; 489 } 490 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { 491 struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; 492 493 if (!part_setup) 494 break; 495 496 msg = container_of(msg_hdr, struct 497 xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); 498 spin_lock_irqsave(&part->chctl_lock, irq_flags); 499 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE; 500 spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 501 502 xpc_wakeup_channel_mgr(part); 503 } 504 fallthrough; 505 case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: 506 spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 507 part_uv->flags |= XPC_P_ENGAGED_UV; 508 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 509 break; 510 511 case XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV: 512 spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 513 part_uv->flags &= ~XPC_P_ENGAGED_UV; 514 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 515 break; 516 517 default: 518 dev_err(xpc_part, "received unknown activate_mq msg type=%d " 519 "from partition=%d\n", msg_hdr->type, XPC_PARTID(part)); 520 521 /* get hb checker to deactivate from the remote partition */ 522 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 523 if (part_uv->act_state_req == 0) 524 xpc_activate_IRQ_rcvd++; 525 part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 526 part_uv->reason = xpBadMsgType; 527 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 528 529 (*wakeup_hb_checker)++; 530 return; 531 } 532 533 if (msg_hdr->rp_ts_jiffies != part->remote_rp_ts_jiffies && 534 part->remote_rp_ts_jiffies != 0) { 535 /* 536 * ??? Does what we do here need to be sensitive to 537 * ??? act_state or remote_act_state? 538 */ 539 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 540 if (part_uv->act_state_req == 0) 541 xpc_activate_IRQ_rcvd++; 542 part_uv->act_state_req = XPC_P_ASR_REACTIVATE_UV; 543 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 544 545 (*wakeup_hb_checker)++; 546 } 547 } 548 549 static irqreturn_t 550 xpc_handle_activate_IRQ_uv(int irq, void *dev_id) 551 { 552 struct xpc_activate_mq_msghdr_uv *msg_hdr; 553 short partid; 554 struct xpc_partition *part; 555 int wakeup_hb_checker = 0; 556 int part_referenced; 557 558 while (1) { 559 msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc); 560 if (msg_hdr == NULL) 561 break; 562 563 partid = msg_hdr->partid; 564 if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { 565 dev_err(xpc_part, "xpc_handle_activate_IRQ_uv() " 566 "received invalid partid=0x%x in message\n", 567 partid); 568 } else { 569 part = &xpc_partitions[partid]; 570 571 part_referenced = xpc_part_ref(part); 572 xpc_handle_activate_mq_msg_uv(part, msg_hdr, 573 part_referenced, 574 &wakeup_hb_checker); 575 if (part_referenced) 576 xpc_part_deref(part); 577 } 578 579 gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr); 580 } 581 582 if (wakeup_hb_checker) 583 wake_up_interruptible(&xpc_activate_IRQ_wq); 584 585 return IRQ_HANDLED; 586 } 587 588 static enum xp_retval 589 xpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc, 590 unsigned long gru_mq_desc_gpa) 591 { 592 enum xp_retval ret; 593 594 ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa, 595 sizeof(struct gru_message_queue_desc)); 596 if (ret == xpSuccess) 597 gru_mq_desc->mq = NULL; 598 599 return ret; 600 } 601 602 static enum xp_retval 603 xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size, 604 int msg_type) 605 { 606 struct xpc_activate_mq_msghdr_uv *msg_hdr = msg; 607 struct xpc_partition_uv *part_uv = &part->sn.uv; 608 struct gru_message_queue_desc *gru_mq_desc; 609 unsigned long irq_flags; 610 enum xp_retval ret; 611 612 DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV); 613 614 msg_hdr->type = msg_type; 615 msg_hdr->partid = xp_partition_id; 616 msg_hdr->act_state = part->act_state; 617 msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies; 618 619 mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex); 620 again: 621 if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) { 622 gru_mq_desc = part_uv->cached_activate_gru_mq_desc; 623 if (gru_mq_desc == NULL) { 624 gru_mq_desc = kmalloc_obj(struct gru_message_queue_desc, 625 GFP_ATOMIC); 626 if (gru_mq_desc == NULL) { 627 ret = xpNoMemory; 628 goto done; 629 } 630 part_uv->cached_activate_gru_mq_desc = gru_mq_desc; 631 } 632 633 ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc, 634 part_uv-> 635 activate_gru_mq_desc_gpa); 636 if (ret != xpSuccess) 637 goto done; 638 639 spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 640 part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; 641 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 642 } 643 644 /* ??? Is holding a spin_lock (ch->lock) during this call a bad idea? */ 645 ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg, 646 msg_size); 647 if (ret != xpSuccess) { 648 smp_rmb(); /* ensure a fresh copy of part_uv->flags */ 649 if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) 650 goto again; 651 } 652 done: 653 mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex); 654 return ret; 655 } 656 657 static void 658 xpc_send_activate_IRQ_part_uv(struct xpc_partition *part, void *msg, 659 size_t msg_size, int msg_type) 660 { 661 enum xp_retval ret; 662 663 ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type); 664 if (unlikely(ret != xpSuccess)) 665 XPC_DEACTIVATE_PARTITION(part, ret); 666 } 667 668 static void 669 xpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags, 670 void *msg, size_t msg_size, int msg_type) 671 { 672 struct xpc_partition *part = &xpc_partitions[ch->partid]; 673 enum xp_retval ret; 674 675 ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type); 676 if (unlikely(ret != xpSuccess)) { 677 if (irq_flags != NULL) 678 spin_unlock_irqrestore(&ch->lock, *irq_flags); 679 680 XPC_DEACTIVATE_PARTITION(part, ret); 681 682 if (irq_flags != NULL) 683 spin_lock_irqsave(&ch->lock, *irq_flags); 684 } 685 } 686 687 static void 688 xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req) 689 { 690 unsigned long irq_flags; 691 struct xpc_partition_uv *part_uv = &part->sn.uv; 692 693 /* 694 * !!! Make our side think that the remote partition sent an activate 695 * !!! mq message our way by doing what the activate IRQ handler would 696 * !!! do had one really been sent. 697 */ 698 699 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 700 if (part_uv->act_state_req == 0) 701 xpc_activate_IRQ_rcvd++; 702 part_uv->act_state_req = act_state_req; 703 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 704 705 wake_up_interruptible(&xpc_activate_IRQ_wq); 706 } 707 708 static enum xp_retval 709 xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa, 710 size_t *len) 711 { 712 s64 status; 713 enum xp_retval ret; 714 715 status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa, 716 (u64 *)len); 717 if (status == BIOS_STATUS_SUCCESS) 718 ret = xpSuccess; 719 else if (status == BIOS_STATUS_MORE_PASSES) 720 ret = xpNeedMoreInfo; 721 else 722 ret = xpBiosError; 723 724 return ret; 725 } 726 727 static int 728 xpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp) 729 { 730 xpc_heartbeat_uv = 731 &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat; 732 rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv); 733 rp->sn.uv.activate_gru_mq_desc_gpa = 734 uv_gpa(xpc_activate_mq_uv->gru_mq_desc); 735 return 0; 736 } 737 738 static void 739 xpc_allow_hb_uv(short partid) 740 { 741 } 742 743 static void 744 xpc_disallow_hb_uv(short partid) 745 { 746 } 747 748 static void 749 xpc_disallow_all_hbs_uv(void) 750 { 751 } 752 753 static void 754 xpc_increment_heartbeat_uv(void) 755 { 756 xpc_heartbeat_uv->value++; 757 } 758 759 static void 760 xpc_offline_heartbeat_uv(void) 761 { 762 xpc_increment_heartbeat_uv(); 763 xpc_heartbeat_uv->offline = 1; 764 } 765 766 static void 767 xpc_online_heartbeat_uv(void) 768 { 769 xpc_increment_heartbeat_uv(); 770 xpc_heartbeat_uv->offline = 0; 771 } 772 773 static void 774 xpc_heartbeat_init_uv(void) 775 { 776 xpc_heartbeat_uv->value = 1; 777 xpc_heartbeat_uv->offline = 0; 778 } 779 780 static void 781 xpc_heartbeat_exit_uv(void) 782 { 783 xpc_offline_heartbeat_uv(); 784 } 785 786 static enum xp_retval 787 xpc_get_remote_heartbeat_uv(struct xpc_partition *part) 788 { 789 struct xpc_partition_uv *part_uv = &part->sn.uv; 790 enum xp_retval ret; 791 792 ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat), 793 part_uv->heartbeat_gpa, 794 sizeof(struct xpc_heartbeat_uv)); 795 if (ret != xpSuccess) 796 return ret; 797 798 if (part_uv->cached_heartbeat.value == part->last_heartbeat && 799 !part_uv->cached_heartbeat.offline) { 800 801 ret = xpNoHeartbeat; 802 } else { 803 part->last_heartbeat = part_uv->cached_heartbeat.value; 804 } 805 return ret; 806 } 807 808 static void 809 xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, 810 unsigned long remote_rp_gpa, int nasid) 811 { 812 short partid = remote_rp->SAL_partid; 813 struct xpc_partition *part = &xpc_partitions[partid]; 814 struct xpc_activate_mq_msg_activate_req_uv msg; 815 816 part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */ 817 part->remote_rp_ts_jiffies = remote_rp->ts_jiffies; 818 part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa; 819 part->sn.uv.activate_gru_mq_desc_gpa = 820 remote_rp->sn.uv.activate_gru_mq_desc_gpa; 821 822 /* 823 * ??? Is it a good idea to make this conditional on what is 824 * ??? potentially stale state information? 825 */ 826 if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) { 827 msg.rp_gpa = uv_gpa(xpc_rsvd_page); 828 msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa; 829 msg.activate_gru_mq_desc_gpa = 830 xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa; 831 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 832 XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV); 833 } 834 835 if (part->act_state == XPC_P_AS_INACTIVE) 836 xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV); 837 } 838 839 static void 840 xpc_request_partition_reactivation_uv(struct xpc_partition *part) 841 { 842 xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV); 843 } 844 845 static void 846 xpc_request_partition_deactivation_uv(struct xpc_partition *part) 847 { 848 struct xpc_activate_mq_msg_deactivate_req_uv msg; 849 850 /* 851 * ??? Is it a good idea to make this conditional on what is 852 * ??? potentially stale state information? 853 */ 854 if (part->sn.uv.remote_act_state != XPC_P_AS_DEACTIVATING && 855 part->sn.uv.remote_act_state != XPC_P_AS_INACTIVE) { 856 857 msg.reason = part->reason; 858 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 859 XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV); 860 } 861 } 862 863 static void 864 xpc_cancel_partition_deactivation_request_uv(struct xpc_partition *part) 865 { 866 /* nothing needs to be done */ 867 return; 868 } 869 870 static void 871 xpc_init_fifo_uv(struct xpc_fifo_head_uv *head) 872 { 873 head->first = NULL; 874 head->last = NULL; 875 spin_lock_init(&head->lock); 876 head->n_entries = 0; 877 } 878 879 static void * 880 xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head) 881 { 882 unsigned long irq_flags; 883 struct xpc_fifo_entry_uv *first; 884 885 spin_lock_irqsave(&head->lock, irq_flags); 886 first = head->first; 887 if (head->first != NULL) { 888 head->first = first->next; 889 if (head->first == NULL) 890 head->last = NULL; 891 892 head->n_entries--; 893 BUG_ON(head->n_entries < 0); 894 895 first->next = NULL; 896 } 897 spin_unlock_irqrestore(&head->lock, irq_flags); 898 return first; 899 } 900 901 static void 902 xpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head, 903 struct xpc_fifo_entry_uv *last) 904 { 905 unsigned long irq_flags; 906 907 last->next = NULL; 908 spin_lock_irqsave(&head->lock, irq_flags); 909 if (head->last != NULL) 910 head->last->next = last; 911 else 912 head->first = last; 913 head->last = last; 914 head->n_entries++; 915 spin_unlock_irqrestore(&head->lock, irq_flags); 916 } 917 918 static int 919 xpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head) 920 { 921 return head->n_entries; 922 } 923 924 /* 925 * Setup the channel structures that are uv specific. 926 */ 927 static enum xp_retval 928 xpc_setup_ch_structures_uv(struct xpc_partition *part) 929 { 930 struct xpc_channel_uv *ch_uv; 931 int ch_number; 932 933 for (ch_number = 0; ch_number < part->nchannels; ch_number++) { 934 ch_uv = &part->channels[ch_number].sn.uv; 935 936 xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 937 xpc_init_fifo_uv(&ch_uv->recv_msg_list); 938 } 939 940 return xpSuccess; 941 } 942 943 /* 944 * Teardown the channel structures that are uv specific. 945 */ 946 static void 947 xpc_teardown_ch_structures_uv(struct xpc_partition *part) 948 { 949 /* nothing needs to be done */ 950 return; 951 } 952 953 static enum xp_retval 954 xpc_make_first_contact_uv(struct xpc_partition *part) 955 { 956 struct xpc_activate_mq_msg_uv msg; 957 958 /* 959 * We send a sync msg to get the remote partition's remote_act_state 960 * updated to our current act_state which at this point should 961 * be XPC_P_AS_ACTIVATING. 962 */ 963 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 964 XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV); 965 966 while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) || 967 (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) { 968 969 dev_dbg(xpc_part, "waiting to make first contact with " 970 "partition %d\n", XPC_PARTID(part)); 971 972 /* wait a 1/4 of a second or so */ 973 (void)msleep_interruptible(250); 974 975 if (part->act_state == XPC_P_AS_DEACTIVATING) 976 return part->reason; 977 } 978 979 return xpSuccess; 980 } 981 982 static u64 983 xpc_get_chctl_all_flags_uv(struct xpc_partition *part) 984 { 985 unsigned long irq_flags; 986 union xpc_channel_ctl_flags chctl; 987 988 spin_lock_irqsave(&part->chctl_lock, irq_flags); 989 chctl = part->chctl; 990 if (chctl.all_flags != 0) 991 part->chctl.all_flags = 0; 992 993 spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 994 return chctl.all_flags; 995 } 996 997 static enum xp_retval 998 xpc_allocate_send_msg_slot_uv(struct xpc_channel *ch) 999 { 1000 struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1001 struct xpc_send_msg_slot_uv *msg_slot; 1002 unsigned long irq_flags; 1003 int nentries; 1004 int entry; 1005 size_t nbytes; 1006 1007 for (nentries = ch->local_nentries; nentries > 0; nentries--) { 1008 nbytes = nentries * sizeof(struct xpc_send_msg_slot_uv); 1009 ch_uv->send_msg_slots = kzalloc(nbytes, GFP_KERNEL); 1010 if (ch_uv->send_msg_slots == NULL) 1011 continue; 1012 1013 for (entry = 0; entry < nentries; entry++) { 1014 msg_slot = &ch_uv->send_msg_slots[entry]; 1015 1016 msg_slot->msg_slot_number = entry; 1017 xpc_put_fifo_entry_uv(&ch_uv->msg_slot_free_list, 1018 &msg_slot->next); 1019 } 1020 1021 spin_lock_irqsave(&ch->lock, irq_flags); 1022 if (nentries < ch->local_nentries) 1023 ch->local_nentries = nentries; 1024 spin_unlock_irqrestore(&ch->lock, irq_flags); 1025 return xpSuccess; 1026 } 1027 1028 return xpNoMemory; 1029 } 1030 1031 static enum xp_retval 1032 xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch) 1033 { 1034 struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1035 struct xpc_notify_mq_msg_uv *msg_slot; 1036 unsigned long irq_flags; 1037 int nentries; 1038 int entry; 1039 size_t nbytes; 1040 1041 for (nentries = ch->remote_nentries; nentries > 0; nentries--) { 1042 nbytes = nentries * ch->entry_size; 1043 ch_uv->recv_msg_slots = kzalloc(nbytes, GFP_KERNEL); 1044 if (ch_uv->recv_msg_slots == NULL) 1045 continue; 1046 1047 for (entry = 0; entry < nentries; entry++) { 1048 msg_slot = ch_uv->recv_msg_slots + 1049 entry * ch->entry_size; 1050 1051 msg_slot->hdr.msg_slot_number = entry; 1052 } 1053 1054 spin_lock_irqsave(&ch->lock, irq_flags); 1055 if (nentries < ch->remote_nentries) 1056 ch->remote_nentries = nentries; 1057 spin_unlock_irqrestore(&ch->lock, irq_flags); 1058 return xpSuccess; 1059 } 1060 1061 return xpNoMemory; 1062 } 1063 1064 /* 1065 * Allocate msg_slots associated with the channel. 1066 */ 1067 static enum xp_retval 1068 xpc_setup_msg_structures_uv(struct xpc_channel *ch) 1069 { 1070 static enum xp_retval ret; 1071 struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1072 1073 DBUG_ON(ch->flags & XPC_C_SETUP); 1074 1075 ch_uv->cached_notify_gru_mq_desc = kmalloc_obj(struct gru_message_queue_desc); 1076 if (ch_uv->cached_notify_gru_mq_desc == NULL) 1077 return xpNoMemory; 1078 1079 ret = xpc_allocate_send_msg_slot_uv(ch); 1080 if (ret == xpSuccess) { 1081 1082 ret = xpc_allocate_recv_msg_slot_uv(ch); 1083 if (ret != xpSuccess) { 1084 kfree(ch_uv->send_msg_slots); 1085 xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 1086 } 1087 } 1088 return ret; 1089 } 1090 1091 /* 1092 * Free up msg_slots and clear other stuff that were setup for the specified 1093 * channel. 1094 */ 1095 static void 1096 xpc_teardown_msg_structures_uv(struct xpc_channel *ch) 1097 { 1098 struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1099 1100 lockdep_assert_held(&ch->lock); 1101 1102 kfree(ch_uv->cached_notify_gru_mq_desc); 1103 ch_uv->cached_notify_gru_mq_desc = NULL; 1104 1105 if (ch->flags & XPC_C_SETUP) { 1106 xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 1107 kfree(ch_uv->send_msg_slots); 1108 xpc_init_fifo_uv(&ch_uv->recv_msg_list); 1109 kfree(ch_uv->recv_msg_slots); 1110 } 1111 } 1112 1113 static void 1114 xpc_send_chctl_closerequest_uv(struct xpc_channel *ch, unsigned long *irq_flags) 1115 { 1116 struct xpc_activate_mq_msg_chctl_closerequest_uv msg; 1117 1118 msg.ch_number = ch->number; 1119 msg.reason = ch->reason; 1120 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 1121 XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV); 1122 } 1123 1124 static void 1125 xpc_send_chctl_closereply_uv(struct xpc_channel *ch, unsigned long *irq_flags) 1126 { 1127 struct xpc_activate_mq_msg_chctl_closereply_uv msg; 1128 1129 msg.ch_number = ch->number; 1130 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 1131 XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV); 1132 } 1133 1134 static void 1135 xpc_send_chctl_openrequest_uv(struct xpc_channel *ch, unsigned long *irq_flags) 1136 { 1137 struct xpc_activate_mq_msg_chctl_openrequest_uv msg; 1138 1139 msg.ch_number = ch->number; 1140 msg.entry_size = ch->entry_size; 1141 msg.local_nentries = ch->local_nentries; 1142 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 1143 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV); 1144 } 1145 1146 static void 1147 xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags) 1148 { 1149 struct xpc_activate_mq_msg_chctl_openreply_uv msg; 1150 1151 msg.ch_number = ch->number; 1152 msg.local_nentries = ch->local_nentries; 1153 msg.remote_nentries = ch->remote_nentries; 1154 msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc); 1155 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 1156 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV); 1157 } 1158 1159 static void 1160 xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags) 1161 { 1162 struct xpc_activate_mq_msg_chctl_opencomplete_uv msg; 1163 1164 msg.ch_number = ch->number; 1165 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 1166 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV); 1167 } 1168 1169 static void 1170 xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) 1171 { 1172 unsigned long irq_flags; 1173 1174 spin_lock_irqsave(&part->chctl_lock, irq_flags); 1175 part->chctl.flags[ch_number] |= XPC_CHCTL_MSGREQUEST; 1176 spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 1177 1178 xpc_wakeup_channel_mgr(part); 1179 } 1180 1181 static enum xp_retval 1182 xpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch, 1183 unsigned long gru_mq_desc_gpa) 1184 { 1185 struct xpc_channel_uv *ch_uv = &ch->sn.uv; 1186 1187 DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL); 1188 return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc, 1189 gru_mq_desc_gpa); 1190 } 1191 1192 static void 1193 xpc_indicate_partition_engaged_uv(struct xpc_partition *part) 1194 { 1195 struct xpc_activate_mq_msg_uv msg; 1196 1197 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 1198 XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV); 1199 } 1200 1201 static void 1202 xpc_indicate_partition_disengaged_uv(struct xpc_partition *part) 1203 { 1204 struct xpc_activate_mq_msg_uv msg; 1205 1206 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), 1207 XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV); 1208 } 1209 1210 static void 1211 xpc_assume_partition_disengaged_uv(short partid) 1212 { 1213 struct xpc_partition_uv *part_uv = &xpc_partitions[partid].sn.uv; 1214 unsigned long irq_flags; 1215 1216 spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 1217 part_uv->flags &= ~XPC_P_ENGAGED_UV; 1218 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 1219 } 1220 1221 static int 1222 xpc_partition_engaged_uv(short partid) 1223 { 1224 return (xpc_partitions[partid].sn.uv.flags & XPC_P_ENGAGED_UV) != 0; 1225 } 1226 1227 static int 1228 xpc_any_partition_engaged_uv(void) 1229 { 1230 struct xpc_partition_uv *part_uv; 1231 short partid; 1232 1233 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) { 1234 part_uv = &xpc_partitions[partid].sn.uv; 1235 if ((part_uv->flags & XPC_P_ENGAGED_UV) != 0) 1236 return 1; 1237 } 1238 return 0; 1239 } 1240 1241 static enum xp_retval 1242 xpc_allocate_msg_slot_uv(struct xpc_channel *ch, u32 flags, 1243 struct xpc_send_msg_slot_uv **address_of_msg_slot) 1244 { 1245 enum xp_retval ret; 1246 struct xpc_send_msg_slot_uv *msg_slot; 1247 struct xpc_fifo_entry_uv *entry; 1248 1249 while (1) { 1250 entry = xpc_get_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list); 1251 if (entry != NULL) 1252 break; 1253 1254 if (flags & XPC_NOWAIT) 1255 return xpNoWait; 1256 1257 ret = xpc_allocate_msg_wait(ch); 1258 if (ret != xpInterrupted && ret != xpTimeout) 1259 return ret; 1260 } 1261 1262 msg_slot = container_of(entry, struct xpc_send_msg_slot_uv, next); 1263 *address_of_msg_slot = msg_slot; 1264 return xpSuccess; 1265 } 1266 1267 static void 1268 xpc_free_msg_slot_uv(struct xpc_channel *ch, 1269 struct xpc_send_msg_slot_uv *msg_slot) 1270 { 1271 xpc_put_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list, &msg_slot->next); 1272 1273 /* wakeup anyone waiting for a free msg slot */ 1274 if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) 1275 wake_up(&ch->msg_allocate_wq); 1276 } 1277 1278 static void 1279 xpc_notify_sender_uv(struct xpc_channel *ch, 1280 struct xpc_send_msg_slot_uv *msg_slot, 1281 enum xp_retval reason) 1282 { 1283 xpc_notify_func func = msg_slot->func; 1284 1285 if (func != NULL && cmpxchg(&msg_slot->func, func, NULL) == func) { 1286 1287 atomic_dec(&ch->n_to_notify); 1288 1289 dev_dbg(xpc_chan, "msg_slot->func() called, msg_slot=0x%p " 1290 "msg_slot_number=%d partid=%d channel=%d\n", msg_slot, 1291 msg_slot->msg_slot_number, ch->partid, ch->number); 1292 1293 func(reason, ch->partid, ch->number, msg_slot->key); 1294 1295 dev_dbg(xpc_chan, "msg_slot->func() returned, msg_slot=0x%p " 1296 "msg_slot_number=%d partid=%d channel=%d\n", msg_slot, 1297 msg_slot->msg_slot_number, ch->partid, ch->number); 1298 } 1299 } 1300 1301 static void 1302 xpc_handle_notify_mq_ack_uv(struct xpc_channel *ch, 1303 struct xpc_notify_mq_msg_uv *msg) 1304 { 1305 struct xpc_send_msg_slot_uv *msg_slot; 1306 int entry = msg->hdr.msg_slot_number % ch->local_nentries; 1307 1308 msg_slot = &ch->sn.uv.send_msg_slots[entry]; 1309 1310 BUG_ON(msg_slot->msg_slot_number != msg->hdr.msg_slot_number); 1311 msg_slot->msg_slot_number += ch->local_nentries; 1312 1313 if (msg_slot->func != NULL) 1314 xpc_notify_sender_uv(ch, msg_slot, xpMsgDelivered); 1315 1316 xpc_free_msg_slot_uv(ch, msg_slot); 1317 } 1318 1319 static void 1320 xpc_handle_notify_mq_msg_uv(struct xpc_partition *part, 1321 struct xpc_notify_mq_msg_uv *msg) 1322 { 1323 struct xpc_partition_uv *part_uv = &part->sn.uv; 1324 struct xpc_channel *ch; 1325 struct xpc_channel_uv *ch_uv; 1326 struct xpc_notify_mq_msg_uv *msg_slot; 1327 unsigned long irq_flags; 1328 int ch_number = msg->hdr.ch_number; 1329 1330 if (unlikely(ch_number >= part->nchannels)) { 1331 dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received invalid " 1332 "channel number=0x%x in message from partid=%d\n", 1333 ch_number, XPC_PARTID(part)); 1334 1335 /* get hb checker to deactivate from the remote partition */ 1336 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 1337 if (part_uv->act_state_req == 0) 1338 xpc_activate_IRQ_rcvd++; 1339 part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 1340 part_uv->reason = xpBadChannelNumber; 1341 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 1342 1343 wake_up_interruptible(&xpc_activate_IRQ_wq); 1344 return; 1345 } 1346 1347 ch = &part->channels[ch_number]; 1348 xpc_msgqueue_ref(ch); 1349 1350 if (!(ch->flags & XPC_C_CONNECTED)) { 1351 xpc_msgqueue_deref(ch); 1352 return; 1353 } 1354 1355 /* see if we're really dealing with an ACK for a previously sent msg */ 1356 if (msg->hdr.size == 0) { 1357 xpc_handle_notify_mq_ack_uv(ch, msg); 1358 xpc_msgqueue_deref(ch); 1359 return; 1360 } 1361 1362 /* we're dealing with a normal message sent via the notify_mq */ 1363 ch_uv = &ch->sn.uv; 1364 1365 msg_slot = ch_uv->recv_msg_slots + 1366 (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size; 1367 1368 BUG_ON(msg_slot->hdr.size != 0); 1369 1370 memcpy(msg_slot, msg, msg->hdr.size); 1371 1372 xpc_put_fifo_entry_uv(&ch_uv->recv_msg_list, &msg_slot->hdr.u.next); 1373 1374 if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) { 1375 /* 1376 * If there is an existing idle kthread get it to deliver 1377 * the payload, otherwise we'll have to get the channel mgr 1378 * for this partition to create a kthread to do the delivery. 1379 */ 1380 if (atomic_read(&ch->kthreads_idle) > 0) 1381 wake_up_nr(&ch->idle_wq, 1); 1382 else 1383 xpc_send_chctl_local_msgrequest_uv(part, ch->number); 1384 } 1385 xpc_msgqueue_deref(ch); 1386 } 1387 1388 static irqreturn_t 1389 xpc_handle_notify_IRQ_uv(int irq, void *dev_id) 1390 { 1391 struct xpc_notify_mq_msg_uv *msg; 1392 short partid; 1393 struct xpc_partition *part; 1394 1395 while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) != 1396 NULL) { 1397 1398 partid = msg->hdr.partid; 1399 if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { 1400 dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received " 1401 "invalid partid=0x%x in message\n", partid); 1402 } else { 1403 part = &xpc_partitions[partid]; 1404 1405 if (xpc_part_ref(part)) { 1406 xpc_handle_notify_mq_msg_uv(part, msg); 1407 xpc_part_deref(part); 1408 } 1409 } 1410 1411 gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg); 1412 } 1413 1414 return IRQ_HANDLED; 1415 } 1416 1417 static int 1418 xpc_n_of_deliverable_payloads_uv(struct xpc_channel *ch) 1419 { 1420 return xpc_n_of_fifo_entries_uv(&ch->sn.uv.recv_msg_list); 1421 } 1422 1423 static void 1424 xpc_process_msg_chctl_flags_uv(struct xpc_partition *part, int ch_number) 1425 { 1426 struct xpc_channel *ch = &part->channels[ch_number]; 1427 int ndeliverable_payloads; 1428 1429 xpc_msgqueue_ref(ch); 1430 1431 ndeliverable_payloads = xpc_n_of_deliverable_payloads_uv(ch); 1432 1433 if (ndeliverable_payloads > 0 && 1434 (ch->flags & XPC_C_CONNECTED) && 1435 (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)) { 1436 1437 xpc_activate_kthreads(ch, ndeliverable_payloads); 1438 } 1439 1440 xpc_msgqueue_deref(ch); 1441 } 1442 1443 static enum xp_retval 1444 xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload, 1445 u16 payload_size, u8 notify_type, xpc_notify_func func, 1446 void *key) 1447 { 1448 enum xp_retval ret = xpSuccess; 1449 struct xpc_send_msg_slot_uv *msg_slot = NULL; 1450 struct xpc_notify_mq_msg_uv *msg; 1451 u8 msg_buffer[XPC_NOTIFY_MSG_SIZE_UV]; 1452 size_t msg_size; 1453 1454 DBUG_ON(notify_type != XPC_N_CALL); 1455 1456 msg_size = sizeof(struct xpc_notify_mq_msghdr_uv) + payload_size; 1457 if (msg_size > ch->entry_size) 1458 return xpPayloadTooBig; 1459 1460 xpc_msgqueue_ref(ch); 1461 1462 if (ch->flags & XPC_C_DISCONNECTING) { 1463 ret = ch->reason; 1464 goto out_1; 1465 } 1466 if (!(ch->flags & XPC_C_CONNECTED)) { 1467 ret = xpNotConnected; 1468 goto out_1; 1469 } 1470 1471 ret = xpc_allocate_msg_slot_uv(ch, flags, &msg_slot); 1472 if (ret != xpSuccess) 1473 goto out_1; 1474 1475 if (func != NULL) { 1476 atomic_inc(&ch->n_to_notify); 1477 1478 msg_slot->key = key; 1479 smp_wmb(); /* a non-NULL func must hit memory after the key */ 1480 msg_slot->func = func; 1481 1482 if (ch->flags & XPC_C_DISCONNECTING) { 1483 ret = ch->reason; 1484 goto out_2; 1485 } 1486 } 1487 1488 msg = (struct xpc_notify_mq_msg_uv *)&msg_buffer; 1489 msg->hdr.partid = xp_partition_id; 1490 msg->hdr.ch_number = ch->number; 1491 msg->hdr.size = msg_size; 1492 msg->hdr.msg_slot_number = msg_slot->msg_slot_number; 1493 memcpy(&msg->payload, payload, payload_size); 1494 1495 ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg, 1496 msg_size); 1497 if (ret == xpSuccess) 1498 goto out_1; 1499 1500 XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); 1501 out_2: 1502 if (func != NULL) { 1503 /* 1504 * Try to NULL the msg_slot's func field. If we fail, then 1505 * xpc_notify_senders_of_disconnect_uv() beat us to it, in which 1506 * case we need to pretend we succeeded to send the message 1507 * since the user will get a callout for the disconnect error 1508 * by xpc_notify_senders_of_disconnect_uv(), and to also get an 1509 * error returned here will confuse them. Additionally, since 1510 * in this case the channel is being disconnected we don't need 1511 * to put the msg_slot back on the free list. 1512 */ 1513 if (cmpxchg(&msg_slot->func, func, NULL) != func) { 1514 ret = xpSuccess; 1515 goto out_1; 1516 } 1517 1518 msg_slot->key = NULL; 1519 atomic_dec(&ch->n_to_notify); 1520 } 1521 xpc_free_msg_slot_uv(ch, msg_slot); 1522 out_1: 1523 xpc_msgqueue_deref(ch); 1524 return ret; 1525 } 1526 1527 /* 1528 * Tell the callers of xpc_send_notify() that the status of their payloads 1529 * is unknown because the channel is now disconnecting. 1530 * 1531 * We don't worry about putting these msg_slots on the free list since the 1532 * msg_slots themselves are about to be kfree'd. 1533 */ 1534 static void 1535 xpc_notify_senders_of_disconnect_uv(struct xpc_channel *ch) 1536 { 1537 struct xpc_send_msg_slot_uv *msg_slot; 1538 int entry; 1539 1540 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING)); 1541 1542 for (entry = 0; entry < ch->local_nentries; entry++) { 1543 1544 if (atomic_read(&ch->n_to_notify) == 0) 1545 break; 1546 1547 msg_slot = &ch->sn.uv.send_msg_slots[entry]; 1548 if (msg_slot->func != NULL) 1549 xpc_notify_sender_uv(ch, msg_slot, ch->reason); 1550 } 1551 } 1552 1553 /* 1554 * Get the next deliverable message's payload. 1555 */ 1556 static void * 1557 xpc_get_deliverable_payload_uv(struct xpc_channel *ch) 1558 { 1559 struct xpc_fifo_entry_uv *entry; 1560 struct xpc_notify_mq_msg_uv *msg; 1561 void *payload = NULL; 1562 1563 if (!(ch->flags & XPC_C_DISCONNECTING)) { 1564 entry = xpc_get_fifo_entry_uv(&ch->sn.uv.recv_msg_list); 1565 if (entry != NULL) { 1566 msg = container_of(entry, struct xpc_notify_mq_msg_uv, 1567 hdr.u.next); 1568 payload = &msg->payload; 1569 } 1570 } 1571 return payload; 1572 } 1573 1574 static void 1575 xpc_received_payload_uv(struct xpc_channel *ch, void *payload) 1576 { 1577 struct xpc_notify_mq_msg_uv *msg; 1578 enum xp_retval ret; 1579 1580 msg = container_of(payload, struct xpc_notify_mq_msg_uv, payload); 1581 1582 /* return an ACK to the sender of this message */ 1583 1584 msg->hdr.partid = xp_partition_id; 1585 msg->hdr.size = 0; /* size of zero indicates this is an ACK */ 1586 1587 ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg, 1588 sizeof(struct xpc_notify_mq_msghdr_uv)); 1589 if (ret != xpSuccess) 1590 XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); 1591 } 1592 1593 static const struct xpc_arch_operations xpc_arch_ops_uv = { 1594 .setup_partitions = xpc_setup_partitions_uv, 1595 .teardown_partitions = xpc_teardown_partitions_uv, 1596 .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv, 1597 .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv, 1598 .setup_rsvd_page = xpc_setup_rsvd_page_uv, 1599 1600 .allow_hb = xpc_allow_hb_uv, 1601 .disallow_hb = xpc_disallow_hb_uv, 1602 .disallow_all_hbs = xpc_disallow_all_hbs_uv, 1603 .increment_heartbeat = xpc_increment_heartbeat_uv, 1604 .offline_heartbeat = xpc_offline_heartbeat_uv, 1605 .online_heartbeat = xpc_online_heartbeat_uv, 1606 .heartbeat_init = xpc_heartbeat_init_uv, 1607 .heartbeat_exit = xpc_heartbeat_exit_uv, 1608 .get_remote_heartbeat = xpc_get_remote_heartbeat_uv, 1609 1610 .request_partition_activation = 1611 xpc_request_partition_activation_uv, 1612 .request_partition_reactivation = 1613 xpc_request_partition_reactivation_uv, 1614 .request_partition_deactivation = 1615 xpc_request_partition_deactivation_uv, 1616 .cancel_partition_deactivation_request = 1617 xpc_cancel_partition_deactivation_request_uv, 1618 1619 .setup_ch_structures = xpc_setup_ch_structures_uv, 1620 .teardown_ch_structures = xpc_teardown_ch_structures_uv, 1621 1622 .make_first_contact = xpc_make_first_contact_uv, 1623 1624 .get_chctl_all_flags = xpc_get_chctl_all_flags_uv, 1625 .send_chctl_closerequest = xpc_send_chctl_closerequest_uv, 1626 .send_chctl_closereply = xpc_send_chctl_closereply_uv, 1627 .send_chctl_openrequest = xpc_send_chctl_openrequest_uv, 1628 .send_chctl_openreply = xpc_send_chctl_openreply_uv, 1629 .send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv, 1630 .process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv, 1631 1632 .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv, 1633 1634 .setup_msg_structures = xpc_setup_msg_structures_uv, 1635 .teardown_msg_structures = xpc_teardown_msg_structures_uv, 1636 1637 .indicate_partition_engaged = xpc_indicate_partition_engaged_uv, 1638 .indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv, 1639 .assume_partition_disengaged = xpc_assume_partition_disengaged_uv, 1640 .partition_engaged = xpc_partition_engaged_uv, 1641 .any_partition_engaged = xpc_any_partition_engaged_uv, 1642 1643 .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv, 1644 .send_payload = xpc_send_payload_uv, 1645 .get_deliverable_payload = xpc_get_deliverable_payload_uv, 1646 .received_payload = xpc_received_payload_uv, 1647 .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, 1648 }; 1649 1650 static int 1651 xpc_init_mq_node(int nid) 1652 { 1653 int cpu; 1654 1655 cpus_read_lock(); 1656 1657 for_each_cpu(cpu, cpumask_of_node(nid)) { 1658 xpc_activate_mq_uv = 1659 xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid, 1660 XPC_ACTIVATE_IRQ_NAME, 1661 xpc_handle_activate_IRQ_uv); 1662 if (!IS_ERR(xpc_activate_mq_uv)) 1663 break; 1664 } 1665 if (IS_ERR(xpc_activate_mq_uv)) { 1666 cpus_read_unlock(); 1667 return PTR_ERR(xpc_activate_mq_uv); 1668 } 1669 1670 for_each_cpu(cpu, cpumask_of_node(nid)) { 1671 xpc_notify_mq_uv = 1672 xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid, 1673 XPC_NOTIFY_IRQ_NAME, 1674 xpc_handle_notify_IRQ_uv); 1675 if (!IS_ERR(xpc_notify_mq_uv)) 1676 break; 1677 } 1678 if (IS_ERR(xpc_notify_mq_uv)) { 1679 xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); 1680 cpus_read_unlock(); 1681 return PTR_ERR(xpc_notify_mq_uv); 1682 } 1683 1684 cpus_read_unlock(); 1685 return 0; 1686 } 1687 1688 int 1689 xpc_init_uv(void) 1690 { 1691 int nid; 1692 int ret = 0; 1693 1694 xpc_arch_ops = xpc_arch_ops_uv; 1695 1696 if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { 1697 dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n", 1698 XPC_MSG_HDR_MAX_SIZE); 1699 return -E2BIG; 1700 } 1701 1702 if (xpc_mq_node < 0) 1703 for_each_online_node(nid) { 1704 ret = xpc_init_mq_node(nid); 1705 1706 if (!ret) 1707 break; 1708 } 1709 else 1710 ret = xpc_init_mq_node(xpc_mq_node); 1711 1712 if (ret < 0) 1713 dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n", 1714 -ret); 1715 1716 return ret; 1717 } 1718 1719 void 1720 xpc_exit_uv(void) 1721 { 1722 xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); 1723 xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); 1724 } 1725 1726 module_param(xpc_mq_node, int, 0); 1727 MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues."); 1728