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