Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b8669df authored by Dean Nelson's avatar Dean Nelson Committed by Linus Torvalds
Browse files

sgi-xp: setup the activate GRU message queue



Setup the activate GRU message queue that is used for partition activation
and channel connection on UV systems.

Signed-off-by: default avatarDean Nelson <dcn@sgi.com>
Cc: Jack Steiner <steiner@sgi.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 83469b55
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -208,8 +208,9 @@ enum xp_retval {
	xpNeedMoreInfo,		/* 57: more info is needed by SAL */

	xpGruCopyError,		/* 58: gru_copy_gru() returned error */
	xpGruSendMqError,	/* 59: gru send message queue related error */

	xpUnknownReason		/* 59: unknown reason - must be last in enum */
	xpUnknownReason		/* 60: unknown reason - must be last in enum */
};

/*
+10 −0
Original line number Diff line number Diff line
@@ -42,15 +42,25 @@ xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
	return xpGruCopyError;
}

static int
xp_cpu_to_nasid_uv(int cpuid)
{
	/* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */
	return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
}

enum xp_retval
xp_init_uv(void)
{
	BUG_ON(!is_uv());

	xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
	xp_partition_id = 0;	/* !!! not correct value */
	xp_region_size = 0;	/* !!! not correct value */

	xp_pa = xp_pa_uv;
	xp_remote_memcpy = xp_remote_memcpy_uv;
	xp_cpu_to_nasid = xp_cpu_to_nasid_uv;

	return xpSuccess;
}
+128 −30
Original line number Diff line number Diff line
@@ -164,8 +164,8 @@ struct xpc_vars_part_sn2 {
 * MAGIC2 indicates that this partition has pulled the remote partititions
 * per partition variables that pertain to this partition.
 */
#define XPC_VP_MAGIC1	0x0053524156435058L   /* 'XPCVARS\0'L (little endian) */
#define XPC_VP_MAGIC2	0x0073726176435058L   /* 'XPCvars\0'L (little endian) */
#define XPC_VP_MAGIC1_SN2 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
#define XPC_VP_MAGIC2_SN2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */

/* the reserved page sizes and offsets */

@@ -180,6 +180,80 @@ struct xpc_vars_part_sn2 {
				 (XPC_RP_MACH_NASIDS(_rp) + \
				  xpc_nasid_mask_nlongs))

/*
 * The activate_mq is used to send/receive messages that affect XPC's heartbeat,
 * partition active state, and channel state. This is UV only.
 */
struct xpc_activate_mq_msghdr_uv {
	short partid;		/* sender's partid */
	u8 act_state;		/* sender's act_state at time msg sent */
	u8 type;		/* message's type */
	unsigned long rp_ts_jiffies; /* timestamp of sender's rp setup by XPC */
};

/* activate_mq defined message types */
#define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV		0
#define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV		1
#define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV	2
#define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV		3

#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV		4
#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV		5

#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV	6
#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV		7
#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV	8
#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV		9

#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV		10
#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV		11

struct xpc_activate_mq_msg_uv {
	struct xpc_activate_mq_msghdr_uv header;
};

struct xpc_activate_mq_msg_heartbeat_req_uv {
	struct xpc_activate_mq_msghdr_uv header;
	u64 heartbeat;
};

struct xpc_activate_mq_msg_activate_req_uv {
	struct xpc_activate_mq_msghdr_uv header;
	unsigned long rp_gpa;
	unsigned long activate_mq_gpa;
};

struct xpc_activate_mq_msg_deactivate_req_uv {
	struct xpc_activate_mq_msghdr_uv header;
	enum xp_retval reason;
};

struct xpc_activate_mq_msg_chctl_closerequest_uv {
	struct xpc_activate_mq_msghdr_uv header;
	short ch_number;
	enum xp_retval reason;
};

struct xpc_activate_mq_msg_chctl_closereply_uv {
	struct xpc_activate_mq_msghdr_uv header;
	short ch_number;
};

struct xpc_activate_mq_msg_chctl_openrequest_uv {
	struct xpc_activate_mq_msghdr_uv header;
	short ch_number;
	short msg_size;		/* size of notify_mq's messages */
	short local_nentries;	/* ??? Is this needed? What is? */
};

struct xpc_activate_mq_msg_chctl_openreply_uv {
	struct xpc_activate_mq_msghdr_uv header;
	short ch_number;
	short remote_nentries;	/* ??? Is this needed? What is? */
	short local_nentries;	/* ??? Is this needed? What is? */
	unsigned long local_notify_mq_gpa;
};

/*
 * Functions registered by add_timer() or called by kernel_thread() only
 * allow for a single 64-bit argument. The following macros can be used to
@@ -331,6 +405,18 @@ struct xpc_notify {
 */

struct xpc_channel_sn2 {
	struct xpc_openclose_args *local_openclose_args; /* args passed on */
					     /* opening or closing of channel */

	void *local_msgqueue_base;	/* base address of kmalloc'd space */
	struct xpc_msg *local_msgqueue;	/* local message queue */
	void *remote_msgqueue_base;	/* base address of kmalloc'd space */
	struct xpc_msg *remote_msgqueue; /* cached copy of remote partition's */
					 /* local message queue */
	unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
					  /* local message queue */

	struct xpc_notify *notify_queue;    /* notify queue for messages sent */

	/* various flavors of local and remote Get/Put values */

@@ -344,13 +430,14 @@ struct xpc_channel_sn2 {
};

struct xpc_channel_uv {
	/* !!! code is coming */
	unsigned long remote_notify_mq_gpa;	/* gru phys address of remote */
						/* partition's notify mq */
};

struct xpc_channel {
	short partid;		/* ID of remote partition connected */
	spinlock_t lock;	/* lock for updating this structure */
	u32 flags;		/* general flags */
	unsigned int flags;	/* general flags */

	enum xp_retval reason;	/* reason why channel is disconnect'g */
	int reason_line;	/* line# disconnect initiated from */
@@ -361,14 +448,6 @@ struct xpc_channel {
	u16 local_nentries;	/* #of msg entries in local msg queue */
	u16 remote_nentries;	/* #of msg entries in remote msg queue */

	void *local_msgqueue_base;	/* base address of kmalloc'd space */
	struct xpc_msg *local_msgqueue;	/* local message queue */
	void *remote_msgqueue_base;	/* base address of kmalloc'd space */
	struct xpc_msg *remote_msgqueue; /* cached copy of remote partition's */
					 /* local message queue */
	unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
					  /* local message queue */

	atomic_t references;	/* #of external references to queues */

	atomic_t n_on_msg_allocate_wq;	/* #on msg allocation wait queue */
@@ -377,19 +456,13 @@ struct xpc_channel {
	u8 delayed_chctl_flags;	/* chctl flags received, but delayed */
				/* action until channel disconnected */

	/* queue of msg senders who want to be notified when msg received */

	atomic_t n_to_notify;	/* #of msg senders to notify */
	struct xpc_notify *notify_queue;    /* notify queue for messages sent */

	xpc_channel_func func;	/* user's channel function */
	void *key;		/* pointer to user's key */

	struct completion wdisconnect_wait;    /* wait for channel disconnect */

	struct xpc_openclose_args *local_openclose_args; /* args passed on */
					     /* opening or closing of channel */

	/* kthread management related fields */

	atomic_t kthreads_assigned;	/* #of kthreads assigned to channel */
@@ -507,6 +580,8 @@ struct xpc_partition_sn2 {
	unsigned long remote_GPs_pa; /* phys addr of remote partition's local */
				     /* Get/Put values */

	void *local_openclose_args_base;   /* base address of kmalloc'd space */
	struct xpc_openclose_args *local_openclose_args;      /* local's args */
	unsigned long remote_openclose_args_pa;	/* phys addr of remote's args */

	int notify_IRQ_nasid;	/* nasid of where to send notify IRQs */
@@ -520,9 +595,27 @@ struct xpc_partition_sn2 {
};

struct xpc_partition_uv {
	/* !!! code is coming */
	unsigned long remote_activate_mq_gpa;	/* gru phys address of remote */
						/* partition's activate mq */
	spinlock_t flags_lock;	/* protect updating of flags */
	unsigned int flags;	/* general flags */
	u8 remote_act_state;	/* remote partition's act_state */
	u8 act_state_req;	/* act_state request from remote partition */
	enum xp_retval reason;	/* reason for deactivate act_state request */
	u64 heartbeat;		/* incremented by remote partition */
};

/* struct xpc_partition_uv flags */

#define XPC_P_HEARTBEAT_OFFLINE_UV	0x00000001
#define XPC_P_ENGAGED_UV		0x00000002

/* struct xpc_partition_uv act_state change requests */

#define XPC_P_ASR_ACTIVATE_UV		0x01
#define XPC_P_ASR_REACTIVATE_UV		0x02
#define XPC_P_ASR_DEACTIVATE_UV		0x03

struct xpc_partition {

	/* XPC HB infrastructure */
@@ -556,8 +649,6 @@ struct xpc_partition {
	union xpc_channel_ctl_flags chctl; /* chctl flags yet to be processed */
	spinlock_t chctl_lock;	/* chctl flags lock */

	void *local_openclose_args_base;   /* base address of kmalloc'd space */
	struct xpc_openclose_args *local_openclose_args;      /* local's args */
	void *remote_openclose_args_base;  /* base address of kmalloc'd space */
	struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
							  /* args */
@@ -616,17 +707,20 @@ extern struct device *xpc_part;
extern struct device *xpc_chan;
extern int xpc_disengage_timelimit;
extern int xpc_disengage_timedout;
extern atomic_t xpc_activate_IRQ_rcvd;
extern int xpc_activate_IRQ_rcvd;
extern spinlock_t xpc_activate_IRQ_rcvd_lock;
extern wait_queue_head_t xpc_activate_IRQ_wq;
extern void *xpc_heartbeating_to_mask;
extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
extern void xpc_activate_partition(struct xpc_partition *);
extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);
extern int (*xpc_setup_partitions_sn) (void);
extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
							 unsigned long *,
							 size_t *);
extern enum xp_retval (*xpc_rsvd_page_init) (struct xpc_rsvd_page *);
extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
extern void (*xpc_heartbeat_init) (void);
extern void (*xpc_heartbeat_exit) (void);
extern void (*xpc_increment_heartbeat) (void);
@@ -635,8 +729,8 @@ extern void (*xpc_online_heartbeat) (void);
extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
extern enum xp_retval (*xpc_allocate_msgqueues) (struct xpc_channel *);
extern void (*xpc_free_msgqueues) (struct xpc_channel *);
extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
extern int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *);
@@ -647,9 +741,9 @@ extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
extern void (*xpc_cancel_partition_deactivation_request) (
							struct xpc_partition *);
extern void (*xpc_process_activate_IRQ_rcvd) (int);
extern enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *);
extern void (*xpc_teardown_infrastructure) (struct xpc_partition *);
extern void (*xpc_process_activate_IRQ_rcvd) (void);
extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);

extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
extern int (*xpc_partition_engaged) (short);
@@ -665,6 +759,9 @@ extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
					   unsigned long *);
extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);

extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
					    unsigned long);

extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16,
				       u8, xpc_notify_func, void *);
extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *);
@@ -674,7 +771,7 @@ extern int xpc_init_sn2(void);
extern void xpc_exit_sn2(void);

/* found in xpc_uv.c */
extern void xpc_init_uv(void);
extern int xpc_init_uv(void);
extern void xpc_exit_uv(void);

/* found in xpc_partition.c */
@@ -684,7 +781,8 @@ extern struct xpc_rsvd_page *xpc_rsvd_page;
extern unsigned long *xpc_mach_nasids;
extern struct xpc_partition *xpc_partitions;
extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
extern int xpc_setup_rsvd_page(void);
extern void xpc_teardown_rsvd_page(void);
extern int xpc_identify_activate_IRQ_sender(void);
extern int xpc_partition_disengaged(struct xpc_partition *);
extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
+15 −7
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)

	if (!(ch->flags & XPC_C_SETUP)) {
		spin_unlock_irqrestore(&ch->lock, *irq_flags);
		ret = xpc_allocate_msgqueues(ch);
		ret = xpc_setup_msg_structures(ch);
		spin_lock_irqsave(&ch->lock, *irq_flags);

		if (ret != xpSuccess)
@@ -62,8 +62,6 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
	if (!(ch->flags & XPC_C_ROPENREPLY))
		return;

	DBUG_ON(ch->remote_msgqueue_pa == 0);

	ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP);	/* clear all else */

	dev_info(xpc_chan, "channel %d to partition %d connected\n",
@@ -134,13 +132,23 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
		spin_lock_irqsave(&ch->lock, *irq_flags);
	}

	DBUG_ON(atomic_read(&ch->n_to_notify) != 0);

	/* it's now safe to free the channel's message queues */
	xpc_free_msgqueues(ch);
	xpc_teardown_msg_structures(ch);

	ch->func = NULL;
	ch->key = NULL;
	ch->msg_size = 0;
	ch->local_nentries = 0;
	ch->remote_nentries = 0;
	ch->kthreads_assigned_limit = 0;
	ch->kthreads_idle_limit = 0;

	/*
	 * Mark the channel disconnected and clear all other flags, including
	 * XPC_C_SETUP (because of call to xpc_free_msgqueues()) but not
	 * including XPC_C_WDISCONNECT (if it was set).
	 * XPC_C_SETUP (because of call to xpc_teardown_msg_structures()) but
	 * not including XPC_C_WDISCONNECT (if it was set).
	 */
	ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));

@@ -395,7 +403,7 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
		DBUG_ON(args->remote_nentries == 0);

		ch->flags |= XPC_C_ROPENREPLY;
		ch->remote_msgqueue_pa = args->local_msgqueue_pa;
		xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);

		if (args->local_nentries < ch->remote_nentries) {
			dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
+246 −83

File changed.

Preview size limit exceeded, changes collapsed.

Loading