This source file includes following definitions.
- xpc_any_openclose_chctl_flags_set
- xpc_any_msg_chctl_flags_set
- xpc_wakeup_channel_mgr
- xpc_msgqueue_ref
- xpc_msgqueue_deref
- xpc_part_deref
- xpc_part_ref
1
2
3
4
5
6
7
8
9
10
11
12
13 #ifndef _DRIVERS_MISC_SGIXP_XPC_H
14 #define _DRIVERS_MISC_SGIXP_XPC_H
15
16 #include <linux/wait.h>
17 #include <linux/completion.h>
18 #include <linux/timer.h>
19 #include <linux/sched.h>
20 #include "xp.h"
21
22
23
24
25
26
27 #define _XPC_VERSION(_maj, _min) (((_maj) << 4) | ((_min) & 0xf))
28 #define XPC_VERSION_MAJOR(_v) ((_v) >> 4)
29 #define XPC_VERSION_MINOR(_v) ((_v) & 0xf)
30
31
32 #define XPC_HB_DEFAULT_INTERVAL 5
33 #define XPC_HB_CHECK_DEFAULT_INTERVAL 20
34
35
36 #define XPC_HB_CHECK_THREAD_NAME "xpc_hb"
37 #define XPC_HB_CHECK_CPU 0
38
39
40 #define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 struct xpc_rsvd_page {
83 u64 SAL_signature;
84 u64 SAL_version;
85 short SAL_partid;
86 short max_npartitions;
87 u8 version;
88 u8 pad1[3];
89 unsigned long ts_jiffies;
90 union {
91 struct {
92 unsigned long heartbeat_gpa;
93 unsigned long activate_gru_mq_desc_gpa;
94 } uv;
95 } sn;
96 u64 pad2[9];
97 u64 SAL_nasids_size;
98 };
99
100 #define XPC_RP_VERSION _XPC_VERSION(3, 0)
101
102
103
104 #define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
105
106 #define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
107 XPC_RP_HEADER_SIZE))
108 #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
109 xpc_nasid_mask_nlongs)
110
111
112
113
114
115
116
117 struct xpc_heartbeat_uv {
118 unsigned long value;
119 unsigned long offline;
120 };
121
122
123
124
125 struct xpc_gru_mq_uv {
126 void *address;
127 unsigned int order;
128 int irq;
129 int mmr_blade;
130 unsigned long mmr_offset;
131 unsigned long mmr_value;
132 int watchlist_num;
133 void *gru_mq_desc;
134 };
135
136
137
138
139
140 struct xpc_activate_mq_msghdr_uv {
141 unsigned int gru_msg_hdr;
142 short partid;
143 u8 act_state;
144 u8 type;
145 unsigned long rp_ts_jiffies;
146 };
147
148
149 #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0
150
151 #define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 1
152 #define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 2
153
154 #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 3
155 #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4
156 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5
157 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6
158 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV 7
159
160 #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 8
161 #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 9
162
163 struct xpc_activate_mq_msg_uv {
164 struct xpc_activate_mq_msghdr_uv hdr;
165 };
166
167 struct xpc_activate_mq_msg_activate_req_uv {
168 struct xpc_activate_mq_msghdr_uv hdr;
169 unsigned long rp_gpa;
170 unsigned long heartbeat_gpa;
171 unsigned long activate_gru_mq_desc_gpa;
172 };
173
174 struct xpc_activate_mq_msg_deactivate_req_uv {
175 struct xpc_activate_mq_msghdr_uv hdr;
176 enum xp_retval reason;
177 };
178
179 struct xpc_activate_mq_msg_chctl_closerequest_uv {
180 struct xpc_activate_mq_msghdr_uv hdr;
181 short ch_number;
182 enum xp_retval reason;
183 };
184
185 struct xpc_activate_mq_msg_chctl_closereply_uv {
186 struct xpc_activate_mq_msghdr_uv hdr;
187 short ch_number;
188 };
189
190 struct xpc_activate_mq_msg_chctl_openrequest_uv {
191 struct xpc_activate_mq_msghdr_uv hdr;
192 short ch_number;
193 short entry_size;
194 short local_nentries;
195 };
196
197 struct xpc_activate_mq_msg_chctl_openreply_uv {
198 struct xpc_activate_mq_msghdr_uv hdr;
199 short ch_number;
200 short remote_nentries;
201 short local_nentries;
202 unsigned long notify_gru_mq_desc_gpa;
203 };
204
205 struct xpc_activate_mq_msg_chctl_opencomplete_uv {
206 struct xpc_activate_mq_msghdr_uv hdr;
207 short ch_number;
208 };
209
210
211
212
213
214
215
216 #define XPC_PACK_ARGS(_arg1, _arg2) \
217 ((((u64)_arg1) & 0xffffffff) | \
218 ((((u64)_arg2) & 0xffffffff) << 32))
219
220 #define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
221 #define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
222
223
224
225
226
227 struct xpc_openclose_args {
228 u16 reason;
229 u16 entry_size;
230 u16 remote_nentries;
231 u16 local_nentries;
232 unsigned long local_msgqueue_pa;
233 };
234
235 #define XPC_OPENCLOSE_ARGS_SIZE \
236 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
237 XPC_MAX_NCHANNELS)
238
239
240
241
242
243
244 struct xpc_fifo_entry_uv {
245 struct xpc_fifo_entry_uv *next;
246 };
247
248 struct xpc_fifo_head_uv {
249 struct xpc_fifo_entry_uv *first;
250 struct xpc_fifo_entry_uv *last;
251 spinlock_t lock;
252 int n_entries;
253 };
254
255
256
257
258
259
260
261
262
263
264
265 struct xpc_notify_mq_msghdr_uv {
266 union {
267 unsigned int gru_msg_hdr;
268 struct xpc_fifo_entry_uv next;
269 } u;
270 short partid;
271 u8 ch_number;
272 u8 size;
273 unsigned int msg_slot_number;
274 };
275
276 struct xpc_notify_mq_msg_uv {
277 struct xpc_notify_mq_msghdr_uv hdr;
278 unsigned long payload;
279 };
280
281
282
283 #define XPC_N_CALL 0x01
284
285
286
287
288
289 struct xpc_send_msg_slot_uv {
290 struct xpc_fifo_entry_uv next;
291 unsigned int msg_slot_number;
292 xpc_notify_func func;
293 void *key;
294 };
295
296
297
298
299
300
301
302
303
304
305
306
307
308 struct xpc_channel_uv {
309 void *cached_notify_gru_mq_desc;
310
311
312 struct xpc_send_msg_slot_uv *send_msg_slots;
313 void *recv_msg_slots;
314
315
316 struct xpc_fifo_head_uv msg_slot_free_list;
317 struct xpc_fifo_head_uv recv_msg_list;
318 };
319
320 struct xpc_channel {
321 short partid;
322 spinlock_t lock;
323 unsigned int flags;
324
325 enum xp_retval reason;
326 int reason_line;
327
328 u16 number;
329
330 u16 entry_size;
331 u16 local_nentries;
332 u16 remote_nentries;
333
334 atomic_t references;
335
336 atomic_t n_on_msg_allocate_wq;
337 wait_queue_head_t msg_allocate_wq;
338
339 u8 delayed_chctl_flags;
340
341
342 atomic_t n_to_notify;
343
344 xpc_channel_func func;
345 void *key;
346
347 struct completion wdisconnect_wait;
348
349
350
351 atomic_t kthreads_assigned;
352 u32 kthreads_assigned_limit;
353 atomic_t kthreads_idle;
354 u32 kthreads_idle_limit;
355 atomic_t kthreads_active;
356
357 wait_queue_head_t idle_wq;
358
359 union {
360 struct xpc_channel_uv uv;
361 } sn;
362
363 } ____cacheline_aligned;
364
365
366
367 #define XPC_C_WASCONNECTED 0x00000001
368
369 #define XPC_C_ROPENCOMPLETE 0x00000002
370 #define XPC_C_OPENCOMPLETE 0x00000004
371 #define XPC_C_ROPENREPLY 0x00000008
372 #define XPC_C_OPENREPLY 0x00000010
373 #define XPC_C_ROPENREQUEST 0x00000020
374 #define XPC_C_OPENREQUEST 0x00000040
375
376 #define XPC_C_SETUP 0x00000080
377 #define XPC_C_CONNECTEDCALLOUT 0x00000100
378 #define XPC_C_CONNECTEDCALLOUT_MADE \
379 0x00000200
380 #define XPC_C_CONNECTED 0x00000400
381 #define XPC_C_CONNECTING 0x00000800
382
383 #define XPC_C_RCLOSEREPLY 0x00001000
384 #define XPC_C_CLOSEREPLY 0x00002000
385 #define XPC_C_RCLOSEREQUEST 0x00004000
386 #define XPC_C_CLOSEREQUEST 0x00008000
387
388 #define XPC_C_DISCONNECTED 0x00010000
389 #define XPC_C_DISCONNECTING 0x00020000
390 #define XPC_C_DISCONNECTINGCALLOUT \
391 0x00040000
392 #define XPC_C_DISCONNECTINGCALLOUT_MADE \
393 0x00080000
394 #define XPC_C_WDISCONNECT 0x00100000
395
396
397
398
399
400
401
402
403 union xpc_channel_ctl_flags {
404 u64 all_flags;
405 u8 flags[XPC_MAX_NCHANNELS];
406 };
407
408
409 #define XPC_CHCTL_CLOSEREQUEST 0x01
410 #define XPC_CHCTL_CLOSEREPLY 0x02
411 #define XPC_CHCTL_OPENREQUEST 0x04
412 #define XPC_CHCTL_OPENREPLY 0x08
413 #define XPC_CHCTL_OPENCOMPLETE 0x10
414 #define XPC_CHCTL_MSGREQUEST 0x20
415
416 #define XPC_OPENCLOSE_CHCTL_FLAGS \
417 (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
418 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
419 XPC_CHCTL_OPENCOMPLETE)
420 #define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST
421
422 static inline int
423 xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
424 {
425 int ch_number;
426
427 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
428 if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
429 return 1;
430 }
431 return 0;
432 }
433
434 static inline int
435 xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
436 {
437 int ch_number;
438
439 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
440 if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
441 return 1;
442 }
443 return 0;
444 }
445
446 struct xpc_partition_uv {
447 unsigned long heartbeat_gpa;
448 struct xpc_heartbeat_uv cached_heartbeat;
449
450 unsigned long activate_gru_mq_desc_gpa;
451
452
453 void *cached_activate_gru_mq_desc;
454
455 struct mutex cached_activate_gru_mq_desc_mutex;
456 spinlock_t flags_lock;
457 unsigned int flags;
458 u8 remote_act_state;
459 u8 act_state_req;
460 enum xp_retval reason;
461 };
462
463
464
465 #define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000001
466 #define XPC_P_ENGAGED_UV 0x00000002
467
468
469
470 #define XPC_P_ASR_ACTIVATE_UV 0x01
471 #define XPC_P_ASR_REACTIVATE_UV 0x02
472 #define XPC_P_ASR_DEACTIVATE_UV 0x03
473
474 struct xpc_partition {
475
476
477
478 u8 remote_rp_version;
479 unsigned long remote_rp_ts_jiffies;
480 unsigned long remote_rp_pa;
481 u64 last_heartbeat;
482 u32 activate_IRQ_rcvd;
483 spinlock_t act_lock;
484 u8 act_state;
485 enum xp_retval reason;
486 int reason_line;
487
488 unsigned long disengage_timeout;
489 struct timer_list disengage_timer;
490
491
492
493 u8 setup_state;
494 wait_queue_head_t teardown_wq;
495 atomic_t references;
496
497 u8 nchannels;
498 atomic_t nchannels_active;
499 atomic_t nchannels_engaged;
500 struct xpc_channel *channels;
501
502
503
504 union xpc_channel_ctl_flags chctl;
505 spinlock_t chctl_lock;
506
507 void *remote_openclose_args_base;
508 struct xpc_openclose_args *remote_openclose_args;
509
510
511
512
513 atomic_t channel_mgr_requests;
514 wait_queue_head_t channel_mgr_wq;
515
516 union {
517 struct xpc_partition_uv uv;
518 } sn;
519
520 } ____cacheline_aligned;
521
522 struct xpc_arch_operations {
523 int (*setup_partitions) (void);
524 void (*teardown_partitions) (void);
525 void (*process_activate_IRQ_rcvd) (void);
526 enum xp_retval (*get_partition_rsvd_page_pa)
527 (void *, u64 *, unsigned long *, size_t *);
528 int (*setup_rsvd_page) (struct xpc_rsvd_page *);
529
530 void (*allow_hb) (short);
531 void (*disallow_hb) (short);
532 void (*disallow_all_hbs) (void);
533 void (*increment_heartbeat) (void);
534 void (*offline_heartbeat) (void);
535 void (*online_heartbeat) (void);
536 void (*heartbeat_init) (void);
537 void (*heartbeat_exit) (void);
538 enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
539
540 void (*request_partition_activation) (struct xpc_rsvd_page *,
541 unsigned long, int);
542 void (*request_partition_reactivation) (struct xpc_partition *);
543 void (*request_partition_deactivation) (struct xpc_partition *);
544 void (*cancel_partition_deactivation_request) (struct xpc_partition *);
545 enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
546 void (*teardown_ch_structures) (struct xpc_partition *);
547
548 enum xp_retval (*make_first_contact) (struct xpc_partition *);
549
550 u64 (*get_chctl_all_flags) (struct xpc_partition *);
551 void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
552 void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
553 void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
554 void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
555 void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
556 void (*process_msg_chctl_flags) (struct xpc_partition *, int);
557
558 enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
559 unsigned long);
560
561 enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
562 void (*teardown_msg_structures) (struct xpc_channel *);
563
564 void (*indicate_partition_engaged) (struct xpc_partition *);
565 void (*indicate_partition_disengaged) (struct xpc_partition *);
566 void (*assume_partition_disengaged) (short);
567 int (*partition_engaged) (short);
568 int (*any_partition_engaged) (void);
569
570 int (*n_of_deliverable_payloads) (struct xpc_channel *);
571 enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
572 u16, u8, xpc_notify_func, void *);
573 void *(*get_deliverable_payload) (struct xpc_channel *);
574 void (*received_payload) (struct xpc_channel *, void *);
575 void (*notify_senders_of_disconnect) (struct xpc_channel *);
576 };
577
578
579
580 #define XPC_P_AS_INACTIVE 0x00
581 #define XPC_P_AS_ACTIVATION_REQ 0x01
582 #define XPC_P_AS_ACTIVATING 0x02
583 #define XPC_P_AS_ACTIVE 0x03
584 #define XPC_P_AS_DEACTIVATING 0x04
585
586 #define XPC_DEACTIVATE_PARTITION(_p, _reason) \
587 xpc_deactivate_partition(__LINE__, (_p), (_reason))
588
589
590
591 #define XPC_P_SS_UNSET 0x00
592 #define XPC_P_SS_SETUP 0x01
593 #define XPC_P_SS_WTEARDOWN 0x02
594 #define XPC_P_SS_TORNDOWN 0x03
595
596
597 #define XPC_DISENGAGE_DEFAULT_TIMELIMIT 90
598
599
600 #define XPC_DEACTIVATE_PRINTMSG_INTERVAL 10
601
602 #define XPC_PARTID(_p) ((short)((_p) - &xpc_partitions[0]))
603
604
605 extern struct xpc_registration xpc_registrations[];
606
607
608 extern struct device *xpc_part;
609 extern struct device *xpc_chan;
610 extern struct xpc_arch_operations xpc_arch_ops;
611 extern int xpc_disengage_timelimit;
612 extern int xpc_disengage_timedout;
613 extern int xpc_activate_IRQ_rcvd;
614 extern spinlock_t xpc_activate_IRQ_rcvd_lock;
615 extern wait_queue_head_t xpc_activate_IRQ_wq;
616 extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
617 extern void xpc_activate_partition(struct xpc_partition *);
618 extern void xpc_activate_kthreads(struct xpc_channel *, int);
619 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
620 extern void xpc_disconnect_wait(int);
621
622
623 extern int xpc_init_uv(void);
624 extern void xpc_exit_uv(void);
625
626
627 extern int xpc_exiting;
628 extern int xpc_nasid_mask_nlongs;
629 extern struct xpc_rsvd_page *xpc_rsvd_page;
630 extern unsigned long *xpc_mach_nasids;
631 extern struct xpc_partition *xpc_partitions;
632 extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
633 extern int xpc_setup_rsvd_page(void);
634 extern void xpc_teardown_rsvd_page(void);
635 extern int xpc_identify_activate_IRQ_sender(void);
636 extern int xpc_partition_disengaged(struct xpc_partition *);
637 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
638 extern void xpc_mark_partition_inactive(struct xpc_partition *);
639 extern void xpc_discovery(void);
640 extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
641 struct xpc_rsvd_page *,
642 unsigned long *);
643 extern void xpc_deactivate_partition(const int, struct xpc_partition *,
644 enum xp_retval);
645 extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
646
647
648 extern void xpc_initiate_connect(int);
649 extern void xpc_initiate_disconnect(int);
650 extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
651 extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
652 extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
653 xpc_notify_func, void *);
654 extern void xpc_initiate_received(short, int, void *);
655 extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
656 extern void xpc_connected_callout(struct xpc_channel *);
657 extern void xpc_deliver_payload(struct xpc_channel *);
658 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
659 enum xp_retval, unsigned long *);
660 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
661 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
662
663 static inline void
664 xpc_wakeup_channel_mgr(struct xpc_partition *part)
665 {
666 if (atomic_inc_return(&part->channel_mgr_requests) == 1)
667 wake_up(&part->channel_mgr_wq);
668 }
669
670
671
672
673
674 static inline void
675 xpc_msgqueue_ref(struct xpc_channel *ch)
676 {
677 atomic_inc(&ch->references);
678 }
679
680 static inline void
681 xpc_msgqueue_deref(struct xpc_channel *ch)
682 {
683 s32 refs = atomic_dec_return(&ch->references);
684
685 DBUG_ON(refs < 0);
686 if (refs == 0)
687 xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
688 }
689
690 #define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
691 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
692
693
694
695
696
697 static inline void
698 xpc_part_deref(struct xpc_partition *part)
699 {
700 s32 refs = atomic_dec_return(&part->references);
701
702 DBUG_ON(refs < 0);
703 if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
704 wake_up(&part->teardown_wq);
705 }
706
707 static inline int
708 xpc_part_ref(struct xpc_partition *part)
709 {
710 int setup;
711
712 atomic_inc(&part->references);
713 setup = (part->setup_state == XPC_P_SS_SETUP);
714 if (!setup)
715 xpc_part_deref(part);
716
717 return setup;
718 }
719
720
721
722
723
724
725 #define XPC_SET_REASON(_p, _reason, _line) \
726 { \
727 (_p)->reason = _reason; \
728 (_p)->reason_line = _line; \
729 }
730
731 #endif