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) 2004-2006 Silicon Graphics, Inc. All Rights Reserved. 7 */ 8 9 10/* 11 * Cross Partition Communication (XPC) support - standard version. 12 * 13 * XPC provides a message passing capability that crosses partition 14 * boundaries. This module is made up of two parts: 15 * 16 * partition This part detects the presence/absence of other 17 * partitions. It provides a heartbeat and monitors 18 * the heartbeats of other partitions. 19 * 20 * channel This part manages the channels and sends/receives 21 * messages across them to/from other partitions. 22 * 23 * There are a couple of additional functions residing in XP, which 24 * provide an interface to XPC for its users. 25 * 26 * 27 * Caveats: 28 * 29 * . We currently have no way to determine which nasid an IPI came 30 * from. Thus, xpc_IPI_send() does a remote AMO write followed by 31 * an IPI. The AMO indicates where data is to be pulled from, so 32 * after the IPI arrives, the remote partition checks the AMO word. 33 * The IPI can actually arrive before the AMO however, so other code 34 * must periodically check for this case. Also, remote AMO operations 35 * do not reliably time out. Thus we do a remote PIO read solely to 36 * know whether the remote partition is down and whether we should 37 * stop sending IPIs to it. This remote PIO read operation is set up 38 * in a special nofault region so SAL knows to ignore (and cleanup) 39 * any errors due to the remote AMO write, PIO read, and/or PIO 40 * write operations. 41 * 42 * If/when new hardware solves this IPI problem, we should abandon 43 * the current approach. 44 * 45 */ 46 47 48#include <linux/kernel.h> 49#include <linux/module.h> 50#include <linux/init.h> 51#include <linux/sched.h> 52#include <linux/syscalls.h> 53#include <linux/cache.h> 54#include <linux/interrupt.h> 55#include <linux/delay.h> 56#include <linux/reboot.h> 57#include <linux/completion.h> 58#include <linux/kdebug.h> 59#include <asm/sn/intr.h> 60#include <asm/sn/sn_sal.h> 61#include <asm/uaccess.h> 62#include <asm/sn/xpc.h> 63 64 65/* define two XPC debug device structures to be used with dev_dbg() et al */ 66 67struct device_driver xpc_dbg_name = { 68 .name = "xpc" 69}; 70 71struct device xpc_part_dbg_subname = { 72 .bus_id = {0}, /* set to "part" at xpc_init() time */ 73 .driver = &xpc_dbg_name 74}; 75 76struct device xpc_chan_dbg_subname = { 77 .bus_id = {0}, /* set to "chan" at xpc_init() time */ 78 .driver = &xpc_dbg_name 79}; 80 81struct device *xpc_part = &xpc_part_dbg_subname; 82struct device *xpc_chan = &xpc_chan_dbg_subname; 83 84 85static int xpc_kdebug_ignore; 86 87 88/* systune related variables for /proc/sys directories */ 89 90static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; 91static int xpc_hb_min_interval = 1; 92static int xpc_hb_max_interval = 10; 93 94static int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_INTERVAL; 95static int xpc_hb_check_min_interval = 10; 96static int xpc_hb_check_max_interval = 120; 97 98int xpc_disengage_request_timelimit = XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT; 99static int xpc_disengage_request_min_timelimit = 0; 100static int xpc_disengage_request_max_timelimit = 120; 101 102static ctl_table xpc_sys_xpc_hb_dir[] = { 103 { 104 .ctl_name = CTL_UNNUMBERED, 105 .procname = "hb_interval", 106 .data = &xpc_hb_interval, 107 .maxlen = sizeof(int), 108 .mode = 0644, 109 .proc_handler = &proc_dointvec_minmax, 110 .strategy = &sysctl_intvec, 111 .extra1 = &xpc_hb_min_interval, 112 .extra2 = &xpc_hb_max_interval 113 }, 114 { 115 .ctl_name = CTL_UNNUMBERED, 116 .procname = "hb_check_interval", 117 .data = &xpc_hb_check_interval, 118 .maxlen = sizeof(int), 119 .mode = 0644, 120 .proc_handler = &proc_dointvec_minmax, 121 .strategy = &sysctl_intvec, 122 .extra1 = &xpc_hb_check_min_interval, 123 .extra2 = &xpc_hb_check_max_interval 124 }, 125 {} 126}; 127static ctl_table xpc_sys_xpc_dir[] = { 128 { 129 .ctl_name = CTL_UNNUMBERED, 130 .procname = "hb", 131 .mode = 0555, 132 .child = xpc_sys_xpc_hb_dir 133 }, 134 { 135 .ctl_name = CTL_UNNUMBERED, 136 .procname = "disengage_request_timelimit", 137 .data = &xpc_disengage_request_timelimit, 138 .maxlen = sizeof(int), 139 .mode = 0644, 140 .proc_handler = &proc_dointvec_minmax, 141 .strategy = &sysctl_intvec, 142 .extra1 = &xpc_disengage_request_min_timelimit, 143 .extra2 = &xpc_disengage_request_max_timelimit 144 }, 145 {} 146}; 147static ctl_table xpc_sys_dir[] = { 148 { 149 .ctl_name = CTL_UNNUMBERED, 150 .procname = "xpc", 151 .mode = 0555, 152 .child = xpc_sys_xpc_dir 153 }, 154 {} 155}; 156static struct ctl_table_header *xpc_sysctl; 157 158/* non-zero if any remote partition disengage request was timed out */ 159int xpc_disengage_request_timedout; 160 161/* #of IRQs received */ 162static atomic_t xpc_act_IRQ_rcvd; 163 164/* IRQ handler notifies this wait queue on receipt of an IRQ */ 165static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq); 166 167static unsigned long xpc_hb_check_timeout; 168 169/* notification that the xpc_hb_checker thread has exited */ 170static DECLARE_COMPLETION(xpc_hb_checker_exited); 171 172/* notification that the xpc_discovery thread has exited */ 173static DECLARE_COMPLETION(xpc_discovery_exited); 174 175 176static struct timer_list xpc_hb_timer; 177 178 179static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *); 180 181 182static int xpc_system_reboot(struct notifier_block *, unsigned long, void *); 183static struct notifier_block xpc_reboot_notifier = { 184 .notifier_call = xpc_system_reboot, 185}; 186 187static int xpc_system_die(struct notifier_block *, unsigned long, void *); 188static struct notifier_block xpc_die_notifier = { 189 .notifier_call = xpc_system_die, 190}; 191 192 193/* 194 * Timer function to enforce the timelimit on the partition disengage request. 195 */ 196static void 197xpc_timeout_partition_disengage_request(unsigned long data) 198{ 199 struct xpc_partition *part = (struct xpc_partition *) data; 200 201 202 DBUG_ON(jiffies < part->disengage_request_timeout); 203 204 (void) xpc_partition_disengaged(part); 205 206 DBUG_ON(part->disengage_request_timeout != 0); 207 DBUG_ON(xpc_partition_engaged(1UL << XPC_PARTID(part)) != 0); 208} 209 210 211/* 212 * Notify the heartbeat check thread that an IRQ has been received. 213 */ 214static irqreturn_t 215xpc_act_IRQ_handler(int irq, void *dev_id) 216{ 217 atomic_inc(&xpc_act_IRQ_rcvd); 218 wake_up_interruptible(&xpc_act_IRQ_wq); 219 return IRQ_HANDLED; 220} 221 222 223/* 224 * Timer to produce the heartbeat. The timer structures function is 225 * already set when this is initially called. A tunable is used to 226 * specify when the next timeout should occur. 227 */ 228static void 229xpc_hb_beater(unsigned long dummy) 230{ 231 xpc_vars->heartbeat++; 232 233 if (jiffies >= xpc_hb_check_timeout) { 234 wake_up_interruptible(&xpc_act_IRQ_wq); 235 } 236 237 xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ); 238 add_timer(&xpc_hb_timer); 239} 240 241 242/* 243 * This thread is responsible for nearly all of the partition 244 * activation/deactivation. 245 */ 246static int 247xpc_hb_checker(void *ignore) 248{ 249 int last_IRQ_count = 0; 250 int new_IRQ_count; 251 int force_IRQ=0; 252 253 254 /* this thread was marked active by xpc_hb_init() */ 255 256 daemonize(XPC_HB_CHECK_THREAD_NAME); 257 258 set_cpus_allowed(current, cpumask_of_cpu(XPC_HB_CHECK_CPU)); 259 260 xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ); 261 262 while (!(volatile int) xpc_exiting) { 263 264 dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have " 265 "been received\n", 266 (int) (xpc_hb_check_timeout - jiffies), 267 atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count); 268 269 270 /* checking of remote heartbeats is skewed by IRQ handling */ 271 if (jiffies >= xpc_hb_check_timeout) { 272 dev_dbg(xpc_part, "checking remote heartbeats\n"); 273 xpc_check_remote_hb(); 274 275 /* 276 * We need to periodically recheck to ensure no 277 * IPI/AMO pairs have been missed. That check 278 * must always reset xpc_hb_check_timeout. 279 */ 280 force_IRQ = 1; 281 } 282 283 284 /* check for outstanding IRQs */ 285 new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd); 286 if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) { 287 force_IRQ = 0; 288 289 dev_dbg(xpc_part, "found an IRQ to process; will be " 290 "resetting xpc_hb_check_timeout\n"); 291 292 last_IRQ_count += xpc_identify_act_IRQ_sender(); 293 if (last_IRQ_count < new_IRQ_count) { 294 /* retry once to help avoid missing AMO */ 295 (void) xpc_identify_act_IRQ_sender(); 296 } 297 last_IRQ_count = new_IRQ_count; 298 299 xpc_hb_check_timeout = jiffies + 300 (xpc_hb_check_interval * HZ); 301 } 302 303 /* wait for IRQ or timeout */ 304 (void) wait_event_interruptible(xpc_act_IRQ_wq, 305 (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) || 306 jiffies >= xpc_hb_check_timeout || 307 (volatile int) xpc_exiting)); 308 } 309 310 dev_dbg(xpc_part, "heartbeat checker is exiting\n"); 311 312 313 /* mark this thread as having exited */ 314 complete(&xpc_hb_checker_exited); 315 return 0; 316} 317 318 319/* 320 * This thread will attempt to discover other partitions to activate 321 * based on info provided by SAL. This new thread is short lived and 322 * will exit once discovery is complete. 323 */ 324static int 325xpc_initiate_discovery(void *ignore) 326{ 327 daemonize(XPC_DISCOVERY_THREAD_NAME); 328 329 xpc_discovery(); 330 331 dev_dbg(xpc_part, "discovery thread is exiting\n"); 332 333 /* mark this thread as having exited */ 334 complete(&xpc_discovery_exited); 335 return 0; 336} 337 338 339/* 340 * Establish first contact with the remote partititon. This involves pulling 341 * the XPC per partition variables from the remote partition and waiting for 342 * the remote partition to pull ours. 343 */ 344static enum xpc_retval 345xpc_make_first_contact(struct xpc_partition *part) 346{ 347 enum xpc_retval ret; 348 349 350 while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) { 351 if (ret != xpcRetry) { 352 XPC_DEACTIVATE_PARTITION(part, ret); 353 return ret; 354 } 355 356 dev_dbg(xpc_chan, "waiting to make first contact with " 357 "partition %d\n", XPC_PARTID(part)); 358 359 /* wait a 1/4 of a second or so */ 360 (void) msleep_interruptible(250); 361 362 if (part->act_state == XPC_P_DEACTIVATING) { 363 return part->reason; 364 } 365 } 366 367 return xpc_mark_partition_active(part); 368} 369 370 371/* 372 * The first kthread assigned to a newly activated partition is the one 373 * created by XPC HB with which it calls xpc_partition_up(). XPC hangs on to 374 * that kthread until the partition is brought down, at which time that kthread 375 * returns back to XPC HB. (The return of that kthread will signify to XPC HB 376 * that XPC has dismantled all communication infrastructure for the associated 377 * partition.) This kthread becomes the channel manager for that partition. 378 * 379 * Each active partition has a channel manager, who, besides connecting and 380 * disconnecting channels, will ensure that each of the partition's connected 381 * channels has the required number of assigned kthreads to get the work done. 382 */ 383static void 384xpc_channel_mgr(struct xpc_partition *part) 385{ 386 while (part->act_state != XPC_P_DEACTIVATING || 387 atomic_read(&part->nchannels_active) > 0 || 388 !xpc_partition_disengaged(part)) { 389 390 xpc_process_channel_activity(part); 391 392 393 /* 394 * Wait until we've been requested to activate kthreads or 395 * all of the channel's message queues have been torn down or 396 * a signal is pending. 397 * 398 * The channel_mgr_requests is set to 1 after being awakened, 399 * This is done to prevent the channel mgr from making one pass 400 * through the loop for each request, since he will 401 * be servicing all the requests in one pass. The reason it's 402 * set to 1 instead of 0 is so that other kthreads will know 403 * that the channel mgr is running and won't bother trying to 404 * wake him up. 405 */ 406 atomic_dec(&part->channel_mgr_requests); 407 (void) wait_event_interruptible(part->channel_mgr_wq, 408 (atomic_read(&part->channel_mgr_requests) > 0 || 409 (volatile u64) part->local_IPI_amo != 0 || 410 ((volatile u8) part->act_state == 411 XPC_P_DEACTIVATING && 412 atomic_read(&part->nchannels_active) == 0 && 413 xpc_partition_disengaged(part)))); 414 atomic_set(&part->channel_mgr_requests, 1); 415 416 // >>> Does it need to wakeup periodically as well? In case we 417 // >>> miscalculated the #of kthreads to wakeup or create? 418 } 419} 420 421 422/* 423 * When XPC HB determines that a partition has come up, it will create a new 424 * kthread and that kthread will call this function to attempt to set up the 425 * basic infrastructure used for Cross Partition Communication with the newly 426 * upped partition. 427 * 428 * The kthread that was created by XPC HB and which setup the XPC 429 * infrastructure will remain assigned to the partition until the partition 430 * goes down. At which time the kthread will teardown the XPC infrastructure 431 * and then exit. 432 * 433 * XPC HB will put the remote partition's XPC per partition specific variables 434 * physical address into xpc_partitions[partid].remote_vars_part_pa prior to 435 * calling xpc_partition_up(). 436 */ 437static void 438xpc_partition_up(struct xpc_partition *part) 439{ 440 DBUG_ON(part->channels != NULL); 441 442 dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part)); 443 444 if (xpc_setup_infrastructure(part) != xpcSuccess) { 445 return; 446 } 447 448 /* 449 * The kthread that XPC HB called us with will become the 450 * channel manager for this partition. It will not return 451 * back to XPC HB until the partition's XPC infrastructure 452 * has been dismantled. 453 */ 454 455 (void) xpc_part_ref(part); /* this will always succeed */ 456 457 if (xpc_make_first_contact(part) == xpcSuccess) { 458 xpc_channel_mgr(part); 459 } 460 461 xpc_part_deref(part); 462 463 xpc_teardown_infrastructure(part); 464} 465 466 467static int 468xpc_activating(void *__partid) 469{ 470 partid_t partid = (u64) __partid; 471 struct xpc_partition *part = &xpc_partitions[partid]; 472 unsigned long irq_flags; 473 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; 474 int ret; 475 476 477 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); 478 479 spin_lock_irqsave(&part->act_lock, irq_flags); 480 481 if (part->act_state == XPC_P_DEACTIVATING) { 482 part->act_state = XPC_P_INACTIVE; 483 spin_unlock_irqrestore(&part->act_lock, irq_flags); 484 part->remote_rp_pa = 0; 485 return 0; 486 } 487 488 /* indicate the thread is activating */ 489 DBUG_ON(part->act_state != XPC_P_ACTIVATION_REQ); 490 part->act_state = XPC_P_ACTIVATING; 491 492 XPC_SET_REASON(part, 0, 0); 493 spin_unlock_irqrestore(&part->act_lock, irq_flags); 494 495 dev_dbg(xpc_part, "bringing partition %d up\n", partid); 496 497 daemonize("xpc%02d", partid); 498 499 /* 500 * This thread needs to run at a realtime priority to prevent a 501 * significant performance degradation. 502 */ 503 ret = sched_setscheduler(current, SCHED_FIFO, ¶m); 504 if (ret != 0) { 505 dev_warn(xpc_part, "unable to set pid %d to a realtime " 506 "priority, ret=%d\n", current->pid, ret); 507 } 508 509 /* allow this thread and its children to run on any CPU */ 510 set_cpus_allowed(current, CPU_MASK_ALL); 511 512 /* 513 * Register the remote partition's AMOs with SAL so it can handle 514 * and cleanup errors within that address range should the remote 515 * partition go down. We don't unregister this range because it is 516 * difficult to tell when outstanding writes to the remote partition 517 * are finished and thus when it is safe to unregister. This should 518 * not result in wasted space in the SAL xp_addr_region table because 519 * we should get the same page for remote_amos_page_pa after module 520 * reloads and system reboots. 521 */ 522 if (sn_register_xp_addr_region(part->remote_amos_page_pa, 523 PAGE_SIZE, 1) < 0) { 524 dev_warn(xpc_part, "xpc_partition_up(%d) failed to register " 525 "xp_addr region\n", partid); 526 527 spin_lock_irqsave(&part->act_lock, irq_flags); 528 part->act_state = XPC_P_INACTIVE; 529 XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__); 530 spin_unlock_irqrestore(&part->act_lock, irq_flags); 531 part->remote_rp_pa = 0; 532 return 0; 533 } 534 535 xpc_allow_hb(partid, xpc_vars); 536 xpc_IPI_send_activated(part); 537 538 539 /* 540 * xpc_partition_up() holds this thread and marks this partition as 541 * XPC_P_ACTIVE by calling xpc_hb_mark_active(). 542 */ 543 (void) xpc_partition_up(part); 544 545 xpc_disallow_hb(partid, xpc_vars); 546 xpc_mark_partition_inactive(part); 547 548 if (part->reason == xpcReactivating) { 549 /* interrupting ourselves results in activating partition */ 550 xpc_IPI_send_reactivate(part); 551 } 552 553 return 0; 554} 555 556 557void 558xpc_activate_partition(struct xpc_partition *part) 559{ 560 partid_t partid = XPC_PARTID(part); 561 unsigned long irq_flags; 562 pid_t pid; 563 564 565 spin_lock_irqsave(&part->act_lock, irq_flags); 566 567 DBUG_ON(part->act_state != XPC_P_INACTIVE); 568 569 part->act_state = XPC_P_ACTIVATION_REQ; 570 XPC_SET_REASON(part, xpcCloneKThread, __LINE__); 571 572 spin_unlock_irqrestore(&part->act_lock, irq_flags); 573 574 pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0); 575 576 if (unlikely(pid <= 0)) { 577 spin_lock_irqsave(&part->act_lock, irq_flags); 578 part->act_state = XPC_P_INACTIVE; 579 XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__); 580 spin_unlock_irqrestore(&part->act_lock, irq_flags); 581 } 582} 583 584 585/* 586 * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified 587 * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more 588 * than one partition, we use an AMO_t structure per partition to indicate 589 * whether a partition has sent an IPI or not. >>> If it has, then wake up the 590 * associated kthread to handle it. 591 * 592 * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IPIs sent by XPC 593 * running on other partitions. 594 * 595 * Noteworthy Arguments: 596 * 597 * irq - Interrupt ReQuest number. NOT USED. 598 * 599 * dev_id - partid of IPI's potential sender. 600 */ 601irqreturn_t 602xpc_notify_IRQ_handler(int irq, void *dev_id) 603{ 604 partid_t partid = (partid_t) (u64) dev_id; 605 struct xpc_partition *part = &xpc_partitions[partid]; 606 607 608 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); 609 610 if (xpc_part_ref(part)) { 611 xpc_check_for_channel_activity(part); 612 613 xpc_part_deref(part); 614 } 615 return IRQ_HANDLED; 616} 617 618 619/* 620 * Check to see if xpc_notify_IRQ_handler() dropped any IPIs on the floor 621 * because the write to their associated IPI amo completed after the IRQ/IPI 622 * was received. 623 */ 624void 625xpc_dropped_IPI_check(struct xpc_partition *part) 626{ 627 if (xpc_part_ref(part)) { 628 xpc_check_for_channel_activity(part); 629 630 part->dropped_IPI_timer.expires = jiffies + 631 XPC_P_DROPPED_IPI_WAIT; 632 add_timer(&part->dropped_IPI_timer); 633 xpc_part_deref(part); 634 } 635} 636 637 638void 639xpc_activate_kthreads(struct xpc_channel *ch, int needed) 640{ 641 int idle = atomic_read(&ch->kthreads_idle); 642 int assigned = atomic_read(&ch->kthreads_assigned); 643 int wakeup; 644 645 646 DBUG_ON(needed <= 0); 647 648 if (idle > 0) { 649 wakeup = (needed > idle) ? idle : needed; 650 needed -= wakeup; 651 652 dev_dbg(xpc_chan, "wakeup %d idle kthreads, partid=%d, " 653 "channel=%d\n", wakeup, ch->partid, ch->number); 654 655 /* only wakeup the requested number of kthreads */ 656 wake_up_nr(&ch->idle_wq, wakeup); 657 } 658 659 if (needed <= 0) { 660 return; 661 } 662 663 if (needed + assigned > ch->kthreads_assigned_limit) { 664 needed = ch->kthreads_assigned_limit - assigned; 665 // >>>should never be less than 0 666 if (needed <= 0) { 667 return; 668 } 669 } 670 671 dev_dbg(xpc_chan, "create %d new kthreads, partid=%d, channel=%d\n", 672 needed, ch->partid, ch->number); 673 674 xpc_create_kthreads(ch, needed, 0); 675} 676 677 678/* 679 * This function is where XPC's kthreads wait for messages to deliver. 680 */ 681static void 682xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) 683{ 684 do { 685 /* deliver messages to their intended recipients */ 686 687 while ((volatile s64) ch->w_local_GP.get < 688 (volatile s64) ch->w_remote_GP.put && 689 !((volatile u32) ch->flags & 690 XPC_C_DISCONNECTING)) { 691 xpc_deliver_msg(ch); 692 } 693 694 if (atomic_inc_return(&ch->kthreads_idle) > 695 ch->kthreads_idle_limit) { 696 /* too many idle kthreads on this channel */ 697 atomic_dec(&ch->kthreads_idle); 698 break; 699 } 700 701 dev_dbg(xpc_chan, "idle kthread calling " 702 "wait_event_interruptible_exclusive()\n"); 703 704 (void) wait_event_interruptible_exclusive(ch->idle_wq, 705 ((volatile s64) ch->w_local_GP.get < 706 (volatile s64) ch->w_remote_GP.put || 707 ((volatile u32) ch->flags & 708 XPC_C_DISCONNECTING))); 709 710 atomic_dec(&ch->kthreads_idle); 711 712 } while (!((volatile u32) ch->flags & XPC_C_DISCONNECTING)); 713} 714 715 716static int 717xpc_daemonize_kthread(void *args) 718{ 719 partid_t partid = XPC_UNPACK_ARG1(args); 720 u16 ch_number = XPC_UNPACK_ARG2(args); 721 struct xpc_partition *part = &xpc_partitions[partid]; 722 struct xpc_channel *ch; 723 int n_needed; 724 unsigned long irq_flags; 725 726 727 daemonize("xpc%02dc%d", partid, ch_number); 728 729 dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n", 730 partid, ch_number); 731 732 ch = &part->channels[ch_number]; 733 734 if (!(ch->flags & XPC_C_DISCONNECTING)) { 735 736 /* let registerer know that connection has been established */ 737 738 spin_lock_irqsave(&ch->lock, irq_flags); 739 if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) { 740 ch->flags |= XPC_C_CONNECTEDCALLOUT; 741 spin_unlock_irqrestore(&ch->lock, irq_flags); 742 743 xpc_connected_callout(ch); 744 745 spin_lock_irqsave(&ch->lock, irq_flags); 746 ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE; 747 spin_unlock_irqrestore(&ch->lock, irq_flags); 748 749 /* 750 * It is possible that while the callout was being 751 * made that the remote partition sent some messages. 752 * If that is the case, we may need to activate 753 * additional kthreads to help deliver them. We only 754 * need one less than total #of messages to deliver. 755 */ 756 n_needed = ch->w_remote_GP.put - ch->w_local_GP.get - 1; 757 if (n_needed > 0 && 758 !(ch->flags & XPC_C_DISCONNECTING)) { 759 xpc_activate_kthreads(ch, n_needed); 760 } 761 } else { 762 spin_unlock_irqrestore(&ch->lock, irq_flags); 763 } 764 765 xpc_kthread_waitmsgs(part, ch); 766 } 767 768 /* let registerer know that connection is disconnecting */ 769 770 spin_lock_irqsave(&ch->lock, irq_flags); 771 if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) && 772 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) { 773 ch->flags |= XPC_C_DISCONNECTINGCALLOUT; 774 spin_unlock_irqrestore(&ch->lock, irq_flags); 775 776 xpc_disconnect_callout(ch, xpcDisconnecting); 777 778 spin_lock_irqsave(&ch->lock, irq_flags); 779 ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE; 780 } 781 spin_unlock_irqrestore(&ch->lock, irq_flags); 782 783 if (atomic_dec_return(&ch->kthreads_assigned) == 0) { 784 if (atomic_dec_return(&part->nchannels_engaged) == 0) { 785 xpc_mark_partition_disengaged(part); 786 xpc_IPI_send_disengage(part); 787 } 788 } 789 790 xpc_msgqueue_deref(ch); 791 792 dev_dbg(xpc_chan, "kthread exiting, partid=%d, channel=%d\n", 793 partid, ch_number); 794 795 xpc_part_deref(part); 796 return 0; 797} 798 799 800/* 801 * For each partition that XPC has established communications with, there is 802 * a minimum of one kernel thread assigned to perform any operation that 803 * may potentially sleep or block (basically the callouts to the asynchronous 804 * functions registered via xpc_connect()). 805 * 806 * Additional kthreads are created and destroyed by XPC as the workload 807 * demands. 808 * 809 * A kthread is assigned to one of the active channels that exists for a given 810 * partition. 811 */ 812void 813xpc_create_kthreads(struct xpc_channel *ch, int needed, 814 int ignore_disconnecting) 815{ 816 unsigned long irq_flags; 817 pid_t pid; 818 u64 args = XPC_PACK_ARGS(ch->partid, ch->number); 819 struct xpc_partition *part = &xpc_partitions[ch->partid]; 820 821 822 while (needed-- > 0) { 823 824 /* 825 * The following is done on behalf of the newly created 826 * kthread. That kthread is responsible for doing the 827 * counterpart to the following before it exits. 828 */ 829 if (ignore_disconnecting) { 830 if (!atomic_inc_not_zero(&ch->kthreads_assigned)) { 831 /* kthreads assigned had gone to zero */ 832 BUG_ON(!(ch->flags & 833 XPC_C_DISCONNECTINGCALLOUT_MADE)); 834 break; 835 } 836 837 } else if (ch->flags & XPC_C_DISCONNECTING) { 838 break; 839 840 } else if (atomic_inc_return(&ch->kthreads_assigned) == 1) { 841 if (atomic_inc_return(&part->nchannels_engaged) == 1) 842 xpc_mark_partition_engaged(part); 843 } 844 (void) xpc_part_ref(part); 845 xpc_msgqueue_ref(ch); 846 847 pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0); 848 if (pid < 0) { 849 /* the fork failed */ 850 851 /* 852 * NOTE: if (ignore_disconnecting && 853 * !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) is true, 854 * then we'll deadlock if all other kthreads assigned 855 * to this channel are blocked in the channel's 856 * registerer, because the only thing that will unblock 857 * them is the xpcDisconnecting callout that this 858 * failed kernel_thread would have made. 859 */ 860 861 if (atomic_dec_return(&ch->kthreads_assigned) == 0 && 862 atomic_dec_return(&part->nchannels_engaged) == 0) { 863 xpc_mark_partition_disengaged(part); 864 xpc_IPI_send_disengage(part); 865 } 866 xpc_msgqueue_deref(ch); 867 xpc_part_deref(part); 868 869 if (atomic_read(&ch->kthreads_assigned) < 870 ch->kthreads_idle_limit) { 871 /* 872 * Flag this as an error only if we have an 873 * insufficient #of kthreads for the channel 874 * to function. 875 */ 876 spin_lock_irqsave(&ch->lock, irq_flags); 877 XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources, 878 &irq_flags); 879 spin_unlock_irqrestore(&ch->lock, irq_flags); 880 } 881 break; 882 } 883 884 ch->kthreads_created++; // >>> temporary debug only!!! 885 } 886} 887 888 889void 890xpc_disconnect_wait(int ch_number) 891{ 892 unsigned long irq_flags; 893 partid_t partid; 894 struct xpc_partition *part; 895 struct xpc_channel *ch; 896 int wakeup_channel_mgr; 897 898 899 /* now wait for all callouts to the caller's function to cease */ 900 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { 901 part = &xpc_partitions[partid]; 902 903 if (!xpc_part_ref(part)) { 904 continue; 905 } 906 907 ch = &part->channels[ch_number]; 908 909 if (!(ch->flags & XPC_C_WDISCONNECT)) { 910 xpc_part_deref(part); 911 continue; 912 } 913 914 wait_for_completion(&ch->wdisconnect_wait); 915 916 spin_lock_irqsave(&ch->lock, irq_flags); 917 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); 918 wakeup_channel_mgr = 0; 919 920 if (ch->delayed_IPI_flags) { 921 if (part->act_state != XPC_P_DEACTIVATING) { 922 spin_lock(&part->IPI_lock); 923 XPC_SET_IPI_FLAGS(part->local_IPI_amo, 924 ch->number, ch->delayed_IPI_flags); 925 spin_unlock(&part->IPI_lock); 926 wakeup_channel_mgr = 1; 927 } 928 ch->delayed_IPI_flags = 0; 929 } 930 931 ch->flags &= ~XPC_C_WDISCONNECT; 932 spin_unlock_irqrestore(&ch->lock, irq_flags); 933 934 if (wakeup_channel_mgr) { 935 xpc_wakeup_channel_mgr(part); 936 } 937 938 xpc_part_deref(part); 939 } 940} 941 942 943static void 944xpc_do_exit(enum xpc_retval reason) 945{ 946 partid_t partid; 947 int active_part_count, printed_waiting_msg = 0; 948 struct xpc_partition *part; 949 unsigned long printmsg_time, disengage_request_timeout = 0; 950 951 952 /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ 953 DBUG_ON(xpc_exiting == 1); 954 955 /* 956 * Let the heartbeat checker thread and the discovery thread 957 * (if one is running) know that they should exit. Also wake up 958 * the heartbeat checker thread in case it's sleeping. 959 */ 960 xpc_exiting = 1; 961 wake_up_interruptible(&xpc_act_IRQ_wq); 962 963 /* ignore all incoming interrupts */ 964 free_irq(SGI_XPC_ACTIVATE, NULL); 965 966 /* wait for the discovery thread to exit */ 967 wait_for_completion(&xpc_discovery_exited); 968 969 /* wait for the heartbeat checker thread to exit */ 970 wait_for_completion(&xpc_hb_checker_exited); 971 972 973 /* sleep for a 1/3 of a second or so */ 974 (void) msleep_interruptible(300); 975 976 977 /* wait for all partitions to become inactive */ 978 979 printmsg_time = jiffies + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); 980 xpc_disengage_request_timedout = 0; 981 982 do { 983 active_part_count = 0; 984 985 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { 986 part = &xpc_partitions[partid]; 987 988 if (xpc_partition_disengaged(part) && 989 part->act_state == XPC_P_INACTIVE) { 990 continue; 991 } 992 993 active_part_count++; 994 995 XPC_DEACTIVATE_PARTITION(part, reason); 996 997 if (part->disengage_request_timeout > 998 disengage_request_timeout) { 999 disengage_request_timeout = 1000 part->disengage_request_timeout; 1001 } 1002 } 1003 1004 if (xpc_partition_engaged(-1UL)) { 1005 if (time_after(jiffies, printmsg_time)) { 1006 dev_info(xpc_part, "waiting for remote " 1007 "partitions to disengage, timeout in " 1008 "%ld seconds\n", 1009 (disengage_request_timeout - jiffies) 1010 / HZ); 1011 printmsg_time = jiffies + 1012 (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); 1013 printed_waiting_msg = 1; 1014 } 1015 1016 } else if (active_part_count > 0) { 1017 if (printed_waiting_msg) { 1018 dev_info(xpc_part, "waiting for local partition" 1019 " to disengage\n"); 1020 printed_waiting_msg = 0; 1021 } 1022 1023 } else { 1024 if (!xpc_disengage_request_timedout) { 1025 dev_info(xpc_part, "all partitions have " 1026 "disengaged\n"); 1027 } 1028 break; 1029 } 1030 1031 /* sleep for a 1/3 of a second or so */ 1032 (void) msleep_interruptible(300); 1033 1034 } while (1); 1035 1036 DBUG_ON(xpc_partition_engaged(-1UL)); 1037 1038 1039 /* indicate to others that our reserved page is uninitialized */ 1040 xpc_rsvd_page->vars_pa = 0; 1041 1042 /* now it's time to eliminate our heartbeat */ 1043 del_timer_sync(&xpc_hb_timer); 1044 DBUG_ON(xpc_vars->heartbeating_to_mask != 0); 1045 1046 if (reason == xpcUnloading) { 1047 /* take ourselves off of the reboot_notifier_list */ 1048 (void) unregister_reboot_notifier(&xpc_reboot_notifier); 1049 1050 /* take ourselves off of the die_notifier list */ 1051 (void) unregister_die_notifier(&xpc_die_notifier); 1052 } 1053 1054 /* close down protections for IPI operations */ 1055 xpc_restrict_IPI_ops(); 1056 1057 1058 /* clear the interface to XPC's functions */ 1059 xpc_clear_interface(); 1060 1061 if (xpc_sysctl) { 1062 unregister_sysctl_table(xpc_sysctl); 1063 } 1064 1065 kfree(xpc_remote_copy_buffer_base); 1066} 1067 1068 1069/* 1070 * This function is called when the system is being rebooted. 1071 */ 1072static int 1073xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) 1074{ 1075 enum xpc_retval reason; 1076 1077 1078 switch (event) { 1079 case SYS_RESTART: 1080 reason = xpcSystemReboot; 1081 break; 1082 case SYS_HALT: 1083 reason = xpcSystemHalt; 1084 break; 1085 case SYS_POWER_OFF: 1086 reason = xpcSystemPoweroff; 1087 break; 1088 default: 1089 reason = xpcSystemGoingDown; 1090 } 1091 1092 xpc_do_exit(reason); 1093 return NOTIFY_DONE; 1094} 1095 1096 1097/* 1098 * Notify other partitions to disengage from all references to our memory. 1099 */ 1100static void 1101xpc_die_disengage(void) 1102{ 1103 struct xpc_partition *part; 1104 partid_t partid; 1105 unsigned long engaged; 1106 long time, printmsg_time, disengage_request_timeout; 1107 1108 1109 /* keep xpc_hb_checker thread from doing anything (just in case) */ 1110 xpc_exiting = 1; 1111 1112 xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */ 1113 1114 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { 1115 part = &xpc_partitions[partid]; 1116 1117 if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part-> 1118 remote_vars_version)) { 1119 1120 /* just in case it was left set by an earlier XPC */ 1121 xpc_clear_partition_engaged(1UL << partid); 1122 continue; 1123 } 1124 1125 if (xpc_partition_engaged(1UL << partid) || 1126 part->act_state != XPC_P_INACTIVE) { 1127 xpc_request_partition_disengage(part); 1128 xpc_mark_partition_disengaged(part); 1129 xpc_IPI_send_disengage(part); 1130 } 1131 } 1132 1133 time = rtc_time(); 1134 printmsg_time = time + 1135 (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second); 1136 disengage_request_timeout = time + 1137 (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); 1138 1139 /* wait for all other partitions to disengage from us */ 1140 1141 while (1) { 1142 engaged = xpc_partition_engaged(-1UL); 1143 if (!engaged) { 1144 dev_info(xpc_part, "all partitions have disengaged\n"); 1145 break; 1146 } 1147 1148 time = rtc_time(); 1149 if (time >= disengage_request_timeout) { 1150 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { 1151 if (engaged & (1UL << partid)) { 1152 dev_info(xpc_part, "disengage from " 1153 "remote partition %d timed " 1154 "out\n", partid); 1155 } 1156 } 1157 break; 1158 } 1159 1160 if (time >= printmsg_time) { 1161 dev_info(xpc_part, "waiting for remote partitions to " 1162 "disengage, timeout in %ld seconds\n", 1163 (disengage_request_timeout - time) / 1164 sn_rtc_cycles_per_second); 1165 printmsg_time = time + 1166 (XPC_DISENGAGE_PRINTMSG_INTERVAL * 1167 sn_rtc_cycles_per_second); 1168 } 1169 } 1170} 1171 1172 1173/* 1174 * This function is called when the system is being restarted or halted due 1175 * to some sort of system failure. If this is the case we need to notify the 1176 * other partitions to disengage from all references to our memory. 1177 * This function can also be called when our heartbeater could be offlined 1178 * for a time. In this case we need to notify other partitions to not worry 1179 * about the lack of a heartbeat. 1180 */ 1181static int 1182xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) 1183{ 1184 switch (event) { 1185 case DIE_MACHINE_RESTART: 1186 case DIE_MACHINE_HALT: 1187 xpc_die_disengage(); 1188 break; 1189 1190 case DIE_KDEBUG_ENTER: 1191 /* Should lack of heartbeat be ignored by other partitions? */ 1192 if (!xpc_kdebug_ignore) { 1193 break; 1194 } 1195 /* fall through */ 1196 case DIE_MCA_MONARCH_ENTER: 1197 case DIE_INIT_MONARCH_ENTER: 1198 xpc_vars->heartbeat++; 1199 xpc_vars->heartbeat_offline = 1; 1200 break; 1201 1202 case DIE_KDEBUG_LEAVE: 1203 /* Is lack of heartbeat being ignored by other partitions? */ 1204 if (!xpc_kdebug_ignore) { 1205 break; 1206 } 1207 /* fall through */ 1208 case DIE_MCA_MONARCH_LEAVE: 1209 case DIE_INIT_MONARCH_LEAVE: 1210 xpc_vars->heartbeat++; 1211 xpc_vars->heartbeat_offline = 0; 1212 break; 1213 } 1214 1215 return NOTIFY_DONE; 1216} 1217 1218 1219int __init 1220xpc_init(void) 1221{ 1222 int ret; 1223 partid_t partid; 1224 struct xpc_partition *part; 1225 pid_t pid; 1226 size_t buf_size; 1227 1228 1229 if (!ia64_platform_is("sn2")) { 1230 return -ENODEV; 1231 } 1232 1233 1234 buf_size = max(XPC_RP_VARS_SIZE, 1235 XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES); 1236 xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size, 1237 GFP_KERNEL, &xpc_remote_copy_buffer_base); 1238 if (xpc_remote_copy_buffer == NULL) 1239 return -ENOMEM; 1240 1241 snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); 1242 snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); 1243 1244 xpc_sysctl = register_sysctl_table(xpc_sys_dir); 1245 1246 /* 1247 * The first few fields of each entry of xpc_partitions[] need to 1248 * be initialized now so that calls to xpc_connect() and 1249 * xpc_disconnect() can be made prior to the activation of any remote 1250 * partition. NOTE THAT NONE OF THE OTHER FIELDS BELONGING TO THESE 1251 * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING 1252 * PARTITION HAS BEEN ACTIVATED. 1253 */ 1254 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { 1255 part = &xpc_partitions[partid]; 1256 1257 DBUG_ON((u64) part != L1_CACHE_ALIGN((u64) part)); 1258 1259 part->act_IRQ_rcvd = 0; 1260 spin_lock_init(&part->act_lock); 1261 part->act_state = XPC_P_INACTIVE; 1262 XPC_SET_REASON(part, 0, 0); 1263 1264 init_timer(&part->disengage_request_timer); 1265 part->disengage_request_timer.function = 1266 xpc_timeout_partition_disengage_request; 1267 part->disengage_request_timer.data = (unsigned long) part; 1268 1269 part->setup_state = XPC_P_UNSET; 1270 init_waitqueue_head(&part->teardown_wq); 1271 atomic_set(&part->references, 0); 1272 } 1273 1274 /* 1275 * Open up protections for IPI operations (and AMO operations on 1276 * Shub 1.1 systems). 1277 */ 1278 xpc_allow_IPI_ops(); 1279 1280 /* 1281 * Interrupts being processed will increment this atomic variable and 1282 * awaken the heartbeat thread which will process the interrupts. 1283 */ 1284 atomic_set(&xpc_act_IRQ_rcvd, 0); 1285 1286 /* 1287 * This is safe to do before the xpc_hb_checker thread has started 1288 * because the handler releases a wait queue. If an interrupt is 1289 * received before the thread is waiting, it will not go to sleep, 1290 * but rather immediately process the interrupt. 1291 */ 1292 ret = request_irq(SGI_XPC_ACTIVATE, xpc_act_IRQ_handler, 0, 1293 "xpc hb", NULL); 1294 if (ret != 0) { 1295 dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " 1296 "errno=%d\n", -ret); 1297 1298 xpc_restrict_IPI_ops(); 1299 1300 if (xpc_sysctl) { 1301 unregister_sysctl_table(xpc_sysctl); 1302 } 1303 1304 kfree(xpc_remote_copy_buffer_base); 1305 return -EBUSY; 1306 } 1307 1308 /* 1309 * Fill the partition reserved page with the information needed by 1310 * other partitions to discover we are alive and establish initial 1311 * communications. 1312 */ 1313 xpc_rsvd_page = xpc_rsvd_page_init(); 1314 if (xpc_rsvd_page == NULL) { 1315 dev_err(xpc_part, "could not setup our reserved page\n"); 1316 1317 free_irq(SGI_XPC_ACTIVATE, NULL); 1318 xpc_restrict_IPI_ops(); 1319 1320 if (xpc_sysctl) { 1321 unregister_sysctl_table(xpc_sysctl); 1322 } 1323 1324 kfree(xpc_remote_copy_buffer_base); 1325 return -EBUSY; 1326 } 1327 1328 1329 /* add ourselves to the reboot_notifier_list */ 1330 ret = register_reboot_notifier(&xpc_reboot_notifier); 1331 if (ret != 0) { 1332 dev_warn(xpc_part, "can't register reboot notifier\n"); 1333 } 1334 1335 /* add ourselves to the die_notifier list */ 1336 ret = register_die_notifier(&xpc_die_notifier); 1337 if (ret != 0) { 1338 dev_warn(xpc_part, "can't register die notifier\n"); 1339 } 1340 1341 1342 /* 1343 * Set the beating to other partitions into motion. This is 1344 * the last requirement for other partitions' discovery to 1345 * initiate communications with us. 1346 */ 1347 init_timer(&xpc_hb_timer); 1348 xpc_hb_timer.function = xpc_hb_beater; 1349 xpc_hb_beater(0); 1350 1351 1352 /* 1353 * The real work-horse behind xpc. This processes incoming 1354 * interrupts and monitors remote heartbeats. 1355 */ 1356 pid = kernel_thread(xpc_hb_checker, NULL, 0); 1357 if (pid < 0) { 1358 dev_err(xpc_part, "failed while forking hb check thread\n"); 1359 1360 /* indicate to others that our reserved page is uninitialized */ 1361 xpc_rsvd_page->vars_pa = 0; 1362 1363 /* take ourselves off of the reboot_notifier_list */ 1364 (void) unregister_reboot_notifier(&xpc_reboot_notifier); 1365 1366 /* take ourselves off of the die_notifier list */ 1367 (void) unregister_die_notifier(&xpc_die_notifier); 1368 1369 del_timer_sync(&xpc_hb_timer); 1370 free_irq(SGI_XPC_ACTIVATE, NULL); 1371 xpc_restrict_IPI_ops(); 1372 1373 if (xpc_sysctl) { 1374 unregister_sysctl_table(xpc_sysctl); 1375 } 1376 1377 kfree(xpc_remote_copy_buffer_base); 1378 return -EBUSY; 1379 } 1380 1381 1382 /* 1383 * Startup a thread that will attempt to discover other partitions to 1384 * activate based on info provided by SAL. This new thread is short 1385 * lived and will exit once discovery is complete. 1386 */ 1387 pid = kernel_thread(xpc_initiate_discovery, NULL, 0); 1388 if (pid < 0) { 1389 dev_err(xpc_part, "failed while forking discovery thread\n"); 1390 1391 /* mark this new thread as a non-starter */ 1392 complete(&xpc_discovery_exited); 1393 1394 xpc_do_exit(xpcUnloading); 1395 return -EBUSY; 1396 } 1397 1398 1399 /* set the interface to point at XPC's functions */ 1400 xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect, 1401 xpc_initiate_allocate, xpc_initiate_send, 1402 xpc_initiate_send_notify, xpc_initiate_received, 1403 xpc_initiate_partid_to_nasids); 1404 1405 return 0; 1406} 1407module_init(xpc_init); 1408 1409 1410void __exit 1411xpc_exit(void) 1412{ 1413 xpc_do_exit(xpcUnloading); 1414} 1415module_exit(xpc_exit); 1416 1417 1418MODULE_AUTHOR("Silicon Graphics, Inc."); 1419MODULE_DESCRIPTION("Cross Partition Communication (XPC) support"); 1420MODULE_LICENSE("GPL"); 1421 1422module_param(xpc_hb_interval, int, 0); 1423MODULE_PARM_DESC(xpc_hb_interval, "Number of seconds between " 1424 "heartbeat increments."); 1425 1426module_param(xpc_hb_check_interval, int, 0); 1427MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between " 1428 "heartbeat checks."); 1429 1430module_param(xpc_disengage_request_timelimit, int, 0); 1431MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait " 1432 "for disengage request to complete."); 1433 1434module_param(xpc_kdebug_ignore, int, 0); 1435MODULE_PARM_DESC(xpc_kdebug_ignore, "Should lack of heartbeat be ignored by " 1436 "other partitions when dropping into kdebug."); 1437