0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/kernel.h>
0017 #include <linux/mm.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/delay.h>
0020 #include <linux/device.h>
0021 #include <linux/cpu.h>
0022 #include <linux/module.h>
0023 #include <linux/err.h>
0024 #include <linux/slab.h>
0025 #include <linux/numa.h>
0026 #include <asm/uv/uv_hub.h>
0027 #if defined CONFIG_X86_64
0028 #include <asm/uv/bios.h>
0029 #include <asm/uv/uv_irq.h>
0030 #elif defined CONFIG_IA64_SGI_UV
0031 #include <asm/sn/intr.h>
0032 #include <asm/sn/sn_sal.h>
0033 #endif
0034 #include "../sgi-gru/gru.h"
0035 #include "../sgi-gru/grukservices.h"
0036 #include "xpc.h"
0037
0038 #if defined CONFIG_IA64_SGI_UV
0039 struct uv_IO_APIC_route_entry {
0040 __u64 vector : 8,
0041 delivery_mode : 3,
0042 dest_mode : 1,
0043 delivery_status : 1,
0044 polarity : 1,
0045 __reserved_1 : 1,
0046 trigger : 1,
0047 mask : 1,
0048 __reserved_2 : 15,
0049 dest : 32;
0050 };
0051
0052 #define sn_partition_id 0
0053 #endif
0054
0055 static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
0056
0057 #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES)
0058 #define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
0059 XPC_ACTIVATE_MSG_SIZE_UV)
0060 #define XPC_ACTIVATE_IRQ_NAME "xpc_activate"
0061
0062 #define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES)
0063 #define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
0064 XPC_NOTIFY_MSG_SIZE_UV)
0065 #define XPC_NOTIFY_IRQ_NAME "xpc_notify"
0066
0067 static int xpc_mq_node = NUMA_NO_NODE;
0068
0069 static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
0070 static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
0071
0072 static int
0073 xpc_setup_partitions_uv(void)
0074 {
0075 short partid;
0076 struct xpc_partition_uv *part_uv;
0077
0078 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
0079 part_uv = &xpc_partitions[partid].sn.uv;
0080
0081 mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex);
0082 spin_lock_init(&part_uv->flags_lock);
0083 part_uv->remote_act_state = XPC_P_AS_INACTIVE;
0084 }
0085 return 0;
0086 }
0087
0088 static void
0089 xpc_teardown_partitions_uv(void)
0090 {
0091 short partid;
0092 struct xpc_partition_uv *part_uv;
0093 unsigned long irq_flags;
0094
0095 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
0096 part_uv = &xpc_partitions[partid].sn.uv;
0097
0098 if (part_uv->cached_activate_gru_mq_desc != NULL) {
0099 mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
0100 spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
0101 part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
0102 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
0103 kfree(part_uv->cached_activate_gru_mq_desc);
0104 part_uv->cached_activate_gru_mq_desc = NULL;
0105 mutex_unlock(&part_uv->
0106 cached_activate_gru_mq_desc_mutex);
0107 }
0108 }
0109 }
0110
0111 static int
0112 xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
0113 {
0114 int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
0115
0116 #if defined CONFIG_X86_64
0117 mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
0118 UV_AFFINITY_CPU);
0119 if (mq->irq < 0)
0120 return mq->irq;
0121
0122 mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
0123
0124 #elif defined CONFIG_IA64_SGI_UV
0125 if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
0126 mq->irq = SGI_XPC_ACTIVATE;
0127 else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
0128 mq->irq = SGI_XPC_NOTIFY;
0129 else
0130 return -EINVAL;
0131
0132 mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
0133 uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value);
0134 #else
0135 #error not a supported configuration
0136 #endif
0137
0138 return 0;
0139 }
0140
0141 static void
0142 xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
0143 {
0144 #if defined CONFIG_X86_64
0145 uv_teardown_irq(mq->irq);
0146
0147 #elif defined CONFIG_IA64_SGI_UV
0148 int mmr_pnode;
0149 unsigned long mmr_value;
0150
0151 mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
0152 mmr_value = 1UL << 16;
0153
0154 uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
0155 #else
0156 #error not a supported configuration
0157 #endif
0158 }
0159
0160 static int
0161 xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
0162 {
0163 int ret;
0164
0165 #if defined CONFIG_IA64_SGI_UV
0166 int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
0167
0168 ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address),
0169 mq->order, &mq->mmr_offset);
0170 if (ret < 0) {
0171 dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
0172 ret);
0173 return -EBUSY;
0174 }
0175 #elif defined CONFIG_X86_64
0176 ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address),
0177 mq->order, &mq->mmr_offset);
0178 if (ret < 0) {
0179 dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
0180 "ret=%d\n", ret);
0181 return ret;
0182 }
0183 #else
0184 #error not a supported configuration
0185 #endif
0186
0187 mq->watchlist_num = ret;
0188 return 0;
0189 }
0190
0191 static void
0192 xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
0193 {
0194 int ret;
0195 int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
0196
0197 #if defined CONFIG_X86_64
0198 ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
0199 BUG_ON(ret != BIOS_STATUS_SUCCESS);
0200 #elif defined CONFIG_IA64_SGI_UV
0201 ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
0202 BUG_ON(ret != SALRET_OK);
0203 #else
0204 #error not a supported configuration
0205 #endif
0206 }
0207
0208 static struct xpc_gru_mq_uv *
0209 xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
0210 irq_handler_t irq_handler)
0211 {
0212 enum xp_retval xp_ret;
0213 int ret;
0214 int nid;
0215 int nasid;
0216 int pg_order;
0217 struct page *page;
0218 struct xpc_gru_mq_uv *mq;
0219 struct uv_IO_APIC_route_entry *mmr_value;
0220
0221 mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL);
0222 if (mq == NULL) {
0223 dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
0224 "a xpc_gru_mq_uv structure\n");
0225 ret = -ENOMEM;
0226 goto out_0;
0227 }
0228
0229 mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc),
0230 GFP_KERNEL);
0231 if (mq->gru_mq_desc == NULL) {
0232 dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
0233 "a gru_message_queue_desc structure\n");
0234 ret = -ENOMEM;
0235 goto out_1;
0236 }
0237
0238 pg_order = get_order(mq_size);
0239 mq->order = pg_order + PAGE_SHIFT;
0240 mq_size = 1UL << mq->order;
0241
0242 mq->mmr_blade = uv_cpu_to_blade_id(cpu);
0243
0244 nid = cpu_to_node(cpu);
0245 page = __alloc_pages_node(nid,
0246 GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
0247 pg_order);
0248 if (page == NULL) {
0249 dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
0250 "bytes of memory on nid=%d for GRU mq\n", mq_size, nid);
0251 ret = -ENOMEM;
0252 goto out_2;
0253 }
0254 mq->address = page_address(page);
0255
0256
0257 ret = xpc_gru_mq_watchlist_alloc_uv(mq);
0258 if (ret != 0)
0259 goto out_3;
0260
0261 ret = xpc_get_gru_mq_irq_uv(mq, cpu, irq_name);
0262 if (ret != 0)
0263 goto out_4;
0264
0265 ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL);
0266 if (ret != 0) {
0267 dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n",
0268 mq->irq, -ret);
0269 goto out_5;
0270 }
0271
0272 nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu));
0273
0274 mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value;
0275 ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size,
0276 nasid, mmr_value->vector, mmr_value->dest);
0277 if (ret != 0) {
0278 dev_err(xpc_part, "gru_create_message_queue() returned "
0279 "error=%d\n", ret);
0280 ret = -EINVAL;
0281 goto out_6;
0282 }
0283
0284
0285 xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size);
0286 if (xp_ret != xpSuccess) {
0287 ret = -EACCES;
0288 goto out_6;
0289 }
0290
0291 return mq;
0292
0293
0294 out_6:
0295 free_irq(mq->irq, NULL);
0296 out_5:
0297 xpc_release_gru_mq_irq_uv(mq);
0298 out_4:
0299 xpc_gru_mq_watchlist_free_uv(mq);
0300 out_3:
0301 free_pages((unsigned long)mq->address, pg_order);
0302 out_2:
0303 kfree(mq->gru_mq_desc);
0304 out_1:
0305 kfree(mq);
0306 out_0:
0307 return ERR_PTR(ret);
0308 }
0309
0310 static void
0311 xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq)
0312 {
0313 unsigned int mq_size;
0314 int pg_order;
0315 int ret;
0316
0317
0318 mq_size = 1UL << mq->order;
0319 ret = xp_restrict_memprotect(xp_pa(mq->address), mq_size);
0320 BUG_ON(ret != xpSuccess);
0321
0322
0323 free_irq(mq->irq, NULL);
0324 xpc_release_gru_mq_irq_uv(mq);
0325
0326
0327 xpc_gru_mq_watchlist_free_uv(mq);
0328
0329 pg_order = mq->order - PAGE_SHIFT;
0330 free_pages((unsigned long)mq->address, pg_order);
0331
0332 kfree(mq);
0333 }
0334
0335 static enum xp_retval
0336 xpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg,
0337 size_t msg_size)
0338 {
0339 enum xp_retval xp_ret;
0340 int ret;
0341
0342 while (1) {
0343 ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size);
0344 if (ret == MQE_OK) {
0345 xp_ret = xpSuccess;
0346 break;
0347 }
0348
0349 if (ret == MQE_QUEUE_FULL) {
0350 dev_dbg(xpc_chan, "gru_send_message_gpa() returned "
0351 "error=MQE_QUEUE_FULL\n");
0352
0353
0354 (void)msleep_interruptible(10);
0355 } else if (ret == MQE_CONGESTION) {
0356 dev_dbg(xpc_chan, "gru_send_message_gpa() returned "
0357 "error=MQE_CONGESTION\n");
0358
0359
0360 } else {
0361
0362 dev_err(xpc_chan, "gru_send_message_gpa() returned "
0363 "error=%d\n", ret);
0364 xp_ret = xpGruSendMqError;
0365 break;
0366 }
0367 }
0368 return xp_ret;
0369 }
0370
0371 static void
0372 xpc_process_activate_IRQ_rcvd_uv(void)
0373 {
0374 unsigned long irq_flags;
0375 short partid;
0376 struct xpc_partition *part;
0377 u8 act_state_req;
0378
0379 DBUG_ON(xpc_activate_IRQ_rcvd == 0);
0380
0381 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0382 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
0383 part = &xpc_partitions[partid];
0384
0385 if (part->sn.uv.act_state_req == 0)
0386 continue;
0387
0388 xpc_activate_IRQ_rcvd--;
0389 BUG_ON(xpc_activate_IRQ_rcvd < 0);
0390
0391 act_state_req = part->sn.uv.act_state_req;
0392 part->sn.uv.act_state_req = 0;
0393 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0394
0395 if (act_state_req == XPC_P_ASR_ACTIVATE_UV) {
0396 if (part->act_state == XPC_P_AS_INACTIVE)
0397 xpc_activate_partition(part);
0398 else if (part->act_state == XPC_P_AS_DEACTIVATING)
0399 XPC_DEACTIVATE_PARTITION(part, xpReactivating);
0400
0401 } else if (act_state_req == XPC_P_ASR_REACTIVATE_UV) {
0402 if (part->act_state == XPC_P_AS_INACTIVE)
0403 xpc_activate_partition(part);
0404 else
0405 XPC_DEACTIVATE_PARTITION(part, xpReactivating);
0406
0407 } else if (act_state_req == XPC_P_ASR_DEACTIVATE_UV) {
0408 XPC_DEACTIVATE_PARTITION(part, part->sn.uv.reason);
0409
0410 } else {
0411 BUG();
0412 }
0413
0414 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0415 if (xpc_activate_IRQ_rcvd == 0)
0416 break;
0417 }
0418 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0419
0420 }
0421
0422 static void
0423 xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
0424 struct xpc_activate_mq_msghdr_uv *msg_hdr,
0425 int part_setup,
0426 int *wakeup_hb_checker)
0427 {
0428 unsigned long irq_flags;
0429 struct xpc_partition_uv *part_uv = &part->sn.uv;
0430 struct xpc_openclose_args *args;
0431
0432 part_uv->remote_act_state = msg_hdr->act_state;
0433
0434 switch (msg_hdr->type) {
0435 case XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV:
0436
0437 break;
0438
0439 case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: {
0440 struct xpc_activate_mq_msg_activate_req_uv *msg;
0441
0442
0443
0444
0445
0446
0447 msg = container_of(msg_hdr, struct
0448 xpc_activate_mq_msg_activate_req_uv, hdr);
0449
0450 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0451 if (part_uv->act_state_req == 0)
0452 xpc_activate_IRQ_rcvd++;
0453 part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV;
0454 part->remote_rp_pa = msg->rp_gpa;
0455 part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies;
0456 part_uv->heartbeat_gpa = msg->heartbeat_gpa;
0457
0458 if (msg->activate_gru_mq_desc_gpa !=
0459 part_uv->activate_gru_mq_desc_gpa) {
0460 spin_lock(&part_uv->flags_lock);
0461 part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
0462 spin_unlock(&part_uv->flags_lock);
0463 part_uv->activate_gru_mq_desc_gpa =
0464 msg->activate_gru_mq_desc_gpa;
0465 }
0466 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0467
0468 (*wakeup_hb_checker)++;
0469 break;
0470 }
0471 case XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV: {
0472 struct xpc_activate_mq_msg_deactivate_req_uv *msg;
0473
0474 msg = container_of(msg_hdr, struct
0475 xpc_activate_mq_msg_deactivate_req_uv, hdr);
0476
0477 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0478 if (part_uv->act_state_req == 0)
0479 xpc_activate_IRQ_rcvd++;
0480 part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV;
0481 part_uv->reason = msg->reason;
0482 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0483
0484 (*wakeup_hb_checker)++;
0485 return;
0486 }
0487 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: {
0488 struct xpc_activate_mq_msg_chctl_closerequest_uv *msg;
0489
0490 if (!part_setup)
0491 break;
0492
0493 msg = container_of(msg_hdr, struct
0494 xpc_activate_mq_msg_chctl_closerequest_uv,
0495 hdr);
0496 args = &part->remote_openclose_args[msg->ch_number];
0497 args->reason = msg->reason;
0498
0499 spin_lock_irqsave(&part->chctl_lock, irq_flags);
0500 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREQUEST;
0501 spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
0502
0503 xpc_wakeup_channel_mgr(part);
0504 break;
0505 }
0506 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: {
0507 struct xpc_activate_mq_msg_chctl_closereply_uv *msg;
0508
0509 if (!part_setup)
0510 break;
0511
0512 msg = container_of(msg_hdr, struct
0513 xpc_activate_mq_msg_chctl_closereply_uv,
0514 hdr);
0515
0516 spin_lock_irqsave(&part->chctl_lock, irq_flags);
0517 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREPLY;
0518 spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
0519
0520 xpc_wakeup_channel_mgr(part);
0521 break;
0522 }
0523 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: {
0524 struct xpc_activate_mq_msg_chctl_openrequest_uv *msg;
0525
0526 if (!part_setup)
0527 break;
0528
0529 msg = container_of(msg_hdr, struct
0530 xpc_activate_mq_msg_chctl_openrequest_uv,
0531 hdr);
0532 args = &part->remote_openclose_args[msg->ch_number];
0533 args->entry_size = msg->entry_size;
0534 args->local_nentries = msg->local_nentries;
0535
0536 spin_lock_irqsave(&part->chctl_lock, irq_flags);
0537 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREQUEST;
0538 spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
0539
0540 xpc_wakeup_channel_mgr(part);
0541 break;
0542 }
0543 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: {
0544 struct xpc_activate_mq_msg_chctl_openreply_uv *msg;
0545
0546 if (!part_setup)
0547 break;
0548
0549 msg = container_of(msg_hdr, struct
0550 xpc_activate_mq_msg_chctl_openreply_uv, hdr);
0551 args = &part->remote_openclose_args[msg->ch_number];
0552 args->remote_nentries = msg->remote_nentries;
0553 args->local_nentries = msg->local_nentries;
0554 args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa;
0555
0556 spin_lock_irqsave(&part->chctl_lock, irq_flags);
0557 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY;
0558 spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
0559
0560 xpc_wakeup_channel_mgr(part);
0561 break;
0562 }
0563 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: {
0564 struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg;
0565
0566 if (!part_setup)
0567 break;
0568
0569 msg = container_of(msg_hdr, struct
0570 xpc_activate_mq_msg_chctl_opencomplete_uv, hdr);
0571 spin_lock_irqsave(&part->chctl_lock, irq_flags);
0572 part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE;
0573 spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
0574
0575 xpc_wakeup_channel_mgr(part);
0576 }
0577 fallthrough;
0578 case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV:
0579 spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
0580 part_uv->flags |= XPC_P_ENGAGED_UV;
0581 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
0582 break;
0583
0584 case XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV:
0585 spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
0586 part_uv->flags &= ~XPC_P_ENGAGED_UV;
0587 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
0588 break;
0589
0590 default:
0591 dev_err(xpc_part, "received unknown activate_mq msg type=%d "
0592 "from partition=%d\n", msg_hdr->type, XPC_PARTID(part));
0593
0594
0595 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0596 if (part_uv->act_state_req == 0)
0597 xpc_activate_IRQ_rcvd++;
0598 part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV;
0599 part_uv->reason = xpBadMsgType;
0600 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0601
0602 (*wakeup_hb_checker)++;
0603 return;
0604 }
0605
0606 if (msg_hdr->rp_ts_jiffies != part->remote_rp_ts_jiffies &&
0607 part->remote_rp_ts_jiffies != 0) {
0608
0609
0610
0611
0612 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0613 if (part_uv->act_state_req == 0)
0614 xpc_activate_IRQ_rcvd++;
0615 part_uv->act_state_req = XPC_P_ASR_REACTIVATE_UV;
0616 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0617
0618 (*wakeup_hb_checker)++;
0619 }
0620 }
0621
0622 static irqreturn_t
0623 xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
0624 {
0625 struct xpc_activate_mq_msghdr_uv *msg_hdr;
0626 short partid;
0627 struct xpc_partition *part;
0628 int wakeup_hb_checker = 0;
0629 int part_referenced;
0630
0631 while (1) {
0632 msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc);
0633 if (msg_hdr == NULL)
0634 break;
0635
0636 partid = msg_hdr->partid;
0637 if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
0638 dev_err(xpc_part, "xpc_handle_activate_IRQ_uv() "
0639 "received invalid partid=0x%x in message\n",
0640 partid);
0641 } else {
0642 part = &xpc_partitions[partid];
0643
0644 part_referenced = xpc_part_ref(part);
0645 xpc_handle_activate_mq_msg_uv(part, msg_hdr,
0646 part_referenced,
0647 &wakeup_hb_checker);
0648 if (part_referenced)
0649 xpc_part_deref(part);
0650 }
0651
0652 gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr);
0653 }
0654
0655 if (wakeup_hb_checker)
0656 wake_up_interruptible(&xpc_activate_IRQ_wq);
0657
0658 return IRQ_HANDLED;
0659 }
0660
0661 static enum xp_retval
0662 xpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc,
0663 unsigned long gru_mq_desc_gpa)
0664 {
0665 enum xp_retval ret;
0666
0667 ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa,
0668 sizeof(struct gru_message_queue_desc));
0669 if (ret == xpSuccess)
0670 gru_mq_desc->mq = NULL;
0671
0672 return ret;
0673 }
0674
0675 static enum xp_retval
0676 xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size,
0677 int msg_type)
0678 {
0679 struct xpc_activate_mq_msghdr_uv *msg_hdr = msg;
0680 struct xpc_partition_uv *part_uv = &part->sn.uv;
0681 struct gru_message_queue_desc *gru_mq_desc;
0682 unsigned long irq_flags;
0683 enum xp_retval ret;
0684
0685 DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV);
0686
0687 msg_hdr->type = msg_type;
0688 msg_hdr->partid = xp_partition_id;
0689 msg_hdr->act_state = part->act_state;
0690 msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies;
0691
0692 mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
0693 again:
0694 if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) {
0695 gru_mq_desc = part_uv->cached_activate_gru_mq_desc;
0696 if (gru_mq_desc == NULL) {
0697 gru_mq_desc = kmalloc(sizeof(struct
0698 gru_message_queue_desc),
0699 GFP_ATOMIC);
0700 if (gru_mq_desc == NULL) {
0701 ret = xpNoMemory;
0702 goto done;
0703 }
0704 part_uv->cached_activate_gru_mq_desc = gru_mq_desc;
0705 }
0706
0707 ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc,
0708 part_uv->
0709 activate_gru_mq_desc_gpa);
0710 if (ret != xpSuccess)
0711 goto done;
0712
0713 spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
0714 part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
0715 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
0716 }
0717
0718
0719 ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg,
0720 msg_size);
0721 if (ret != xpSuccess) {
0722 smp_rmb();
0723 if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV))
0724 goto again;
0725 }
0726 done:
0727 mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex);
0728 return ret;
0729 }
0730
0731 static void
0732 xpc_send_activate_IRQ_part_uv(struct xpc_partition *part, void *msg,
0733 size_t msg_size, int msg_type)
0734 {
0735 enum xp_retval ret;
0736
0737 ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type);
0738 if (unlikely(ret != xpSuccess))
0739 XPC_DEACTIVATE_PARTITION(part, ret);
0740 }
0741
0742 static void
0743 xpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags,
0744 void *msg, size_t msg_size, int msg_type)
0745 {
0746 struct xpc_partition *part = &xpc_partitions[ch->partid];
0747 enum xp_retval ret;
0748
0749 ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type);
0750 if (unlikely(ret != xpSuccess)) {
0751 if (irq_flags != NULL)
0752 spin_unlock_irqrestore(&ch->lock, *irq_flags);
0753
0754 XPC_DEACTIVATE_PARTITION(part, ret);
0755
0756 if (irq_flags != NULL)
0757 spin_lock_irqsave(&ch->lock, *irq_flags);
0758 }
0759 }
0760
0761 static void
0762 xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req)
0763 {
0764 unsigned long irq_flags;
0765 struct xpc_partition_uv *part_uv = &part->sn.uv;
0766
0767
0768
0769
0770
0771
0772
0773 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0774 if (part_uv->act_state_req == 0)
0775 xpc_activate_IRQ_rcvd++;
0776 part_uv->act_state_req = act_state_req;
0777 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
0778
0779 wake_up_interruptible(&xpc_activate_IRQ_wq);
0780 }
0781
0782 static enum xp_retval
0783 xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
0784 size_t *len)
0785 {
0786 s64 status;
0787 enum xp_retval ret;
0788
0789 #if defined CONFIG_X86_64
0790 status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa,
0791 (u64 *)len);
0792 if (status == BIOS_STATUS_SUCCESS)
0793 ret = xpSuccess;
0794 else if (status == BIOS_STATUS_MORE_PASSES)
0795 ret = xpNeedMoreInfo;
0796 else
0797 ret = xpBiosError;
0798
0799 #elif defined CONFIG_IA64_SGI_UV
0800 status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len);
0801 if (status == SALRET_OK)
0802 ret = xpSuccess;
0803 else if (status == SALRET_MORE_PASSES)
0804 ret = xpNeedMoreInfo;
0805 else
0806 ret = xpSalError;
0807
0808 #else
0809 #error not a supported configuration
0810 #endif
0811
0812 return ret;
0813 }
0814
0815 static int
0816 xpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp)
0817 {
0818 xpc_heartbeat_uv =
0819 &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat;
0820 rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv);
0821 rp->sn.uv.activate_gru_mq_desc_gpa =
0822 uv_gpa(xpc_activate_mq_uv->gru_mq_desc);
0823 return 0;
0824 }
0825
0826 static void
0827 xpc_allow_hb_uv(short partid)
0828 {
0829 }
0830
0831 static void
0832 xpc_disallow_hb_uv(short partid)
0833 {
0834 }
0835
0836 static void
0837 xpc_disallow_all_hbs_uv(void)
0838 {
0839 }
0840
0841 static void
0842 xpc_increment_heartbeat_uv(void)
0843 {
0844 xpc_heartbeat_uv->value++;
0845 }
0846
0847 static void
0848 xpc_offline_heartbeat_uv(void)
0849 {
0850 xpc_increment_heartbeat_uv();
0851 xpc_heartbeat_uv->offline = 1;
0852 }
0853
0854 static void
0855 xpc_online_heartbeat_uv(void)
0856 {
0857 xpc_increment_heartbeat_uv();
0858 xpc_heartbeat_uv->offline = 0;
0859 }
0860
0861 static void
0862 xpc_heartbeat_init_uv(void)
0863 {
0864 xpc_heartbeat_uv->value = 1;
0865 xpc_heartbeat_uv->offline = 0;
0866 }
0867
0868 static void
0869 xpc_heartbeat_exit_uv(void)
0870 {
0871 xpc_offline_heartbeat_uv();
0872 }
0873
0874 static enum xp_retval
0875 xpc_get_remote_heartbeat_uv(struct xpc_partition *part)
0876 {
0877 struct xpc_partition_uv *part_uv = &part->sn.uv;
0878 enum xp_retval ret;
0879
0880 ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat),
0881 part_uv->heartbeat_gpa,
0882 sizeof(struct xpc_heartbeat_uv));
0883 if (ret != xpSuccess)
0884 return ret;
0885
0886 if (part_uv->cached_heartbeat.value == part->last_heartbeat &&
0887 !part_uv->cached_heartbeat.offline) {
0888
0889 ret = xpNoHeartbeat;
0890 } else {
0891 part->last_heartbeat = part_uv->cached_heartbeat.value;
0892 }
0893 return ret;
0894 }
0895
0896 static void
0897 xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
0898 unsigned long remote_rp_gpa, int nasid)
0899 {
0900 short partid = remote_rp->SAL_partid;
0901 struct xpc_partition *part = &xpc_partitions[partid];
0902 struct xpc_activate_mq_msg_activate_req_uv msg;
0903
0904 part->remote_rp_pa = remote_rp_gpa;
0905 part->remote_rp_ts_jiffies = remote_rp->ts_jiffies;
0906 part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa;
0907 part->sn.uv.activate_gru_mq_desc_gpa =
0908 remote_rp->sn.uv.activate_gru_mq_desc_gpa;
0909
0910
0911
0912
0913
0914 if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) {
0915 msg.rp_gpa = uv_gpa(xpc_rsvd_page);
0916 msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa;
0917 msg.activate_gru_mq_desc_gpa =
0918 xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa;
0919 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
0920 XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV);
0921 }
0922
0923 if (part->act_state == XPC_P_AS_INACTIVE)
0924 xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV);
0925 }
0926
0927 static void
0928 xpc_request_partition_reactivation_uv(struct xpc_partition *part)
0929 {
0930 xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV);
0931 }
0932
0933 static void
0934 xpc_request_partition_deactivation_uv(struct xpc_partition *part)
0935 {
0936 struct xpc_activate_mq_msg_deactivate_req_uv msg;
0937
0938
0939
0940
0941
0942 if (part->sn.uv.remote_act_state != XPC_P_AS_DEACTIVATING &&
0943 part->sn.uv.remote_act_state != XPC_P_AS_INACTIVE) {
0944
0945 msg.reason = part->reason;
0946 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
0947 XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV);
0948 }
0949 }
0950
0951 static void
0952 xpc_cancel_partition_deactivation_request_uv(struct xpc_partition *part)
0953 {
0954
0955 return;
0956 }
0957
0958 static void
0959 xpc_init_fifo_uv(struct xpc_fifo_head_uv *head)
0960 {
0961 head->first = NULL;
0962 head->last = NULL;
0963 spin_lock_init(&head->lock);
0964 head->n_entries = 0;
0965 }
0966
0967 static void *
0968 xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head)
0969 {
0970 unsigned long irq_flags;
0971 struct xpc_fifo_entry_uv *first;
0972
0973 spin_lock_irqsave(&head->lock, irq_flags);
0974 first = head->first;
0975 if (head->first != NULL) {
0976 head->first = first->next;
0977 if (head->first == NULL)
0978 head->last = NULL;
0979
0980 head->n_entries--;
0981 BUG_ON(head->n_entries < 0);
0982
0983 first->next = NULL;
0984 }
0985 spin_unlock_irqrestore(&head->lock, irq_flags);
0986 return first;
0987 }
0988
0989 static void
0990 xpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head,
0991 struct xpc_fifo_entry_uv *last)
0992 {
0993 unsigned long irq_flags;
0994
0995 last->next = NULL;
0996 spin_lock_irqsave(&head->lock, irq_flags);
0997 if (head->last != NULL)
0998 head->last->next = last;
0999 else
1000 head->first = last;
1001 head->last = last;
1002 head->n_entries++;
1003 spin_unlock_irqrestore(&head->lock, irq_flags);
1004 }
1005
1006 static int
1007 xpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head)
1008 {
1009 return head->n_entries;
1010 }
1011
1012
1013
1014
1015 static enum xp_retval
1016 xpc_setup_ch_structures_uv(struct xpc_partition *part)
1017 {
1018 struct xpc_channel_uv *ch_uv;
1019 int ch_number;
1020
1021 for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
1022 ch_uv = &part->channels[ch_number].sn.uv;
1023
1024 xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
1025 xpc_init_fifo_uv(&ch_uv->recv_msg_list);
1026 }
1027
1028 return xpSuccess;
1029 }
1030
1031
1032
1033
1034 static void
1035 xpc_teardown_ch_structures_uv(struct xpc_partition *part)
1036 {
1037
1038 return;
1039 }
1040
1041 static enum xp_retval
1042 xpc_make_first_contact_uv(struct xpc_partition *part)
1043 {
1044 struct xpc_activate_mq_msg_uv msg;
1045
1046
1047
1048
1049
1050
1051 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
1052 XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV);
1053
1054 while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) ||
1055 (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) {
1056
1057 dev_dbg(xpc_part, "waiting to make first contact with "
1058 "partition %d\n", XPC_PARTID(part));
1059
1060
1061 (void)msleep_interruptible(250);
1062
1063 if (part->act_state == XPC_P_AS_DEACTIVATING)
1064 return part->reason;
1065 }
1066
1067 return xpSuccess;
1068 }
1069
1070 static u64
1071 xpc_get_chctl_all_flags_uv(struct xpc_partition *part)
1072 {
1073 unsigned long irq_flags;
1074 union xpc_channel_ctl_flags chctl;
1075
1076 spin_lock_irqsave(&part->chctl_lock, irq_flags);
1077 chctl = part->chctl;
1078 if (chctl.all_flags != 0)
1079 part->chctl.all_flags = 0;
1080
1081 spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
1082 return chctl.all_flags;
1083 }
1084
1085 static enum xp_retval
1086 xpc_allocate_send_msg_slot_uv(struct xpc_channel *ch)
1087 {
1088 struct xpc_channel_uv *ch_uv = &ch->sn.uv;
1089 struct xpc_send_msg_slot_uv *msg_slot;
1090 unsigned long irq_flags;
1091 int nentries;
1092 int entry;
1093 size_t nbytes;
1094
1095 for (nentries = ch->local_nentries; nentries > 0; nentries--) {
1096 nbytes = nentries * sizeof(struct xpc_send_msg_slot_uv);
1097 ch_uv->send_msg_slots = kzalloc(nbytes, GFP_KERNEL);
1098 if (ch_uv->send_msg_slots == NULL)
1099 continue;
1100
1101 for (entry = 0; entry < nentries; entry++) {
1102 msg_slot = &ch_uv->send_msg_slots[entry];
1103
1104 msg_slot->msg_slot_number = entry;
1105 xpc_put_fifo_entry_uv(&ch_uv->msg_slot_free_list,
1106 &msg_slot->next);
1107 }
1108
1109 spin_lock_irqsave(&ch->lock, irq_flags);
1110 if (nentries < ch->local_nentries)
1111 ch->local_nentries = nentries;
1112 spin_unlock_irqrestore(&ch->lock, irq_flags);
1113 return xpSuccess;
1114 }
1115
1116 return xpNoMemory;
1117 }
1118
1119 static enum xp_retval
1120 xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch)
1121 {
1122 struct xpc_channel_uv *ch_uv = &ch->sn.uv;
1123 struct xpc_notify_mq_msg_uv *msg_slot;
1124 unsigned long irq_flags;
1125 int nentries;
1126 int entry;
1127 size_t nbytes;
1128
1129 for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
1130 nbytes = nentries * ch->entry_size;
1131 ch_uv->recv_msg_slots = kzalloc(nbytes, GFP_KERNEL);
1132 if (ch_uv->recv_msg_slots == NULL)
1133 continue;
1134
1135 for (entry = 0; entry < nentries; entry++) {
1136 msg_slot = ch_uv->recv_msg_slots +
1137 entry * ch->entry_size;
1138
1139 msg_slot->hdr.msg_slot_number = entry;
1140 }
1141
1142 spin_lock_irqsave(&ch->lock, irq_flags);
1143 if (nentries < ch->remote_nentries)
1144 ch->remote_nentries = nentries;
1145 spin_unlock_irqrestore(&ch->lock, irq_flags);
1146 return xpSuccess;
1147 }
1148
1149 return xpNoMemory;
1150 }
1151
1152
1153
1154
1155 static enum xp_retval
1156 xpc_setup_msg_structures_uv(struct xpc_channel *ch)
1157 {
1158 static enum xp_retval ret;
1159 struct xpc_channel_uv *ch_uv = &ch->sn.uv;
1160
1161 DBUG_ON(ch->flags & XPC_C_SETUP);
1162
1163 ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct
1164 gru_message_queue_desc),
1165 GFP_KERNEL);
1166 if (ch_uv->cached_notify_gru_mq_desc == NULL)
1167 return xpNoMemory;
1168
1169 ret = xpc_allocate_send_msg_slot_uv(ch);
1170 if (ret == xpSuccess) {
1171
1172 ret = xpc_allocate_recv_msg_slot_uv(ch);
1173 if (ret != xpSuccess) {
1174 kfree(ch_uv->send_msg_slots);
1175 xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
1176 }
1177 }
1178 return ret;
1179 }
1180
1181
1182
1183
1184
1185 static void
1186 xpc_teardown_msg_structures_uv(struct xpc_channel *ch)
1187 {
1188 struct xpc_channel_uv *ch_uv = &ch->sn.uv;
1189
1190 lockdep_assert_held(&ch->lock);
1191
1192 kfree(ch_uv->cached_notify_gru_mq_desc);
1193 ch_uv->cached_notify_gru_mq_desc = NULL;
1194
1195 if (ch->flags & XPC_C_SETUP) {
1196 xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
1197 kfree(ch_uv->send_msg_slots);
1198 xpc_init_fifo_uv(&ch_uv->recv_msg_list);
1199 kfree(ch_uv->recv_msg_slots);
1200 }
1201 }
1202
1203 static void
1204 xpc_send_chctl_closerequest_uv(struct xpc_channel *ch, unsigned long *irq_flags)
1205 {
1206 struct xpc_activate_mq_msg_chctl_closerequest_uv msg;
1207
1208 msg.ch_number = ch->number;
1209 msg.reason = ch->reason;
1210 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
1211 XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV);
1212 }
1213
1214 static void
1215 xpc_send_chctl_closereply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
1216 {
1217 struct xpc_activate_mq_msg_chctl_closereply_uv msg;
1218
1219 msg.ch_number = ch->number;
1220 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
1221 XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV);
1222 }
1223
1224 static void
1225 xpc_send_chctl_openrequest_uv(struct xpc_channel *ch, unsigned long *irq_flags)
1226 {
1227 struct xpc_activate_mq_msg_chctl_openrequest_uv msg;
1228
1229 msg.ch_number = ch->number;
1230 msg.entry_size = ch->entry_size;
1231 msg.local_nentries = ch->local_nentries;
1232 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
1233 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV);
1234 }
1235
1236 static void
1237 xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
1238 {
1239 struct xpc_activate_mq_msg_chctl_openreply_uv msg;
1240
1241 msg.ch_number = ch->number;
1242 msg.local_nentries = ch->local_nentries;
1243 msg.remote_nentries = ch->remote_nentries;
1244 msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc);
1245 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
1246 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV);
1247 }
1248
1249 static void
1250 xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags)
1251 {
1252 struct xpc_activate_mq_msg_chctl_opencomplete_uv msg;
1253
1254 msg.ch_number = ch->number;
1255 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
1256 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV);
1257 }
1258
1259 static void
1260 xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number)
1261 {
1262 unsigned long irq_flags;
1263
1264 spin_lock_irqsave(&part->chctl_lock, irq_flags);
1265 part->chctl.flags[ch_number] |= XPC_CHCTL_MSGREQUEST;
1266 spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
1267
1268 xpc_wakeup_channel_mgr(part);
1269 }
1270
1271 static enum xp_retval
1272 xpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch,
1273 unsigned long gru_mq_desc_gpa)
1274 {
1275 struct xpc_channel_uv *ch_uv = &ch->sn.uv;
1276
1277 DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL);
1278 return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc,
1279 gru_mq_desc_gpa);
1280 }
1281
1282 static void
1283 xpc_indicate_partition_engaged_uv(struct xpc_partition *part)
1284 {
1285 struct xpc_activate_mq_msg_uv msg;
1286
1287 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
1288 XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV);
1289 }
1290
1291 static void
1292 xpc_indicate_partition_disengaged_uv(struct xpc_partition *part)
1293 {
1294 struct xpc_activate_mq_msg_uv msg;
1295
1296 xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
1297 XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV);
1298 }
1299
1300 static void
1301 xpc_assume_partition_disengaged_uv(short partid)
1302 {
1303 struct xpc_partition_uv *part_uv = &xpc_partitions[partid].sn.uv;
1304 unsigned long irq_flags;
1305
1306 spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
1307 part_uv->flags &= ~XPC_P_ENGAGED_UV;
1308 spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
1309 }
1310
1311 static int
1312 xpc_partition_engaged_uv(short partid)
1313 {
1314 return (xpc_partitions[partid].sn.uv.flags & XPC_P_ENGAGED_UV) != 0;
1315 }
1316
1317 static int
1318 xpc_any_partition_engaged_uv(void)
1319 {
1320 struct xpc_partition_uv *part_uv;
1321 short partid;
1322
1323 for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
1324 part_uv = &xpc_partitions[partid].sn.uv;
1325 if ((part_uv->flags & XPC_P_ENGAGED_UV) != 0)
1326 return 1;
1327 }
1328 return 0;
1329 }
1330
1331 static enum xp_retval
1332 xpc_allocate_msg_slot_uv(struct xpc_channel *ch, u32 flags,
1333 struct xpc_send_msg_slot_uv **address_of_msg_slot)
1334 {
1335 enum xp_retval ret;
1336 struct xpc_send_msg_slot_uv *msg_slot;
1337 struct xpc_fifo_entry_uv *entry;
1338
1339 while (1) {
1340 entry = xpc_get_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list);
1341 if (entry != NULL)
1342 break;
1343
1344 if (flags & XPC_NOWAIT)
1345 return xpNoWait;
1346
1347 ret = xpc_allocate_msg_wait(ch);
1348 if (ret != xpInterrupted && ret != xpTimeout)
1349 return ret;
1350 }
1351
1352 msg_slot = container_of(entry, struct xpc_send_msg_slot_uv, next);
1353 *address_of_msg_slot = msg_slot;
1354 return xpSuccess;
1355 }
1356
1357 static void
1358 xpc_free_msg_slot_uv(struct xpc_channel *ch,
1359 struct xpc_send_msg_slot_uv *msg_slot)
1360 {
1361 xpc_put_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list, &msg_slot->next);
1362
1363
1364 if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
1365 wake_up(&ch->msg_allocate_wq);
1366 }
1367
1368 static void
1369 xpc_notify_sender_uv(struct xpc_channel *ch,
1370 struct xpc_send_msg_slot_uv *msg_slot,
1371 enum xp_retval reason)
1372 {
1373 xpc_notify_func func = msg_slot->func;
1374
1375 if (func != NULL && cmpxchg(&msg_slot->func, func, NULL) == func) {
1376
1377 atomic_dec(&ch->n_to_notify);
1378
1379 dev_dbg(xpc_chan, "msg_slot->func() called, msg_slot=0x%p "
1380 "msg_slot_number=%d partid=%d channel=%d\n", msg_slot,
1381 msg_slot->msg_slot_number, ch->partid, ch->number);
1382
1383 func(reason, ch->partid, ch->number, msg_slot->key);
1384
1385 dev_dbg(xpc_chan, "msg_slot->func() returned, msg_slot=0x%p "
1386 "msg_slot_number=%d partid=%d channel=%d\n", msg_slot,
1387 msg_slot->msg_slot_number, ch->partid, ch->number);
1388 }
1389 }
1390
1391 static void
1392 xpc_handle_notify_mq_ack_uv(struct xpc_channel *ch,
1393 struct xpc_notify_mq_msg_uv *msg)
1394 {
1395 struct xpc_send_msg_slot_uv *msg_slot;
1396 int entry = msg->hdr.msg_slot_number % ch->local_nentries;
1397
1398 msg_slot = &ch->sn.uv.send_msg_slots[entry];
1399
1400 BUG_ON(msg_slot->msg_slot_number != msg->hdr.msg_slot_number);
1401 msg_slot->msg_slot_number += ch->local_nentries;
1402
1403 if (msg_slot->func != NULL)
1404 xpc_notify_sender_uv(ch, msg_slot, xpMsgDelivered);
1405
1406 xpc_free_msg_slot_uv(ch, msg_slot);
1407 }
1408
1409 static void
1410 xpc_handle_notify_mq_msg_uv(struct xpc_partition *part,
1411 struct xpc_notify_mq_msg_uv *msg)
1412 {
1413 struct xpc_partition_uv *part_uv = &part->sn.uv;
1414 struct xpc_channel *ch;
1415 struct xpc_channel_uv *ch_uv;
1416 struct xpc_notify_mq_msg_uv *msg_slot;
1417 unsigned long irq_flags;
1418 int ch_number = msg->hdr.ch_number;
1419
1420 if (unlikely(ch_number >= part->nchannels)) {
1421 dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received invalid "
1422 "channel number=0x%x in message from partid=%d\n",
1423 ch_number, XPC_PARTID(part));
1424
1425
1426 spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
1427 if (part_uv->act_state_req == 0)
1428 xpc_activate_IRQ_rcvd++;
1429 part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV;
1430 part_uv->reason = xpBadChannelNumber;
1431 spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
1432
1433 wake_up_interruptible(&xpc_activate_IRQ_wq);
1434 return;
1435 }
1436
1437 ch = &part->channels[ch_number];
1438 xpc_msgqueue_ref(ch);
1439
1440 if (!(ch->flags & XPC_C_CONNECTED)) {
1441 xpc_msgqueue_deref(ch);
1442 return;
1443 }
1444
1445
1446 if (msg->hdr.size == 0) {
1447 xpc_handle_notify_mq_ack_uv(ch, msg);
1448 xpc_msgqueue_deref(ch);
1449 return;
1450 }
1451
1452
1453 ch_uv = &ch->sn.uv;
1454
1455 msg_slot = ch_uv->recv_msg_slots +
1456 (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
1457
1458 BUG_ON(msg_slot->hdr.size != 0);
1459
1460 memcpy(msg_slot, msg, msg->hdr.size);
1461
1462 xpc_put_fifo_entry_uv(&ch_uv->recv_msg_list, &msg_slot->hdr.u.next);
1463
1464 if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) {
1465
1466
1467
1468
1469
1470 if (atomic_read(&ch->kthreads_idle) > 0)
1471 wake_up_nr(&ch->idle_wq, 1);
1472 else
1473 xpc_send_chctl_local_msgrequest_uv(part, ch->number);
1474 }
1475 xpc_msgqueue_deref(ch);
1476 }
1477
1478 static irqreturn_t
1479 xpc_handle_notify_IRQ_uv(int irq, void *dev_id)
1480 {
1481 struct xpc_notify_mq_msg_uv *msg;
1482 short partid;
1483 struct xpc_partition *part;
1484
1485 while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) !=
1486 NULL) {
1487
1488 partid = msg->hdr.partid;
1489 if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
1490 dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received "
1491 "invalid partid=0x%x in message\n", partid);
1492 } else {
1493 part = &xpc_partitions[partid];
1494
1495 if (xpc_part_ref(part)) {
1496 xpc_handle_notify_mq_msg_uv(part, msg);
1497 xpc_part_deref(part);
1498 }
1499 }
1500
1501 gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg);
1502 }
1503
1504 return IRQ_HANDLED;
1505 }
1506
1507 static int
1508 xpc_n_of_deliverable_payloads_uv(struct xpc_channel *ch)
1509 {
1510 return xpc_n_of_fifo_entries_uv(&ch->sn.uv.recv_msg_list);
1511 }
1512
1513 static void
1514 xpc_process_msg_chctl_flags_uv(struct xpc_partition *part, int ch_number)
1515 {
1516 struct xpc_channel *ch = &part->channels[ch_number];
1517 int ndeliverable_payloads;
1518
1519 xpc_msgqueue_ref(ch);
1520
1521 ndeliverable_payloads = xpc_n_of_deliverable_payloads_uv(ch);
1522
1523 if (ndeliverable_payloads > 0 &&
1524 (ch->flags & XPC_C_CONNECTED) &&
1525 (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)) {
1526
1527 xpc_activate_kthreads(ch, ndeliverable_payloads);
1528 }
1529
1530 xpc_msgqueue_deref(ch);
1531 }
1532
1533 static enum xp_retval
1534 xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload,
1535 u16 payload_size, u8 notify_type, xpc_notify_func func,
1536 void *key)
1537 {
1538 enum xp_retval ret = xpSuccess;
1539 struct xpc_send_msg_slot_uv *msg_slot = NULL;
1540 struct xpc_notify_mq_msg_uv *msg;
1541 u8 msg_buffer[XPC_NOTIFY_MSG_SIZE_UV];
1542 size_t msg_size;
1543
1544 DBUG_ON(notify_type != XPC_N_CALL);
1545
1546 msg_size = sizeof(struct xpc_notify_mq_msghdr_uv) + payload_size;
1547 if (msg_size > ch->entry_size)
1548 return xpPayloadTooBig;
1549
1550 xpc_msgqueue_ref(ch);
1551
1552 if (ch->flags & XPC_C_DISCONNECTING) {
1553 ret = ch->reason;
1554 goto out_1;
1555 }
1556 if (!(ch->flags & XPC_C_CONNECTED)) {
1557 ret = xpNotConnected;
1558 goto out_1;
1559 }
1560
1561 ret = xpc_allocate_msg_slot_uv(ch, flags, &msg_slot);
1562 if (ret != xpSuccess)
1563 goto out_1;
1564
1565 if (func != NULL) {
1566 atomic_inc(&ch->n_to_notify);
1567
1568 msg_slot->key = key;
1569 smp_wmb();
1570 msg_slot->func = func;
1571
1572 if (ch->flags & XPC_C_DISCONNECTING) {
1573 ret = ch->reason;
1574 goto out_2;
1575 }
1576 }
1577
1578 msg = (struct xpc_notify_mq_msg_uv *)&msg_buffer;
1579 msg->hdr.partid = xp_partition_id;
1580 msg->hdr.ch_number = ch->number;
1581 msg->hdr.size = msg_size;
1582 msg->hdr.msg_slot_number = msg_slot->msg_slot_number;
1583 memcpy(&msg->payload, payload, payload_size);
1584
1585 ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
1586 msg_size);
1587 if (ret == xpSuccess)
1588 goto out_1;
1589
1590 XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
1591 out_2:
1592 if (func != NULL) {
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603 if (cmpxchg(&msg_slot->func, func, NULL) != func) {
1604 ret = xpSuccess;
1605 goto out_1;
1606 }
1607
1608 msg_slot->key = NULL;
1609 atomic_dec(&ch->n_to_notify);
1610 }
1611 xpc_free_msg_slot_uv(ch, msg_slot);
1612 out_1:
1613 xpc_msgqueue_deref(ch);
1614 return ret;
1615 }
1616
1617
1618
1619
1620
1621
1622
1623
1624 static void
1625 xpc_notify_senders_of_disconnect_uv(struct xpc_channel *ch)
1626 {
1627 struct xpc_send_msg_slot_uv *msg_slot;
1628 int entry;
1629
1630 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING));
1631
1632 for (entry = 0; entry < ch->local_nentries; entry++) {
1633
1634 if (atomic_read(&ch->n_to_notify) == 0)
1635 break;
1636
1637 msg_slot = &ch->sn.uv.send_msg_slots[entry];
1638 if (msg_slot->func != NULL)
1639 xpc_notify_sender_uv(ch, msg_slot, ch->reason);
1640 }
1641 }
1642
1643
1644
1645
1646 static void *
1647 xpc_get_deliverable_payload_uv(struct xpc_channel *ch)
1648 {
1649 struct xpc_fifo_entry_uv *entry;
1650 struct xpc_notify_mq_msg_uv *msg;
1651 void *payload = NULL;
1652
1653 if (!(ch->flags & XPC_C_DISCONNECTING)) {
1654 entry = xpc_get_fifo_entry_uv(&ch->sn.uv.recv_msg_list);
1655 if (entry != NULL) {
1656 msg = container_of(entry, struct xpc_notify_mq_msg_uv,
1657 hdr.u.next);
1658 payload = &msg->payload;
1659 }
1660 }
1661 return payload;
1662 }
1663
1664 static void
1665 xpc_received_payload_uv(struct xpc_channel *ch, void *payload)
1666 {
1667 struct xpc_notify_mq_msg_uv *msg;
1668 enum xp_retval ret;
1669
1670 msg = container_of(payload, struct xpc_notify_mq_msg_uv, payload);
1671
1672
1673
1674 msg->hdr.partid = xp_partition_id;
1675 msg->hdr.size = 0;
1676
1677 ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
1678 sizeof(struct xpc_notify_mq_msghdr_uv));
1679 if (ret != xpSuccess)
1680 XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
1681 }
1682
1683 static const struct xpc_arch_operations xpc_arch_ops_uv = {
1684 .setup_partitions = xpc_setup_partitions_uv,
1685 .teardown_partitions = xpc_teardown_partitions_uv,
1686 .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv,
1687 .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv,
1688 .setup_rsvd_page = xpc_setup_rsvd_page_uv,
1689
1690 .allow_hb = xpc_allow_hb_uv,
1691 .disallow_hb = xpc_disallow_hb_uv,
1692 .disallow_all_hbs = xpc_disallow_all_hbs_uv,
1693 .increment_heartbeat = xpc_increment_heartbeat_uv,
1694 .offline_heartbeat = xpc_offline_heartbeat_uv,
1695 .online_heartbeat = xpc_online_heartbeat_uv,
1696 .heartbeat_init = xpc_heartbeat_init_uv,
1697 .heartbeat_exit = xpc_heartbeat_exit_uv,
1698 .get_remote_heartbeat = xpc_get_remote_heartbeat_uv,
1699
1700 .request_partition_activation =
1701 xpc_request_partition_activation_uv,
1702 .request_partition_reactivation =
1703 xpc_request_partition_reactivation_uv,
1704 .request_partition_deactivation =
1705 xpc_request_partition_deactivation_uv,
1706 .cancel_partition_deactivation_request =
1707 xpc_cancel_partition_deactivation_request_uv,
1708
1709 .setup_ch_structures = xpc_setup_ch_structures_uv,
1710 .teardown_ch_structures = xpc_teardown_ch_structures_uv,
1711
1712 .make_first_contact = xpc_make_first_contact_uv,
1713
1714 .get_chctl_all_flags = xpc_get_chctl_all_flags_uv,
1715 .send_chctl_closerequest = xpc_send_chctl_closerequest_uv,
1716 .send_chctl_closereply = xpc_send_chctl_closereply_uv,
1717 .send_chctl_openrequest = xpc_send_chctl_openrequest_uv,
1718 .send_chctl_openreply = xpc_send_chctl_openreply_uv,
1719 .send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv,
1720 .process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv,
1721
1722 .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv,
1723
1724 .setup_msg_structures = xpc_setup_msg_structures_uv,
1725 .teardown_msg_structures = xpc_teardown_msg_structures_uv,
1726
1727 .indicate_partition_engaged = xpc_indicate_partition_engaged_uv,
1728 .indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv,
1729 .assume_partition_disengaged = xpc_assume_partition_disengaged_uv,
1730 .partition_engaged = xpc_partition_engaged_uv,
1731 .any_partition_engaged = xpc_any_partition_engaged_uv,
1732
1733 .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv,
1734 .send_payload = xpc_send_payload_uv,
1735 .get_deliverable_payload = xpc_get_deliverable_payload_uv,
1736 .received_payload = xpc_received_payload_uv,
1737 .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
1738 };
1739
1740 static int
1741 xpc_init_mq_node(int nid)
1742 {
1743 int cpu;
1744
1745 cpus_read_lock();
1746
1747 for_each_cpu(cpu, cpumask_of_node(nid)) {
1748 xpc_activate_mq_uv =
1749 xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid,
1750 XPC_ACTIVATE_IRQ_NAME,
1751 xpc_handle_activate_IRQ_uv);
1752 if (!IS_ERR(xpc_activate_mq_uv))
1753 break;
1754 }
1755 if (IS_ERR(xpc_activate_mq_uv)) {
1756 cpus_read_unlock();
1757 return PTR_ERR(xpc_activate_mq_uv);
1758 }
1759
1760 for_each_cpu(cpu, cpumask_of_node(nid)) {
1761 xpc_notify_mq_uv =
1762 xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid,
1763 XPC_NOTIFY_IRQ_NAME,
1764 xpc_handle_notify_IRQ_uv);
1765 if (!IS_ERR(xpc_notify_mq_uv))
1766 break;
1767 }
1768 if (IS_ERR(xpc_notify_mq_uv)) {
1769 xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
1770 cpus_read_unlock();
1771 return PTR_ERR(xpc_notify_mq_uv);
1772 }
1773
1774 cpus_read_unlock();
1775 return 0;
1776 }
1777
1778 int
1779 xpc_init_uv(void)
1780 {
1781 int nid;
1782 int ret = 0;
1783
1784 xpc_arch_ops = xpc_arch_ops_uv;
1785
1786 if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
1787 dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n",
1788 XPC_MSG_HDR_MAX_SIZE);
1789 return -E2BIG;
1790 }
1791
1792 if (xpc_mq_node < 0)
1793 for_each_online_node(nid) {
1794 ret = xpc_init_mq_node(nid);
1795
1796 if (!ret)
1797 break;
1798 }
1799 else
1800 ret = xpc_init_mq_node(xpc_mq_node);
1801
1802 if (ret < 0)
1803 dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n",
1804 -ret);
1805
1806 return ret;
1807 }
1808
1809 void
1810 xpc_exit_uv(void)
1811 {
1812 xpc_destroy_gru_mq_uv(xpc_notify_mq_uv);
1813 xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
1814 }
1815
1816 module_param(xpc_mq_node, int, 0);
1817 MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues.");