linux/drivers/misc/sgi-xp/xpc.h
<<
>>
Prefs
   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-2009 Silicon Graphics, Inc.  All Rights Reserved.
   7 */
   8
   9/*
  10 * Cross Partition Communication (XPC) structures and macros.
  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 * XPC Version numbers consist of a major and minor number. XPC can always
  24 * talk to versions with same major #, and never talk to versions with a
  25 * different major #.
  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/* define frequency of the heartbeat and frequency how often it's checked */
  32#define XPC_HB_DEFAULT_INTERVAL         5       /* incr HB every x secs */
  33#define XPC_HB_CHECK_DEFAULT_INTERVAL   20      /* check HB every x secs */
  34
  35/* define the process name of HB checker and the CPU it is pinned to */
  36#define XPC_HB_CHECK_THREAD_NAME        "xpc_hb"
  37#define XPC_HB_CHECK_CPU                0
  38
  39/* define the process name of the discovery thread */
  40#define XPC_DISCOVERY_THREAD_NAME       "xpc_discovery"
  41
  42/*
  43 * the reserved page
  44 *
  45 *   SAL reserves one page of memory per partition for XPC. Though a full page
  46 *   in length (16384 bytes), its starting address is not page aligned, but it
  47 *   is cacheline aligned. The reserved page consists of the following:
  48 *
  49 *   reserved page header
  50 *
  51 *     The first two 64-byte cachelines of the reserved page contain the
  52 *     header (struct xpc_rsvd_page). Before SAL initialization has completed,
  53 *     SAL has set up the following fields of the reserved page header:
  54 *     SAL_signature, SAL_version, SAL_partid, and SAL_nasids_size. The
  55 *     other fields are set up by XPC. (xpc_rsvd_page points to the local
  56 *     partition's reserved page.)
  57 *
  58 *   part_nasids mask
  59 *   mach_nasids mask
  60 *
  61 *     SAL also sets up two bitmaps (or masks), one that reflects the actual
  62 *     nasids in this partition (part_nasids), and the other that reflects
  63 *     the actual nasids in the entire machine (mach_nasids). We're only
  64 *     interested in the even numbered nasids (which contain the processors
  65 *     and/or memory), so we only need half as many bits to represent the
  66 *     nasids. When mapping nasid to bit in a mask (or bit to nasid) be sure
  67 *     to either divide or multiply by 2. The part_nasids mask is located
  68 *     starting at the first cacheline following the reserved page header. The
  69 *     mach_nasids mask follows right after the part_nasids mask. The size in
  70 *     bytes of each mask is reflected by the reserved page header field
  71 *     'SAL_nasids_size'. (Local partition's mask pointers are xpc_part_nasids
  72 *     and xpc_mach_nasids.)
  73 *
  74 *   vars       (ia64-sn2 only)
  75 *   vars part  (ia64-sn2 only)
  76 *
  77 *     Immediately following the mach_nasids mask are the XPC variables
  78 *     required by other partitions. First are those that are generic to all
  79 *     partitions (vars), followed on the next available cacheline by those
  80 *     which are partition specific (vars part). These are setup by XPC.
  81 *     (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
  82 *
  83 * Note: Until 'ts_jiffies' is set non-zero, the partition XPC code has not been
  84 *       initialized.
  85 */
  86struct xpc_rsvd_page {
  87        u64 SAL_signature;      /* SAL: unique signature */
  88        u64 SAL_version;        /* SAL: version */
  89        short SAL_partid;       /* SAL: partition ID */
  90        short max_npartitions;  /* value of XPC_MAX_PARTITIONS */
  91        u8 version;
  92        u8 pad1[3];             /* align to next u64 in 1st 64-byte cacheline */
  93        union {
  94                unsigned long vars_pa;  /* phys address of struct xpc_vars */
  95                unsigned long activate_mq_gpa; /* gru phy addr of activate_mq */
  96        } sn;
  97        unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
  98        u64 pad2[10];           /* align to last u64 in 2nd 64-byte cacheline */
  99        u64 SAL_nasids_size;    /* SAL: size of each nasid mask in bytes */
 100};
 101
 102#define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */
 103
 104/*
 105 * Define the structures by which XPC variables can be exported to other
 106 * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
 107 */
 108
 109/*
 110 * The following structure describes the partition generic variables
 111 * needed by other partitions in order to properly initialize.
 112 *
 113 * struct xpc_vars version number also applies to struct xpc_vars_part.
 114 * Changes to either structure and/or related functionality should be
 115 * reflected by incrementing either the major or minor version numbers
 116 * of struct xpc_vars.
 117 */
 118struct xpc_vars_sn2 {
 119        u8 version;
 120        u64 heartbeat;
 121        DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
 122        u64 heartbeat_offline;  /* if 0, heartbeat should be changing */
 123        int activate_IRQ_nasid;
 124        int activate_IRQ_phys_cpuid;
 125        unsigned long vars_part_pa;
 126        unsigned long amos_page_pa;/* paddr of page of amos from MSPEC driver */
 127        struct amo *amos_page;  /* vaddr of page of amos from MSPEC driver */
 128};
 129
 130#define XPC_V_VERSION _XPC_VERSION(3, 1)    /* version 3.1 of the cross vars */
 131
 132/*
 133 * The following structure describes the per partition specific variables.
 134 *
 135 * An array of these structures, one per partition, will be defined. As a
 136 * partition becomes active XPC will copy the array entry corresponding to
 137 * itself from that partition. It is desirable that the size of this structure
 138 * evenly divides into a 128-byte cacheline, such that none of the entries in
 139 * this array crosses a 128-byte cacheline boundary. As it is now, each entry
 140 * occupies 64-bytes.
 141 */
 142struct xpc_vars_part_sn2 {
 143        u64 magic;
 144
 145        unsigned long openclose_args_pa; /* phys addr of open and close args */
 146        unsigned long GPs_pa;   /* physical address of Get/Put values */
 147
 148        unsigned long chctl_amo_pa; /* physical address of chctl flags' amo */
 149
 150        int notify_IRQ_nasid;   /* nasid of where to send notify IRQs */
 151        int notify_IRQ_phys_cpuid;      /* CPUID of where to send notify IRQs */
 152
 153        u8 nchannels;           /* #of defined channels supported */
 154
 155        u8 reserved[23];        /* pad to a full 64 bytes */
 156};
 157
 158/*
 159 * The vars_part MAGIC numbers play a part in the first contact protocol.
 160 *
 161 * MAGIC1 indicates that the per partition specific variables for a remote
 162 * partition have been initialized by this partition.
 163 *
 164 * MAGIC2 indicates that this partition has pulled the remote partititions
 165 * per partition variables that pertain to this partition.
 166 */
 167#define XPC_VP_MAGIC1_SN2 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
 168#define XPC_VP_MAGIC2_SN2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
 169
 170/* the reserved page sizes and offsets */
 171
 172#define XPC_RP_HEADER_SIZE      L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
 173#define XPC_RP_VARS_SIZE        L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
 174
 175#define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
 176                                 XPC_RP_HEADER_SIZE))
 177#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
 178                                 xpc_nasid_mask_nlongs)
 179#define XPC_RP_VARS(_rp)        ((struct xpc_vars_sn2 *) \
 180                                 (XPC_RP_MACH_NASIDS(_rp) + \
 181                                  xpc_nasid_mask_nlongs))
 182
 183/*
 184 * The activate_mq is used to send/receive GRU messages that affect XPC's
 185 * heartbeat, partition active state, and channel state. This is UV only.
 186 */
 187struct xpc_activate_mq_msghdr_uv {
 188        short partid;           /* sender's partid */
 189        u8 act_state;           /* sender's act_state at time msg sent */
 190        u8 type;                /* message's type */
 191        unsigned long rp_ts_jiffies; /* timestamp of sender's rp setup by XPC */
 192};
 193
 194/* activate_mq defined message types */
 195#define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV           0
 196#define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV            1
 197#define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV        2
 198#define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV         3
 199
 200#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV             4
 201#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV           5
 202
 203#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV       6
 204#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV         7
 205#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV        8
 206#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV          9
 207
 208#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV             10
 209#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV          11
 210
 211struct xpc_activate_mq_msg_uv {
 212        struct xpc_activate_mq_msghdr_uv hdr;
 213};
 214
 215struct xpc_activate_mq_msg_heartbeat_req_uv {
 216        struct xpc_activate_mq_msghdr_uv hdr;
 217        u64 heartbeat;
 218};
 219
 220struct xpc_activate_mq_msg_activate_req_uv {
 221        struct xpc_activate_mq_msghdr_uv hdr;
 222        unsigned long rp_gpa;
 223        unsigned long activate_mq_gpa;
 224};
 225
 226struct xpc_activate_mq_msg_deactivate_req_uv {
 227        struct xpc_activate_mq_msghdr_uv hdr;
 228        enum xp_retval reason;
 229};
 230
 231struct xpc_activate_mq_msg_chctl_closerequest_uv {
 232        struct xpc_activate_mq_msghdr_uv hdr;
 233        short ch_number;
 234        enum xp_retval reason;
 235};
 236
 237struct xpc_activate_mq_msg_chctl_closereply_uv {
 238        struct xpc_activate_mq_msghdr_uv hdr;
 239        short ch_number;
 240};
 241
 242struct xpc_activate_mq_msg_chctl_openrequest_uv {
 243        struct xpc_activate_mq_msghdr_uv hdr;
 244        short ch_number;
 245        short entry_size;       /* size of notify_mq's GRU messages */
 246        short local_nentries;   /* ??? Is this needed? What is? */
 247};
 248
 249struct xpc_activate_mq_msg_chctl_openreply_uv {
 250        struct xpc_activate_mq_msghdr_uv hdr;
 251        short ch_number;
 252        short remote_nentries;  /* ??? Is this needed? What is? */
 253        short local_nentries;   /* ??? Is this needed? What is? */
 254        unsigned long local_notify_mq_gpa;
 255};
 256
 257/*
 258 * Functions registered by add_timer() or called by kernel_thread() only
 259 * allow for a single 64-bit argument. The following macros can be used to
 260 * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from
 261 * the passed argument.
 262 */
 263#define XPC_PACK_ARGS(_arg1, _arg2) \
 264                        ((((u64)_arg1) & 0xffffffff) | \
 265                        ((((u64)_arg2) & 0xffffffff) << 32))
 266
 267#define XPC_UNPACK_ARG1(_args)  (((u64)_args) & 0xffffffff)
 268#define XPC_UNPACK_ARG2(_args)  ((((u64)_args) >> 32) & 0xffffffff)
 269
 270/*
 271 * Define a Get/Put value pair (pointers) used with a message queue.
 272 */
 273struct xpc_gp_sn2 {
 274        s64 get;                /* Get value */
 275        s64 put;                /* Put value */
 276};
 277
 278#define XPC_GP_SIZE \
 279                L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
 280
 281/*
 282 * Define a structure that contains arguments associated with opening and
 283 * closing a channel.
 284 */
 285struct xpc_openclose_args {
 286        u16 reason;             /* reason why channel is closing */
 287        u16 entry_size;         /* sizeof each message entry */
 288        u16 remote_nentries;    /* #of message entries in remote msg queue */
 289        u16 local_nentries;     /* #of message entries in local msg queue */
 290        unsigned long local_msgqueue_pa; /* phys addr of local message queue */
 291};
 292
 293#define XPC_OPENCLOSE_ARGS_SIZE \
 294              L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
 295              XPC_MAX_NCHANNELS)
 296
 297
 298/*
 299 * Structures to define a fifo singly-linked list.
 300 */
 301
 302struct xpc_fifo_entry_uv {
 303        struct xpc_fifo_entry_uv *next;
 304};
 305
 306struct xpc_fifo_head_uv {
 307        struct xpc_fifo_entry_uv *first;
 308        struct xpc_fifo_entry_uv *last;
 309        spinlock_t lock;
 310        int n_entries;
 311};
 312
 313/*
 314 * Define a sn2 styled message.
 315 *
 316 * A user-defined message resides in the payload area. The max size of the
 317 * payload is defined by the user via xpc_connect().
 318 *
 319 * The size of a message entry (within a message queue) must be a 128-byte
 320 * cacheline sized multiple in order to facilitate the BTE transfer of messages
 321 * from one message queue to another.
 322 */
 323struct xpc_msg_sn2 {
 324        u8 flags;               /* FOR XPC INTERNAL USE ONLY */
 325        u8 reserved[7];         /* FOR XPC INTERNAL USE ONLY */
 326        s64 number;             /* FOR XPC INTERNAL USE ONLY */
 327
 328        u64 payload;            /* user defined portion of message */
 329};
 330
 331/* struct xpc_msg_sn2 flags */
 332
 333#define XPC_M_SN2_DONE          0x01    /* msg has been received/consumed */
 334#define XPC_M_SN2_READY         0x02    /* msg is ready to be sent */
 335#define XPC_M_SN2_INTERRUPT     0x04    /* send interrupt when msg consumed */
 336
 337/*
 338 * The format of a uv XPC notify_mq GRU message is as follows:
 339 *
 340 * A user-defined message resides in the payload area. The max size of the
 341 * payload is defined by the user via xpc_connect().
 342 *
 343 * The size of a message (payload and header) sent via the GRU must be either 1
 344 * or 2 GRU_CACHE_LINE_BYTES in length.
 345 */
 346
 347struct xpc_notify_mq_msghdr_uv {
 348        union {
 349                unsigned int gru_msg_hdr;       /* FOR GRU INTERNAL USE ONLY */
 350                struct xpc_fifo_entry_uv next;  /* FOR XPC INTERNAL USE ONLY */
 351        } u;
 352        short partid;           /* FOR XPC INTERNAL USE ONLY */
 353        u8 ch_number;           /* FOR XPC INTERNAL USE ONLY */
 354        u8 size;                /* FOR XPC INTERNAL USE ONLY */
 355        unsigned int msg_slot_number;   /* FOR XPC INTERNAL USE ONLY */
 356};
 357
 358struct xpc_notify_mq_msg_uv {
 359        struct xpc_notify_mq_msghdr_uv hdr;
 360        unsigned long payload;
 361};
 362
 363/*
 364 * Define sn2's notify entry.
 365 *
 366 * This is used to notify a message's sender that their message was received
 367 * and consumed by the intended recipient.
 368 */
 369struct xpc_notify_sn2 {
 370        u8 type;                /* type of notification */
 371
 372        /* the following two fields are only used if type == XPC_N_CALL */
 373        xpc_notify_func func;   /* user's notify function */
 374        void *key;              /* pointer to user's key */
 375};
 376
 377/* struct xpc_notify_sn2 type of notification */
 378
 379#define XPC_N_CALL      0x01    /* notify function provided by user */
 380
 381/*
 382 * Define uv's version of the notify entry. It additionally is used to allocate
 383 * a msg slot on the remote partition into which is copied a sent message.
 384 */
 385struct xpc_send_msg_slot_uv {
 386        struct xpc_fifo_entry_uv next;
 387        unsigned int msg_slot_number;
 388        xpc_notify_func func;   /* user's notify function */
 389        void *key;              /* pointer to user's key */
 390};
 391
 392/*
 393 * Define the structure that manages all the stuff required by a channel. In
 394 * particular, they are used to manage the messages sent across the channel.
 395 *
 396 * This structure is private to a partition, and is NOT shared across the
 397 * partition boundary.
 398 *
 399 * There is an array of these structures for each remote partition. It is
 400 * allocated at the time a partition becomes active. The array contains one
 401 * of these structures for each potential channel connection to that partition.
 402 */
 403
 404/*
 405 * The following is sn2 only.
 406 *
 407 * Each channel structure manages two message queues (circular buffers).
 408 * They are allocated at the time a channel connection is made. One of
 409 * these message queues (local_msgqueue) holds the locally created messages
 410 * that are destined for the remote partition. The other of these message
 411 * queues (remote_msgqueue) is a locally cached copy of the remote partition's
 412 * own local_msgqueue.
 413 *
 414 * The following is a description of the Get/Put pointers used to manage these
 415 * two message queues. Consider the local_msgqueue to be on one partition
 416 * and the remote_msgqueue to be its cached copy on another partition. A
 417 * description of what each of the lettered areas contains is included.
 418 *
 419 *
 420 *                     local_msgqueue      remote_msgqueue
 421 *
 422 *                        |/////////|      |/////////|
 423 *    w_remote_GP.get --> +---------+      |/////////|
 424 *                        |    F    |      |/////////|
 425 *     remote_GP.get  --> +---------+      +---------+ <-- local_GP->get
 426 *                        |         |      |         |
 427 *                        |         |      |    E    |
 428 *                        |         |      |         |
 429 *                        |         |      +---------+ <-- w_local_GP.get
 430 *                        |    B    |      |/////////|
 431 *                        |         |      |////D////|
 432 *                        |         |      |/////////|
 433 *                        |         |      +---------+ <-- w_remote_GP.put
 434 *                        |         |      |////C////|
 435 *      local_GP->put --> +---------+      +---------+ <-- remote_GP.put
 436 *                        |         |      |/////////|
 437 *                        |    A    |      |/////////|
 438 *                        |         |      |/////////|
 439 *     w_local_GP.put --> +---------+      |/////////|
 440 *                        |/////////|      |/////////|
 441 *
 442 *
 443 *          ( remote_GP.[get|put] are cached copies of the remote
 444 *            partition's local_GP->[get|put], and thus their values can
 445 *            lag behind their counterparts on the remote partition. )
 446 *
 447 *
 448 *  A - Messages that have been allocated, but have not yet been sent to the
 449 *      remote partition.
 450 *
 451 *  B - Messages that have been sent, but have not yet been acknowledged by the
 452 *      remote partition as having been received.
 453 *
 454 *  C - Area that needs to be prepared for the copying of sent messages, by
 455 *      the clearing of the message flags of any previously received messages.
 456 *
 457 *  D - Area into which sent messages are to be copied from the remote
 458 *      partition's local_msgqueue and then delivered to their intended
 459 *      recipients. [ To allow for a multi-message copy, another pointer
 460 *      (next_msg_to_pull) has been added to keep track of the next message
 461 *      number needing to be copied (pulled). It chases after w_remote_GP.put.
 462 *      Any messages lying between w_local_GP.get and next_msg_to_pull have
 463 *      been copied and are ready to be delivered. ]
 464 *
 465 *  E - Messages that have been copied and delivered, but have not yet been
 466 *      acknowledged by the recipient as having been received.
 467 *
 468 *  F - Messages that have been acknowledged, but XPC has not yet notified the
 469 *      sender that the message was received by its intended recipient.
 470 *      This is also an area that needs to be prepared for the allocating of
 471 *      new messages, by the clearing of the message flags of the acknowledged
 472 *      messages.
 473 */
 474
 475struct xpc_channel_sn2 {
 476        struct xpc_openclose_args *local_openclose_args; /* args passed on */
 477                                             /* opening or closing of channel */
 478
 479        void *local_msgqueue_base;      /* base address of kmalloc'd space */
 480        struct xpc_msg_sn2 *local_msgqueue;     /* local message queue */
 481        void *remote_msgqueue_base;     /* base address of kmalloc'd space */
 482        struct xpc_msg_sn2 *remote_msgqueue; /* cached copy of remote */
 483                                           /* partition's local message queue */
 484        unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
 485                                          /* local message queue */
 486
 487        struct xpc_notify_sn2 *notify_queue;/* notify queue for messages sent */
 488
 489        /* various flavors of local and remote Get/Put values */
 490
 491        struct xpc_gp_sn2 *local_GP;    /* local Get/Put values */
 492        struct xpc_gp_sn2 remote_GP;    /* remote Get/Put values */
 493        struct xpc_gp_sn2 w_local_GP;   /* working local Get/Put values */
 494        struct xpc_gp_sn2 w_remote_GP;  /* working remote Get/Put values */
 495        s64 next_msg_to_pull;   /* Put value of next msg to pull */
 496
 497        struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
 498};
 499
 500struct xpc_channel_uv {
 501        unsigned long remote_notify_mq_gpa;     /* gru phys address of remote */
 502                                                /* partition's notify mq */
 503
 504        struct xpc_send_msg_slot_uv *send_msg_slots;
 505        void *recv_msg_slots;   /* each slot will hold a xpc_notify_mq_msg_uv */
 506                                /* structure plus the user's payload */
 507
 508        struct xpc_fifo_head_uv msg_slot_free_list;
 509        struct xpc_fifo_head_uv recv_msg_list;  /* deliverable payloads */
 510};
 511
 512struct xpc_channel {
 513        short partid;           /* ID of remote partition connected */
 514        spinlock_t lock;        /* lock for updating this structure */
 515        unsigned int flags;     /* general flags */
 516
 517        enum xp_retval reason;  /* reason why channel is disconnect'g */
 518        int reason_line;        /* line# disconnect initiated from */
 519
 520        u16 number;             /* channel # */
 521
 522        u16 entry_size;         /* sizeof each msg entry */
 523        u16 local_nentries;     /* #of msg entries in local msg queue */
 524        u16 remote_nentries;    /* #of msg entries in remote msg queue */
 525
 526        atomic_t references;    /* #of external references to queues */
 527
 528        atomic_t n_on_msg_allocate_wq;  /* #on msg allocation wait queue */
 529        wait_queue_head_t msg_allocate_wq;      /* msg allocation wait queue */
 530
 531        u8 delayed_chctl_flags; /* chctl flags received, but delayed */
 532                                /* action until channel disconnected */
 533
 534        atomic_t n_to_notify;   /* #of msg senders to notify */
 535
 536        xpc_channel_func func;  /* user's channel function */
 537        void *key;              /* pointer to user's key */
 538
 539        struct completion wdisconnect_wait;    /* wait for channel disconnect */
 540
 541        /* kthread management related fields */
 542
 543        atomic_t kthreads_assigned;     /* #of kthreads assigned to channel */
 544        u32 kthreads_assigned_limit;    /* limit on #of kthreads assigned */
 545        atomic_t kthreads_idle; /* #of kthreads idle waiting for work */
 546        u32 kthreads_idle_limit;        /* limit on #of kthreads idle */
 547        atomic_t kthreads_active;       /* #of kthreads actively working */
 548
 549        wait_queue_head_t idle_wq;      /* idle kthread wait queue */
 550
 551        union {
 552                struct xpc_channel_sn2 sn2;
 553                struct xpc_channel_uv uv;
 554        } sn;
 555
 556} ____cacheline_aligned;
 557
 558/* struct xpc_channel flags */
 559
 560#define XPC_C_WASCONNECTED      0x00000001      /* channel was connected */
 561
 562#define XPC_C_ROPENREPLY        0x00000002      /* remote open channel reply */
 563#define XPC_C_OPENREPLY         0x00000004      /* local open channel reply */
 564#define XPC_C_ROPENREQUEST      0x00000008     /* remote open channel request */
 565#define XPC_C_OPENREQUEST       0x00000010      /* local open channel request */
 566
 567#define XPC_C_SETUP             0x00000020 /* channel's msgqueues are alloc'd */
 568#define XPC_C_CONNECTEDCALLOUT  0x00000040     /* connected callout initiated */
 569#define XPC_C_CONNECTEDCALLOUT_MADE \
 570                                0x00000080     /* connected callout completed */
 571#define XPC_C_CONNECTED         0x00000100      /* local channel is connected */
 572#define XPC_C_CONNECTING        0x00000200      /* channel is being connected */
 573
 574#define XPC_C_RCLOSEREPLY       0x00000400      /* remote close channel reply */
 575#define XPC_C_CLOSEREPLY        0x00000800      /* local close channel reply */
 576#define XPC_C_RCLOSEREQUEST     0x00001000    /* remote close channel request */
 577#define XPC_C_CLOSEREQUEST      0x00002000     /* local close channel request */
 578
 579#define XPC_C_DISCONNECTED      0x00004000      /* channel is disconnected */
 580#define XPC_C_DISCONNECTING     0x00008000   /* channel is being disconnected */
 581#define XPC_C_DISCONNECTINGCALLOUT \
 582                                0x00010000 /* disconnecting callout initiated */
 583#define XPC_C_DISCONNECTINGCALLOUT_MADE \
 584                                0x00020000 /* disconnecting callout completed */
 585#define XPC_C_WDISCONNECT       0x00040000  /* waiting for channel disconnect */
 586
 587/*
 588 * The channel control flags (chctl) union consists of a 64-bit variable which
 589 * is divided up into eight bytes, ordered from right to left. Byte zero
 590 * pertains to channel 0, byte one to channel 1, and so on. Each channel's byte
 591 * can have one or more of the chctl flags set in it.
 592 */
 593
 594union xpc_channel_ctl_flags {
 595        u64 all_flags;
 596        u8 flags[XPC_MAX_NCHANNELS];
 597};
 598
 599/* chctl flags */
 600#define XPC_CHCTL_CLOSEREQUEST  0x01
 601#define XPC_CHCTL_CLOSEREPLY    0x02
 602#define XPC_CHCTL_OPENREQUEST   0x04
 603#define XPC_CHCTL_OPENREPLY     0x08
 604#define XPC_CHCTL_MSGREQUEST    0x10
 605
 606#define XPC_OPENCLOSE_CHCTL_FLAGS \
 607                        (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
 608                         XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
 609#define XPC_MSG_CHCTL_FLAGS     XPC_CHCTL_MSGREQUEST
 610
 611static inline int
 612xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
 613{
 614        int ch_number;
 615
 616        for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
 617                if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
 618                        return 1;
 619        }
 620        return 0;
 621}
 622
 623static inline int
 624xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
 625{
 626        int ch_number;
 627
 628        for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
 629                if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
 630                        return 1;
 631        }
 632        return 0;
 633}
 634
 635/*
 636 * Manage channels on a partition basis. There is one of these structures
 637 * for each partition (a partition will never utilize the structure that
 638 * represents itself).
 639 */
 640
 641struct xpc_partition_sn2 {
 642        unsigned long remote_amos_page_pa; /* paddr of partition's amos page */
 643        int activate_IRQ_nasid; /* active partition's act/deact nasid */
 644        int activate_IRQ_phys_cpuid;    /* active part's act/deact phys cpuid */
 645
 646        unsigned long remote_vars_pa;   /* phys addr of partition's vars */
 647        unsigned long remote_vars_part_pa; /* paddr of partition's vars part */
 648        u8 remote_vars_version; /* version# of partition's vars */
 649
 650        void *local_GPs_base;   /* base address of kmalloc'd space */
 651        struct xpc_gp_sn2 *local_GPs;   /* local Get/Put values */
 652        void *remote_GPs_base;  /* base address of kmalloc'd space */
 653        struct xpc_gp_sn2 *remote_GPs;  /* copy of remote partition's local */
 654                                        /* Get/Put values */
 655        unsigned long remote_GPs_pa; /* phys addr of remote partition's local */
 656                                     /* Get/Put values */
 657
 658        void *local_openclose_args_base;   /* base address of kmalloc'd space */
 659        struct xpc_openclose_args *local_openclose_args;      /* local's args */
 660        unsigned long remote_openclose_args_pa; /* phys addr of remote's args */
 661
 662        int notify_IRQ_nasid;   /* nasid of where to send notify IRQs */
 663        int notify_IRQ_phys_cpuid;      /* CPUID of where to send notify IRQs */
 664        char notify_IRQ_owner[8];       /* notify IRQ's owner's name */
 665
 666        struct amo *remote_chctl_amo_va; /* addr of remote chctl flags' amo */
 667        struct amo *local_chctl_amo_va; /* address of chctl flags' amo */
 668
 669        struct timer_list dropped_notify_IRQ_timer;     /* dropped IRQ timer */
 670};
 671
 672struct xpc_partition_uv {
 673        unsigned long remote_activate_mq_gpa;   /* gru phys address of remote */
 674                                                /* partition's activate mq */
 675        spinlock_t flags_lock;  /* protect updating of flags */
 676        unsigned int flags;     /* general flags */
 677        u8 remote_act_state;    /* remote partition's act_state */
 678        u8 act_state_req;       /* act_state request from remote partition */
 679        enum xp_retval reason;  /* reason for deactivate act_state request */
 680        u64 heartbeat;          /* incremented by remote partition */
 681};
 682
 683/* struct xpc_partition_uv flags */
 684
 685#define XPC_P_HEARTBEAT_OFFLINE_UV      0x00000001
 686#define XPC_P_ENGAGED_UV                0x00000002
 687
 688/* struct xpc_partition_uv act_state change requests */
 689
 690#define XPC_P_ASR_ACTIVATE_UV           0x01
 691#define XPC_P_ASR_REACTIVATE_UV         0x02
 692#define XPC_P_ASR_DEACTIVATE_UV         0x03
 693
 694struct xpc_partition {
 695
 696        /* XPC HB infrastructure */
 697
 698        u8 remote_rp_version;   /* version# of partition's rsvd pg */
 699        unsigned long remote_rp_ts_jiffies; /* timestamp when rsvd pg setup */
 700        unsigned long remote_rp_pa;     /* phys addr of partition's rsvd pg */
 701        u64 last_heartbeat;     /* HB at last read */
 702        u32 activate_IRQ_rcvd;  /* IRQs since activation */
 703        spinlock_t act_lock;    /* protect updating of act_state */
 704        u8 act_state;           /* from XPC HB viewpoint */
 705        enum xp_retval reason;  /* reason partition is deactivating */
 706        int reason_line;        /* line# deactivation initiated from */
 707
 708        unsigned long disengage_timeout;        /* timeout in jiffies */
 709        struct timer_list disengage_timer;
 710
 711        /* XPC infrastructure referencing and teardown control */
 712
 713        u8 setup_state;         /* infrastructure setup state */
 714        wait_queue_head_t teardown_wq;  /* kthread waiting to teardown infra */
 715        atomic_t references;    /* #of references to infrastructure */
 716
 717        u8 nchannels;           /* #of defined channels supported */
 718        atomic_t nchannels_active;  /* #of channels that are not DISCONNECTED */
 719        atomic_t nchannels_engaged;  /* #of channels engaged with remote part */
 720        struct xpc_channel *channels;   /* array of channel structures */
 721
 722        /* fields used for managing channel avialability and activity */
 723
 724        union xpc_channel_ctl_flags chctl; /* chctl flags yet to be processed */
 725        spinlock_t chctl_lock;  /* chctl flags lock */
 726
 727        void *remote_openclose_args_base;  /* base address of kmalloc'd space */
 728        struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
 729                                                          /* args */
 730
 731        /* channel manager related fields */
 732
 733        atomic_t channel_mgr_requests;  /* #of requests to activate chan mgr */
 734        wait_queue_head_t channel_mgr_wq;       /* channel mgr's wait queue */
 735
 736        union {
 737                struct xpc_partition_sn2 sn2;
 738                struct xpc_partition_uv uv;
 739        } sn;
 740
 741} ____cacheline_aligned;
 742
 743/* struct xpc_partition act_state values (for XPC HB) */
 744
 745#define XPC_P_AS_INACTIVE       0x00    /* partition is not active */
 746#define XPC_P_AS_ACTIVATION_REQ 0x01    /* created thread to activate */
 747#define XPC_P_AS_ACTIVATING     0x02    /* activation thread started */
 748#define XPC_P_AS_ACTIVE         0x03    /* xpc_partition_up() was called */
 749#define XPC_P_AS_DEACTIVATING   0x04    /* partition deactivation initiated */
 750
 751#define XPC_DEACTIVATE_PARTITION(_p, _reason) \
 752                        xpc_deactivate_partition(__LINE__, (_p), (_reason))
 753
 754/* struct xpc_partition setup_state values */
 755
 756#define XPC_P_SS_UNSET          0x00    /* infrastructure was never setup */
 757#define XPC_P_SS_SETUP          0x01    /* infrastructure is setup */
 758#define XPC_P_SS_WTEARDOWN      0x02    /* waiting to teardown infrastructure */
 759#define XPC_P_SS_TORNDOWN       0x03    /* infrastructure is torndown */
 760
 761/*
 762 * struct xpc_partition_sn2's dropped notify IRQ timer is set to wait the
 763 * following interval #of seconds before checking for dropped notify IRQs.
 764 * These can occur whenever an IRQ's associated amo write doesn't complete
 765 * until after the IRQ was received.
 766 */
 767#define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL    (0.25 * HZ)
 768
 769/* number of seconds to wait for other partitions to disengage */
 770#define XPC_DISENGAGE_DEFAULT_TIMELIMIT         90
 771
 772/* interval in seconds to print 'waiting deactivation' messages */
 773#define XPC_DEACTIVATE_PRINTMSG_INTERVAL        10
 774
 775#define XPC_PARTID(_p)  ((short)((_p) - &xpc_partitions[0]))
 776
 777/* found in xp_main.c */
 778extern struct xpc_registration xpc_registrations[];
 779
 780/* found in xpc_main.c */
 781extern struct device *xpc_part;
 782extern struct device *xpc_chan;
 783extern int xpc_disengage_timelimit;
 784extern int xpc_disengage_timedout;
 785extern int xpc_activate_IRQ_rcvd;
 786extern spinlock_t xpc_activate_IRQ_rcvd_lock;
 787extern wait_queue_head_t xpc_activate_IRQ_wq;
 788extern void *xpc_heartbeating_to_mask;
 789extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
 790extern void xpc_activate_partition(struct xpc_partition *);
 791extern void xpc_activate_kthreads(struct xpc_channel *, int);
 792extern void xpc_create_kthreads(struct xpc_channel *, int, int);
 793extern void xpc_disconnect_wait(int);
 794extern int (*xpc_setup_partitions_sn) (void);
 795extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
 796                                                         unsigned long *,
 797                                                         size_t *);
 798extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
 799extern void (*xpc_heartbeat_init) (void);
 800extern void (*xpc_heartbeat_exit) (void);
 801extern void (*xpc_increment_heartbeat) (void);
 802extern void (*xpc_offline_heartbeat) (void);
 803extern void (*xpc_online_heartbeat) (void);
 804extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
 805extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
 806extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
 807extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
 808extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
 809extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
 810extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
 811extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
 812extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
 813extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
 814                                                 unsigned long, int);
 815extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
 816extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
 817extern void (*xpc_cancel_partition_deactivation_request) (
 818                                                        struct xpc_partition *);
 819extern void (*xpc_process_activate_IRQ_rcvd) (void);
 820extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
 821extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);
 822
 823extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
 824extern int (*xpc_partition_engaged) (short);
 825extern int (*xpc_any_partition_engaged) (void);
 826extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
 827extern void (*xpc_assume_partition_disengaged) (short);
 828
 829extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
 830                                            unsigned long *);
 831extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
 832                                          unsigned long *);
 833extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
 834                                           unsigned long *);
 835extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
 836
 837extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
 838                                            unsigned long);
 839
 840extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
 841                                           u16, u8, xpc_notify_func, void *);
 842extern void (*xpc_received_payload) (struct xpc_channel *, void *);
 843
 844/* found in xpc_sn2.c */
 845extern int xpc_init_sn2(void);
 846extern void xpc_exit_sn2(void);
 847
 848/* found in xpc_uv.c */
 849extern int xpc_init_uv(void);
 850extern void xpc_exit_uv(void);
 851
 852/* found in xpc_partition.c */
 853extern int xpc_exiting;
 854extern int xpc_nasid_mask_nlongs;
 855extern struct xpc_rsvd_page *xpc_rsvd_page;
 856extern unsigned long *xpc_mach_nasids;
 857extern struct xpc_partition *xpc_partitions;
 858extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
 859extern int xpc_setup_rsvd_page(void);
 860extern void xpc_teardown_rsvd_page(void);
 861extern int xpc_identify_activate_IRQ_sender(void);
 862extern int xpc_partition_disengaged(struct xpc_partition *);
 863extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
 864extern void xpc_mark_partition_inactive(struct xpc_partition *);
 865extern void xpc_discovery(void);
 866extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
 867                                        struct xpc_rsvd_page *,
 868                                        unsigned long *);
 869extern void xpc_deactivate_partition(const int, struct xpc_partition *,
 870                                     enum xp_retval);
 871extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
 872
 873/* found in xpc_channel.c */
 874extern void xpc_initiate_connect(int);
 875extern void xpc_initiate_disconnect(int);
 876extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
 877extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
 878extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
 879                                               xpc_notify_func, void *);
 880extern void xpc_initiate_received(short, int, void *);
 881extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
 882extern void xpc_connected_callout(struct xpc_channel *);
 883extern void xpc_deliver_payload(struct xpc_channel *);
 884extern void xpc_disconnect_channel(const int, struct xpc_channel *,
 885                                   enum xp_retval, unsigned long *);
 886extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
 887extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
 888
 889static inline int
 890xpc_hb_allowed(short partid, void *heartbeating_to_mask)
 891{
 892        return test_bit(partid, heartbeating_to_mask);
 893}
 894
 895static inline int
 896xpc_any_hbs_allowed(void)
 897{
 898        DBUG_ON(xpc_heartbeating_to_mask == NULL);
 899        return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions);
 900}
 901
 902static inline void
 903xpc_allow_hb(short partid)
 904{
 905        DBUG_ON(xpc_heartbeating_to_mask == NULL);
 906        set_bit(partid, xpc_heartbeating_to_mask);
 907}
 908
 909static inline void
 910xpc_disallow_hb(short partid)
 911{
 912        DBUG_ON(xpc_heartbeating_to_mask == NULL);
 913        clear_bit(partid, xpc_heartbeating_to_mask);
 914}
 915
 916static inline void
 917xpc_disallow_all_hbs(void)
 918{
 919        DBUG_ON(xpc_heartbeating_to_mask == NULL);
 920        bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions);
 921}
 922
 923static inline void
 924xpc_wakeup_channel_mgr(struct xpc_partition *part)
 925{
 926        if (atomic_inc_return(&part->channel_mgr_requests) == 1)
 927                wake_up(&part->channel_mgr_wq);
 928}
 929
 930/*
 931 * These next two inlines are used to keep us from tearing down a channel's
 932 * msg queues while a thread may be referencing them.
 933 */
 934static inline void
 935xpc_msgqueue_ref(struct xpc_channel *ch)
 936{
 937        atomic_inc(&ch->references);
 938}
 939
 940static inline void
 941xpc_msgqueue_deref(struct xpc_channel *ch)
 942{
 943        s32 refs = atomic_dec_return(&ch->references);
 944
 945        DBUG_ON(refs < 0);
 946        if (refs == 0)
 947                xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
 948}
 949
 950#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
 951                xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
 952
 953/*
 954 * These two inlines are used to keep us from tearing down a partition's
 955 * setup infrastructure while a thread may be referencing it.
 956 */
 957static inline void
 958xpc_part_deref(struct xpc_partition *part)
 959{
 960        s32 refs = atomic_dec_return(&part->references);
 961
 962        DBUG_ON(refs < 0);
 963        if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
 964                wake_up(&part->teardown_wq);
 965}
 966
 967static inline int
 968xpc_part_ref(struct xpc_partition *part)
 969{
 970        int setup;
 971
 972        atomic_inc(&part->references);
 973        setup = (part->setup_state == XPC_P_SS_SETUP);
 974        if (!setup)
 975                xpc_part_deref(part);
 976
 977        return setup;
 978}
 979
 980/*
 981 * The following macro is to be used for the setting of the reason and
 982 * reason_line fields in both the struct xpc_channel and struct xpc_partition
 983 * structures.
 984 */
 985#define XPC_SET_REASON(_p, _reason, _line) \
 986        { \
 987                (_p)->reason = _reason; \
 988                (_p)->reason_line = _line; \
 989        }
 990
 991#endif /* _DRIVERS_MISC_SGIXP_XPC_H */
 992
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.