Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sgi-xp: setup the notify GRU message queue

Setup the notify GRU message queue that is used for sending user messages
on UV systems.

Signed-off-by: Dean Nelson <dcn@sgi.com>
Cc: Jack Steiner <steiner@sgi.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Dean Nelson and committed by
Linus Torvalds
bd3e64c1 5b8669df

+1043 -395
+15 -30
drivers/misc/sgi-xp/xp.h
··· 87 87 #endif 88 88 89 89 /* 90 - * The format of an XPC message is as follows: 91 - * 92 - * +-------+--------------------------------+ 93 - * | flags |////////////////////////////////| 94 - * +-------+--------------------------------+ 95 - * | message # | 96 - * +----------------------------------------+ 97 - * | payload (user-defined message) | 98 - * | | 99 - * : 100 - * | | 101 - * +----------------------------------------+ 102 - * 103 - * The size of the payload is defined by the user via xpc_connect(). A user- 104 - * defined message resides in the payload area. 105 - * 106 - * The size of a message entry (within a message queue) must be a cacheline 107 - * sized multiple in order to facilitate the BTE transfer of messages from one 108 - * message queue to another. A macro, XPC_MSG_SIZE(), is provided for the user 90 + * Define macro, XPC_MSG_SIZE(), is provided for the user 109 91 * that wants to fit as many msg entries as possible in a given memory size 110 92 * (e.g. a memory page). 111 93 */ 112 - struct xpc_msg { 113 - u8 flags; /* FOR XPC INTERNAL USE ONLY */ 114 - u8 reserved[7]; /* FOR XPC INTERNAL USE ONLY */ 115 - s64 number; /* FOR XPC INTERNAL USE ONLY */ 94 + #define XPC_MSG_MAX_SIZE 128 95 + #define XPC_MSG_HDR_MAX_SIZE 16 96 + #define XPC_MSG_PAYLOAD_MAX_SIZE (XPC_MSG_MAX_SIZE - XPC_MSG_HDR_MAX_SIZE) 116 97 117 - u64 payload; /* user defined portion of message */ 118 - }; 119 - 120 - #define XPC_MSG_PAYLOAD_OFFSET (u64) (&((struct xpc_msg *)0)->payload) 121 98 #define XPC_MSG_SIZE(_payload_size) \ 122 - L1_CACHE_ALIGN(XPC_MSG_PAYLOAD_OFFSET + (_payload_size)) 99 + ALIGN(XPC_MSG_HDR_MAX_SIZE + (_payload_size), \ 100 + is_uv() ? 64 : 128) 101 + 123 102 124 103 /* 125 104 * Define the return values and values passed to user's callout functions. ··· 189 210 xpGruCopyError, /* 58: gru_copy_gru() returned error */ 190 211 xpGruSendMqError, /* 59: gru send message queue related error */ 191 212 192 - xpUnknownReason /* 60: unknown reason - must be last in enum */ 213 + xpBadChannelNumber, /* 60: invalid channel number */ 214 + xpBadMsgType, /* 60: invalid message type */ 215 + 216 + xpUnknownReason /* 61: unknown reason - must be last in enum */ 193 217 }; 194 218 195 219 /* ··· 243 261 * calling xpc_received(). 244 262 * 245 263 * All other reason codes indicate failure. 264 + * 265 + * NOTE: The user defined function must be callable by an interrupt handler 266 + * and thus cannot block. 246 267 */ 247 268 typedef void (*xpc_notify_func) (enum xp_retval reason, short partid, 248 269 int ch_number, void *key); ··· 269 284 xpc_channel_func func; /* function to call */ 270 285 void *key; /* pointer to user's key */ 271 286 u16 nentries; /* #of msg entries in local msg queue */ 272 - u16 msg_size; /* message queue's message size */ 287 + u16 entry_size; /* message queue's message entry size */ 273 288 u32 assigned_limit; /* limit on #of assigned kthreads */ 274 289 u32 idle_limit; /* limit on #of idle kthreads */ 275 290 } ____cacheline_aligned;
+5 -2
drivers/misc/sgi-xp/xp_main.c
··· 154 154 DBUG_ON(func == NULL); 155 155 DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit); 156 156 157 + if (XPC_MSG_SIZE(payload_size) > XPC_MSG_MAX_SIZE) 158 + return xpPayloadTooBig; 159 + 157 160 registration = &xpc_registrations[ch_number]; 158 161 159 162 if (mutex_lock_interruptible(&registration->mutex) != 0) ··· 169 166 } 170 167 171 168 /* register the channel for connection */ 172 - registration->msg_size = XPC_MSG_SIZE(payload_size); 169 + registration->entry_size = XPC_MSG_SIZE(payload_size); 173 170 registration->nentries = nentries; 174 171 registration->assigned_limit = assigned_limit; 175 172 registration->idle_limit = idle_limit; ··· 223 220 registration->func = NULL; 224 221 registration->key = NULL; 225 222 registration->nentries = 0; 226 - registration->msg_size = 0; 223 + registration->entry_size = 0; 227 224 registration->assigned_limit = 0; 228 225 registration->idle_limit = 0; 229 226
+109 -35
drivers/misc/sgi-xp/xpc.h
··· 181 181 xpc_nasid_mask_nlongs)) 182 182 183 183 /* 184 - * The activate_mq is used to send/receive messages that affect XPC's heartbeat, 185 - * partition active state, and channel state. This is UV only. 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 186 */ 187 187 struct xpc_activate_mq_msghdr_uv { 188 188 short partid; /* sender's partid */ ··· 209 209 #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 11 210 210 211 211 struct xpc_activate_mq_msg_uv { 212 - struct xpc_activate_mq_msghdr_uv header; 212 + struct xpc_activate_mq_msghdr_uv hdr; 213 213 }; 214 214 215 215 struct xpc_activate_mq_msg_heartbeat_req_uv { 216 - struct xpc_activate_mq_msghdr_uv header; 216 + struct xpc_activate_mq_msghdr_uv hdr; 217 217 u64 heartbeat; 218 218 }; 219 219 220 220 struct xpc_activate_mq_msg_activate_req_uv { 221 - struct xpc_activate_mq_msghdr_uv header; 221 + struct xpc_activate_mq_msghdr_uv hdr; 222 222 unsigned long rp_gpa; 223 223 unsigned long activate_mq_gpa; 224 224 }; 225 225 226 226 struct xpc_activate_mq_msg_deactivate_req_uv { 227 - struct xpc_activate_mq_msghdr_uv header; 227 + struct xpc_activate_mq_msghdr_uv hdr; 228 228 enum xp_retval reason; 229 229 }; 230 230 231 231 struct xpc_activate_mq_msg_chctl_closerequest_uv { 232 - struct xpc_activate_mq_msghdr_uv header; 232 + struct xpc_activate_mq_msghdr_uv hdr; 233 233 short ch_number; 234 234 enum xp_retval reason; 235 235 }; 236 236 237 237 struct xpc_activate_mq_msg_chctl_closereply_uv { 238 - struct xpc_activate_mq_msghdr_uv header; 238 + struct xpc_activate_mq_msghdr_uv hdr; 239 239 short ch_number; 240 240 }; 241 241 242 242 struct xpc_activate_mq_msg_chctl_openrequest_uv { 243 - struct xpc_activate_mq_msghdr_uv header; 243 + struct xpc_activate_mq_msghdr_uv hdr; 244 244 short ch_number; 245 - short msg_size; /* size of notify_mq's messages */ 245 + short entry_size; /* size of notify_mq's GRU messages */ 246 246 short local_nentries; /* ??? Is this needed? What is? */ 247 247 }; 248 248 249 249 struct xpc_activate_mq_msg_chctl_openreply_uv { 250 - struct xpc_activate_mq_msghdr_uv header; 250 + struct xpc_activate_mq_msghdr_uv hdr; 251 251 short ch_number; 252 252 short remote_nentries; /* ??? Is this needed? What is? */ 253 253 short local_nentries; /* ??? Is this needed? What is? */ ··· 284 284 */ 285 285 struct xpc_openclose_args { 286 286 u16 reason; /* reason why channel is closing */ 287 - u16 msg_size; /* sizeof each message entry */ 287 + u16 entry_size; /* sizeof each message entry */ 288 288 u16 remote_nentries; /* #of message entries in remote msg queue */ 289 289 u16 local_nentries; /* #of message entries in local msg queue */ 290 290 unsigned long local_msgqueue_pa; /* phys addr of local message queue */ ··· 294 294 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \ 295 295 XPC_MAX_NCHANNELS) 296 296 297 - /* struct xpc_msg flags */ 298 - 299 - #define XPC_M_DONE 0x01 /* msg has been received/consumed */ 300 - #define XPC_M_READY 0x02 /* msg is ready to be sent */ 301 - #define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */ 302 - 303 - #define XPC_MSG_ADDRESS(_payload) \ 304 - ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET)) 305 297 306 298 /* 307 - * Defines notify entry. 299 + * Structures to define a fifo singly-linked list. 300 + */ 301 + 302 + struct xpc_fifo_entry_uv { 303 + struct xpc_fifo_entry_uv *next; 304 + }; 305 + 306 + struct 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 + */ 323 + struct 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 + 347 + struct 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 + 358 + struct 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. 308 365 * 309 366 * This is used to notify a message's sender that their message was received 310 367 * and consumed by the intended recipient. 311 368 */ 312 - struct xpc_notify { 369 + struct xpc_notify_sn2 { 313 370 u8 type; /* type of notification */ 314 371 315 372 /* the following two fields are only used if type == XPC_N_CALL */ ··· 374 317 void *key; /* pointer to user's key */ 375 318 }; 376 319 377 - /* struct xpc_notify type of notification */ 320 + /* struct xpc_notify_sn2 type of notification */ 378 321 379 - #define XPC_N_CALL 0x01 /* notify function provided by user */ 322 + #define XPC_N_CALL 0x01 /* notify function provided by user */ 323 + 324 + /* 325 + * Define uv's version of the notify entry. It additionally is used to allocate 326 + * a msg slot on the remote partition into which is copied a sent message. 327 + */ 328 + struct xpc_send_msg_slot_uv { 329 + struct xpc_fifo_entry_uv next; 330 + unsigned int msg_slot_number; 331 + xpc_notify_func func; /* user's notify function */ 332 + void *key; /* pointer to user's key */ 333 + }; 380 334 381 335 /* 382 336 * Define the structure that manages all the stuff required by a channel. In ··· 477 409 /* opening or closing of channel */ 478 410 479 411 void *local_msgqueue_base; /* base address of kmalloc'd space */ 480 - struct xpc_msg *local_msgqueue; /* local message queue */ 412 + struct xpc_msg_sn2 *local_msgqueue; /* local message queue */ 481 413 void *remote_msgqueue_base; /* base address of kmalloc'd space */ 482 - struct xpc_msg *remote_msgqueue; /* cached copy of remote partition's */ 483 - /* local message queue */ 414 + struct xpc_msg_sn2 *remote_msgqueue; /* cached copy of remote */ 415 + /* partition's local message queue */ 484 416 unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */ 485 417 /* local message queue */ 486 418 487 - struct xpc_notify *notify_queue; /* notify queue for messages sent */ 419 + struct xpc_notify_sn2 *notify_queue;/* notify queue for messages sent */ 488 420 489 421 /* various flavors of local and remote Get/Put values */ 490 422 ··· 500 432 struct xpc_channel_uv { 501 433 unsigned long remote_notify_mq_gpa; /* gru phys address of remote */ 502 434 /* partition's notify mq */ 435 + 436 + struct xpc_send_msg_slot_uv *send_msg_slots; 437 + struct xpc_notify_mq_msg_uv *recv_msg_slots; 438 + 439 + struct xpc_fifo_head_uv msg_slot_free_list; 440 + struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */ 503 441 }; 504 442 505 443 struct xpc_channel { ··· 518 444 519 445 u16 number; /* channel # */ 520 446 521 - u16 msg_size; /* sizeof each msg entry */ 447 + u16 entry_size; /* sizeof each msg entry */ 522 448 u16 local_nentries; /* #of msg entries in local msg queue */ 523 449 u16 remote_nentries; /* #of msg entries in remote msg queue */ 524 450 ··· 807 733 extern void (*xpc_teardown_msg_structures) (struct xpc_channel *); 808 734 extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *); 809 735 extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int); 810 - extern int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *); 811 - extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *); 736 + extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *); 737 + extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *); 812 738 extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *, 813 739 unsigned long, int); 814 740 extern void (*xpc_request_partition_reactivation) (struct xpc_partition *); ··· 836 762 extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *, 837 763 unsigned long); 838 764 839 - extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16, 840 - u8, xpc_notify_func, void *); 841 - extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *); 765 + extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *, 766 + u16, u8, xpc_notify_func, void *); 767 + extern void (*xpc_received_payload) (struct xpc_channel *, void *); 842 768 843 769 /* found in xpc_sn2.c */ 844 770 extern int xpc_init_sn2(void); ··· 879 805 extern void xpc_initiate_received(short, int, void *); 880 806 extern void xpc_process_sent_chctl_flags(struct xpc_partition *); 881 807 extern void xpc_connected_callout(struct xpc_channel *); 882 - extern void xpc_deliver_msg(struct xpc_channel *); 808 + extern void xpc_deliver_payload(struct xpc_channel *); 883 809 extern void xpc_disconnect_channel(const int, struct xpc_channel *, 884 810 enum xp_retval, unsigned long *); 885 811 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
+29 -34
drivers/misc/sgi-xp/xpc_channel.c
··· 139 139 140 140 ch->func = NULL; 141 141 ch->key = NULL; 142 - ch->msg_size = 0; 142 + ch->entry_size = 0; 143 143 ch->local_nentries = 0; 144 144 ch->remote_nentries = 0; 145 145 ch->kthreads_assigned_limit = 0; ··· 315 315 316 316 if (chctl_flags & XPC_CHCTL_OPENREQUEST) { 317 317 318 - dev_dbg(xpc_chan, "XPC_CHCTL_OPENREQUEST (msg_size=%d, " 318 + dev_dbg(xpc_chan, "XPC_CHCTL_OPENREQUEST (entry_size=%d, " 319 319 "local_nentries=%d) received from partid=%d, " 320 - "channel=%d\n", args->msg_size, args->local_nentries, 320 + "channel=%d\n", args->entry_size, args->local_nentries, 321 321 ch->partid, ch->number); 322 322 323 323 if (part->act_state == XPC_P_AS_DEACTIVATING || ··· 338 338 339 339 /* 340 340 * The meaningful OPENREQUEST connection state fields are: 341 - * msg_size = size of channel's messages in bytes 341 + * entry_size = size of channel's messages in bytes 342 342 * local_nentries = remote partition's local_nentries 343 343 */ 344 - if (args->msg_size == 0 || args->local_nentries == 0) { 344 + if (args->entry_size == 0 || args->local_nentries == 0) { 345 345 /* assume OPENREQUEST was delayed by mistake */ 346 346 spin_unlock_irqrestore(&ch->lock, irq_flags); 347 347 return; ··· 351 351 ch->remote_nentries = args->local_nentries; 352 352 353 353 if (ch->flags & XPC_C_OPENREQUEST) { 354 - if (args->msg_size != ch->msg_size) { 354 + if (args->entry_size != ch->entry_size) { 355 355 XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes, 356 356 &irq_flags); 357 357 spin_unlock_irqrestore(&ch->lock, irq_flags); 358 358 return; 359 359 } 360 360 } else { 361 - ch->msg_size = args->msg_size; 361 + ch->entry_size = args->entry_size; 362 362 363 363 XPC_SET_REASON(ch, 0, 0); 364 364 ch->flags &= ~XPC_C_DISCONNECTED; ··· 473 473 ch->local_nentries = registration->nentries; 474 474 475 475 if (ch->flags & XPC_C_ROPENREQUEST) { 476 - if (registration->msg_size != ch->msg_size) { 476 + if (registration->entry_size != ch->entry_size) { 477 477 /* the local and remote sides aren't the same */ 478 478 479 479 /* ··· 492 492 return xpUnequalMsgSizes; 493 493 } 494 494 } else { 495 - ch->msg_size = registration->msg_size; 495 + ch->entry_size = registration->entry_size; 496 496 497 497 XPC_SET_REASON(ch, 0, 0); 498 498 ch->flags &= ~XPC_C_DISCONNECTED; ··· 859 859 DBUG_ON(payload == NULL); 860 860 861 861 if (xpc_part_ref(part)) { 862 - ret = xpc_send_msg(&part->channels[ch_number], flags, payload, 863 - payload_size, 0, NULL, NULL); 862 + ret = xpc_send_payload(&part->channels[ch_number], flags, 863 + payload, payload_size, 0, NULL, NULL); 864 864 xpc_part_deref(part); 865 865 } 866 866 ··· 911 911 DBUG_ON(func == NULL); 912 912 913 913 if (xpc_part_ref(part)) { 914 - ret = xpc_send_msg(&part->channels[ch_number], flags, payload, 915 - payload_size, XPC_N_CALL, func, key); 914 + ret = xpc_send_payload(&part->channels[ch_number], flags, 915 + payload, payload_size, XPC_N_CALL, func, 916 + key); 916 917 xpc_part_deref(part); 917 918 } 918 919 return ret; 919 920 } 920 921 921 922 /* 922 - * Deliver a message to its intended recipient. 923 + * Deliver a message's payload to its intended recipient. 923 924 */ 924 925 void 925 - xpc_deliver_msg(struct xpc_channel *ch) 926 + xpc_deliver_payload(struct xpc_channel *ch) 926 927 { 927 - struct xpc_msg *msg; 928 + void *payload; 928 929 929 - msg = xpc_get_deliverable_msg(ch); 930 - if (msg != NULL) { 930 + payload = xpc_get_deliverable_payload(ch); 931 + if (payload != NULL) { 931 932 932 933 /* 933 934 * This ref is taken to protect the payload itself from being ··· 940 939 atomic_inc(&ch->kthreads_active); 941 940 942 941 if (ch->func != NULL) { 943 - dev_dbg(xpc_chan, "ch->func() called, msg=0x%p, " 944 - "msg_number=%ld, partid=%d, channel=%d\n", 945 - msg, (signed long)msg->number, ch->partid, 942 + dev_dbg(xpc_chan, "ch->func() called, payload=0x%p " 943 + "partid=%d channel=%d\n", payload, ch->partid, 946 944 ch->number); 947 945 948 946 /* deliver the message to its intended recipient */ 949 - ch->func(xpMsgReceived, ch->partid, ch->number, 950 - &msg->payload, ch->key); 947 + ch->func(xpMsgReceived, ch->partid, ch->number, payload, 948 + ch->key); 951 949 952 - dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, " 953 - "msg_number=%ld, partid=%d, channel=%d\n", 954 - msg, (signed long)msg->number, ch->partid, 950 + dev_dbg(xpc_chan, "ch->func() returned, payload=0x%p " 951 + "partid=%d channel=%d\n", payload, ch->partid, 955 952 ch->number); 956 953 } 957 954 ··· 958 959 } 959 960 960 961 /* 961 - * Acknowledge receipt of a delivered message. 962 - * 963 - * If a message has XPC_M_INTERRUPT set, send an interrupt to the partition 964 - * that sent the message. 962 + * Acknowledge receipt of a delivered message's payload. 965 963 * 966 964 * This function, although called by users, does not call xpc_part_ref() to 967 965 * ensure that the partition infrastructure is in place. It relies on the 968 - * fact that we called xpc_msgqueue_ref() in xpc_deliver_msg(). 966 + * fact that we called xpc_msgqueue_ref() in xpc_deliver_payload(). 969 967 * 970 968 * Arguments: 971 969 * ··· 976 980 { 977 981 struct xpc_partition *part = &xpc_partitions[partid]; 978 982 struct xpc_channel *ch; 979 - struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); 980 983 981 984 DBUG_ON(partid < 0 || partid >= xp_max_npartitions); 982 985 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); 983 986 984 987 ch = &part->channels[ch_number]; 985 - xpc_received_msg(ch, msg); 988 + xpc_received_payload(ch, payload); 986 989 987 - /* the call to xpc_msgqueue_ref() was done by xpc_deliver_msg() */ 990 + /* the call to xpc_msgqueue_ref() was done by xpc_deliver_payload() */ 988 991 xpc_msgqueue_deref(ch); 989 992 }
+11 -10
drivers/misc/sgi-xp/xpc_main.c
··· 188 188 enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *ch); 189 189 void (*xpc_teardown_msg_structures) (struct xpc_channel *ch); 190 190 void (*xpc_process_msg_chctl_flags) (struct xpc_partition *part, int ch_number); 191 - int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *ch); 192 - struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch); 191 + int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *ch); 192 + void *(*xpc_get_deliverable_payload) (struct xpc_channel *ch); 193 193 194 194 void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp, 195 195 unsigned long remote_rp_pa, ··· 220 220 void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch, 221 221 unsigned long msgqueue_pa); 222 222 223 - enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, u32 flags, 224 - void *payload, u16 payload_size, u8 notify_type, 225 - xpc_notify_func func, void *key); 226 - void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg); 223 + enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags, 224 + void *payload, u16 payload_size, 225 + u8 notify_type, xpc_notify_func func, 226 + void *key); 227 + void (*xpc_received_payload) (struct xpc_channel *ch, void *payload); 227 228 228 229 /* 229 230 * Timer function to enforce the timelimit on the partition disengage. ··· 715 714 do { 716 715 /* deliver messages to their intended recipients */ 717 716 718 - while (xpc_n_of_deliverable_msgs(ch) > 0 && 717 + while (xpc_n_of_deliverable_payloads(ch) > 0 && 719 718 !(ch->flags & XPC_C_DISCONNECTING)) { 720 - xpc_deliver_msg(ch); 719 + xpc_deliver_payload(ch); 721 720 } 722 721 723 722 if (atomic_inc_return(&ch->kthreads_idle) > ··· 731 730 "wait_event_interruptible_exclusive()\n"); 732 731 733 732 (void)wait_event_interruptible_exclusive(ch->idle_wq, 734 - (xpc_n_of_deliverable_msgs(ch) > 0 || 733 + (xpc_n_of_deliverable_payloads(ch) > 0 || 735 734 (ch->flags & XPC_C_DISCONNECTING))); 736 735 737 736 atomic_dec(&ch->kthreads_idle); ··· 776 775 * additional kthreads to help deliver them. We only 777 776 * need one less than total #of messages to deliver. 778 777 */ 779 - n_needed = xpc_n_of_deliverable_msgs(ch) - 1; 778 + n_needed = xpc_n_of_deliverable_payloads(ch) - 1; 780 779 if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING)) 781 780 xpc_activate_kthreads(ch, n_needed); 782 781
+96 -82
drivers/misc/sgi-xp/xpc_sn2.c
··· 408 408 { 409 409 struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args; 410 410 411 - args->msg_size = ch->msg_size; 411 + args->entry_size = ch->entry_size; 412 412 args->local_nentries = ch->local_nentries; 413 413 XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENREQUEST, irq_flags); 414 414 } ··· 1531 1531 1532 1532 for (nentries = ch->local_nentries; nentries > 0; nentries--) { 1533 1533 1534 - nbytes = nentries * ch->msg_size; 1534 + nbytes = nentries * ch->entry_size; 1535 1535 ch_sn2->local_msgqueue = 1536 1536 xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL, 1537 1537 &ch_sn2->local_msgqueue_base); 1538 1538 if (ch_sn2->local_msgqueue == NULL) 1539 1539 continue; 1540 1540 1541 - nbytes = nentries * sizeof(struct xpc_notify); 1541 + nbytes = nentries * sizeof(struct xpc_notify_sn2); 1542 1542 ch_sn2->notify_queue = kzalloc(nbytes, GFP_KERNEL); 1543 1543 if (ch_sn2->notify_queue == NULL) { 1544 1544 kfree(ch_sn2->local_msgqueue_base); ··· 1578 1578 1579 1579 for (nentries = ch->remote_nentries; nentries > 0; nentries--) { 1580 1580 1581 - nbytes = nentries * ch->msg_size; 1581 + nbytes = nentries * ch->entry_size; 1582 1582 ch_sn2->remote_msgqueue = 1583 1583 xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL, &ch_sn2-> 1584 1584 remote_msgqueue_base); ··· 1632 1632 /* 1633 1633 * Free up message queues and other stuff that were allocated for the specified 1634 1634 * channel. 1635 - * 1636 - * Note: ch->reason and ch->reason_line are left set for debugging purposes, 1637 - * they're cleared when XPC_C_DISCONNECTED is cleared. 1638 1635 */ 1639 1636 static void 1640 1637 xpc_teardown_msg_structures_sn2(struct xpc_channel *ch) ··· 1671 1674 static void 1672 1675 xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put) 1673 1676 { 1674 - struct xpc_notify *notify; 1677 + struct xpc_notify_sn2 *notify; 1675 1678 u8 notify_type; 1676 1679 s64 get = ch->sn.sn2.w_remote_GP.get - 1; 1677 1680 ··· 1696 1699 atomic_dec(&ch->n_to_notify); 1697 1700 1698 1701 if (notify->func != NULL) { 1699 - dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, " 1700 - "msg_number=%ld, partid=%d, channel=%d\n", 1702 + dev_dbg(xpc_chan, "notify->func() called, notify=0x%p " 1703 + "msg_number=%ld partid=%d channel=%d\n", 1701 1704 (void *)notify, get, ch->partid, ch->number); 1702 1705 1703 1706 notify->func(reason, ch->partid, ch->number, 1704 1707 notify->key); 1705 1708 1706 - dev_dbg(xpc_chan, "notify->func() returned, " 1707 - "notify=0x%p, msg_number=%ld, partid=%d, " 1708 - "channel=%d\n", (void *)notify, get, 1709 - ch->partid, ch->number); 1709 + dev_dbg(xpc_chan, "notify->func() returned, notify=0x%p" 1710 + " msg_number=%ld partid=%d channel=%d\n", 1711 + (void *)notify, get, ch->partid, ch->number); 1710 1712 } 1711 1713 } 1712 1714 } ··· 1723 1727 xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch) 1724 1728 { 1725 1729 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1726 - struct xpc_msg *msg; 1730 + struct xpc_msg_sn2 *msg; 1727 1731 s64 get; 1728 1732 1729 1733 get = ch_sn2->w_remote_GP.get; 1730 1734 do { 1731 - msg = (struct xpc_msg *)((u64)ch_sn2->local_msgqueue + 1732 - (get % ch->local_nentries) * 1733 - ch->msg_size); 1735 + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue + 1736 + (get % ch->local_nentries) * 1737 + ch->entry_size); 1734 1738 msg->flags = 0; 1735 1739 } while (++get < ch_sn2->remote_GP.get); 1736 1740 } ··· 1742 1746 xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch) 1743 1747 { 1744 1748 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1745 - struct xpc_msg *msg; 1749 + struct xpc_msg_sn2 *msg; 1746 1750 s64 put; 1747 1751 1748 1752 put = ch_sn2->w_remote_GP.put; 1749 1753 do { 1750 - msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + 1751 - (put % ch->remote_nentries) * 1752 - ch->msg_size); 1754 + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + 1755 + (put % ch->remote_nentries) * 1756 + ch->entry_size); 1753 1757 msg->flags = 0; 1754 1758 } while (++put < ch_sn2->remote_GP.put); 1759 + } 1760 + 1761 + static int 1762 + xpc_n_of_deliverable_payloads_sn2(struct xpc_channel *ch) 1763 + { 1764 + return ch->sn.sn2.w_remote_GP.put - ch->sn.sn2.w_local_GP.get; 1755 1765 } 1756 1766 1757 1767 static void ··· 1765 1763 { 1766 1764 struct xpc_channel *ch = &part->channels[ch_number]; 1767 1765 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1768 - int nmsgs_sent; 1766 + int npayloads_sent; 1769 1767 1770 1768 ch_sn2->remote_GP = part->sn.sn2.remote_GPs[ch_number]; 1771 1769 ··· 1837 1835 if (ch_sn2->w_remote_GP.put != ch_sn2->remote_GP.put) { 1838 1836 /* 1839 1837 * Clear msg->flags in previously received messages, so that 1840 - * they're ready for xpc_get_deliverable_msg(). 1838 + * they're ready for xpc_get_deliverable_payload_sn2(). 1841 1839 */ 1842 1840 xpc_clear_remote_msgqueue_flags_sn2(ch); 1843 1841 ··· 1847 1845 "channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid, 1848 1846 ch->number); 1849 1847 1850 - nmsgs_sent = ch_sn2->w_remote_GP.put - ch_sn2->w_local_GP.get; 1851 - if (nmsgs_sent > 0) { 1848 + npayloads_sent = xpc_n_of_deliverable_payloads_sn2(ch); 1849 + if (npayloads_sent > 0) { 1852 1850 dev_dbg(xpc_chan, "msgs waiting to be copied and " 1853 1851 "delivered=%d, partid=%d, channel=%d\n", 1854 - nmsgs_sent, ch->partid, ch->number); 1852 + npayloads_sent, ch->partid, ch->number); 1855 1853 1856 1854 if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) 1857 - xpc_activate_kthreads(ch, nmsgs_sent); 1855 + xpc_activate_kthreads(ch, npayloads_sent); 1858 1856 } 1859 1857 } 1860 1858 1861 1859 xpc_msgqueue_deref(ch); 1862 1860 } 1863 1861 1864 - static struct xpc_msg * 1862 + static struct xpc_msg_sn2 * 1865 1863 xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get) 1866 1864 { 1867 1865 struct xpc_partition *part = &xpc_partitions[ch->partid]; 1868 1866 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1869 1867 unsigned long remote_msg_pa; 1870 - struct xpc_msg *msg; 1868 + struct xpc_msg_sn2 *msg; 1871 1869 u32 msg_index; 1872 1870 u32 nmsgs; 1873 1871 u64 msg_offset; ··· 1891 1889 nmsgs = ch->remote_nentries - msg_index; 1892 1890 } 1893 1891 1894 - msg_offset = msg_index * ch->msg_size; 1895 - msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + 1892 + msg_offset = msg_index * ch->entry_size; 1893 + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + 1896 1894 msg_offset); 1897 1895 remote_msg_pa = ch_sn2->remote_msgqueue_pa + msg_offset; 1898 1896 1899 1897 ret = xpc_pull_remote_cachelines_sn2(part, msg, remote_msg_pa, 1900 - nmsgs * ch->msg_size); 1898 + nmsgs * ch->entry_size); 1901 1899 if (ret != xpSuccess) { 1902 1900 1903 1901 dev_dbg(xpc_chan, "failed to pull %d msgs starting with" ··· 1917 1915 mutex_unlock(&ch_sn2->msg_to_pull_mutex); 1918 1916 1919 1917 /* return the message we were looking for */ 1920 - msg_offset = (get % ch->remote_nentries) * ch->msg_size; 1921 - msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + msg_offset); 1918 + msg_offset = (get % ch->remote_nentries) * ch->entry_size; 1919 + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + msg_offset); 1922 1920 1923 1921 return msg; 1924 1922 } 1925 1923 1926 - static int 1927 - xpc_n_of_deliverable_msgs_sn2(struct xpc_channel *ch) 1928 - { 1929 - return ch->sn.sn2.w_remote_GP.put - ch->sn.sn2.w_local_GP.get; 1930 - } 1931 - 1932 1924 /* 1933 - * Get a message to be delivered. 1925 + * Get the next deliverable message's payload. 1934 1926 */ 1935 - static struct xpc_msg * 1936 - xpc_get_deliverable_msg_sn2(struct xpc_channel *ch) 1927 + static void * 1928 + xpc_get_deliverable_payload_sn2(struct xpc_channel *ch) 1937 1929 { 1938 1930 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1939 - struct xpc_msg *msg = NULL; 1931 + struct xpc_msg_sn2 *msg; 1932 + void *payload = NULL; 1940 1933 s64 get; 1941 1934 1942 1935 do { ··· 1962 1965 msg = xpc_pull_remote_msg_sn2(ch, get); 1963 1966 1964 1967 DBUG_ON(msg != NULL && msg->number != get); 1965 - DBUG_ON(msg != NULL && (msg->flags & XPC_M_DONE)); 1966 - DBUG_ON(msg != NULL && !(msg->flags & XPC_M_READY)); 1968 + DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE)); 1969 + DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY)); 1967 1970 1971 + payload = &msg->payload; 1968 1972 break; 1969 1973 } 1970 1974 1971 1975 } while (1); 1972 1976 1973 - return msg; 1977 + return payload; 1974 1978 } 1975 1979 1976 1980 /* ··· 1983 1985 xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put) 1984 1986 { 1985 1987 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 1986 - struct xpc_msg *msg; 1988 + struct xpc_msg_sn2 *msg; 1987 1989 s64 put = initial_put + 1; 1988 1990 int send_msgrequest = 0; 1989 1991 ··· 1993 1995 if (put == ch_sn2->w_local_GP.put) 1994 1996 break; 1995 1997 1996 - msg = (struct xpc_msg *)((u64)ch_sn2->local_msgqueue + 1997 - (put % ch->local_nentries) * 1998 - ch->msg_size); 1998 + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2-> 1999 + local_msgqueue + (put % 2000 + ch->local_nentries) * 2001 + ch->entry_size); 1999 2002 2000 - if (!(msg->flags & XPC_M_READY)) 2003 + if (!(msg->flags & XPC_M_SN2_READY)) 2001 2004 break; 2002 2005 2003 2006 put++; ··· 2025 2026 2026 2027 /* 2027 2028 * We need to ensure that the message referenced by 2028 - * local_GP->put is not XPC_M_READY or that local_GP->put 2029 + * local_GP->put is not XPC_M_SN2_READY or that local_GP->put 2029 2030 * equals w_local_GP.put, so we'll go have a look. 2030 2031 */ 2031 2032 initial_put = put; ··· 2041 2042 */ 2042 2043 static enum xp_retval 2043 2044 xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags, 2044 - struct xpc_msg **address_of_msg) 2045 + struct xpc_msg_sn2 **address_of_msg) 2045 2046 { 2046 2047 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 2047 - struct xpc_msg *msg; 2048 + struct xpc_msg_sn2 *msg; 2048 2049 enum xp_retval ret; 2049 2050 s64 put; 2050 2051 ··· 2096 2097 } 2097 2098 2098 2099 /* get the message's address and initialize it */ 2099 - msg = (struct xpc_msg *)((u64)ch_sn2->local_msgqueue + 2100 - (put % ch->local_nentries) * ch->msg_size); 2100 + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue + 2101 + (put % ch->local_nentries) * 2102 + ch->entry_size); 2101 2103 2102 2104 DBUG_ON(msg->flags != 0); 2103 2105 msg->number = put; ··· 2117 2117 * partition the message is being sent to. 2118 2118 */ 2119 2119 static enum xp_retval 2120 - xpc_send_msg_sn2(struct xpc_channel *ch, u32 flags, void *payload, 2121 - u16 payload_size, u8 notify_type, xpc_notify_func func, 2122 - void *key) 2120 + xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload, 2121 + u16 payload_size, u8 notify_type, xpc_notify_func func, 2122 + void *key) 2123 2123 { 2124 2124 enum xp_retval ret = xpSuccess; 2125 2125 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 2126 - struct xpc_msg *msg = msg; 2127 - struct xpc_notify *notify = notify; 2126 + struct xpc_msg_sn2 *msg = msg; 2127 + struct xpc_notify_sn2 *notify = notify; 2128 2128 s64 msg_number; 2129 2129 s64 put; 2130 2130 2131 2131 DBUG_ON(notify_type == XPC_N_CALL && func == NULL); 2132 2132 2133 - if (XPC_MSG_SIZE(payload_size) > ch->msg_size) 2133 + if (XPC_MSG_SIZE(payload_size) > ch->entry_size) 2134 2134 return xpPayloadTooBig; 2135 2135 2136 2136 xpc_msgqueue_ref(ch); ··· 2155 2155 * Tell the remote side to send an ACK interrupt when the 2156 2156 * message has been delivered. 2157 2157 */ 2158 - msg->flags |= XPC_M_INTERRUPT; 2158 + msg->flags |= XPC_M_SN2_INTERRUPT; 2159 2159 2160 2160 atomic_inc(&ch->n_to_notify); 2161 2161 ··· 2185 2185 2186 2186 memcpy(&msg->payload, payload, payload_size); 2187 2187 2188 - msg->flags |= XPC_M_READY; 2188 + msg->flags |= XPC_M_SN2_READY; 2189 2189 2190 2190 /* 2191 2191 * The preceding store of msg->flags must occur before the following ··· 2208 2208 * Now we actually acknowledge the messages that have been delivered and ack'd 2209 2209 * by advancing the cached remote message queue's Get value and if requested 2210 2210 * send a chctl msgrequest to the message sender's partition. 2211 + * 2212 + * If a message has XPC_M_SN2_INTERRUPT set, send an interrupt to the partition 2213 + * that sent the message. 2211 2214 */ 2212 2215 static void 2213 2216 xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags) 2214 2217 { 2215 2218 struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2; 2216 - struct xpc_msg *msg; 2219 + struct xpc_msg_sn2 *msg; 2217 2220 s64 get = initial_get + 1; 2218 2221 int send_msgrequest = 0; 2219 2222 ··· 2226 2223 if (get == ch_sn2->w_local_GP.get) 2227 2224 break; 2228 2225 2229 - msg = (struct xpc_msg *)((u64)ch_sn2->remote_msgqueue + 2230 - (get % ch->remote_nentries) * 2231 - ch->msg_size); 2226 + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2-> 2227 + remote_msgqueue + (get % 2228 + ch->remote_nentries) * 2229 + ch->entry_size); 2232 2230 2233 - if (!(msg->flags & XPC_M_DONE)) 2231 + if (!(msg->flags & XPC_M_SN2_DONE)) 2234 2232 break; 2235 2233 2236 2234 msg_flags |= msg->flags; ··· 2255 2251 dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, " 2256 2252 "channel=%d\n", get, ch->partid, ch->number); 2257 2253 2258 - send_msgrequest = (msg_flags & XPC_M_INTERRUPT); 2254 + send_msgrequest = (msg_flags & XPC_M_SN2_INTERRUPT); 2259 2255 2260 2256 /* 2261 2257 * We need to ensure that the message referenced by 2262 - * local_GP->get is not XPC_M_DONE or that local_GP->get 2258 + * local_GP->get is not XPC_M_SN2_DONE or that local_GP->get 2263 2259 * equals w_local_GP.get, so we'll go have a look. 2264 2260 */ 2265 2261 initial_get = get; ··· 2270 2266 } 2271 2267 2272 2268 static void 2273 - xpc_received_msg_sn2(struct xpc_channel *ch, struct xpc_msg *msg) 2269 + xpc_received_payload_sn2(struct xpc_channel *ch, void *payload) 2274 2270 { 2271 + struct xpc_msg_sn2 *msg; 2272 + s64 msg_number; 2275 2273 s64 get; 2276 - s64 msg_number = msg->number; 2274 + 2275 + msg = container_of(payload, struct xpc_msg_sn2, payload); 2276 + msg_number = msg->number; 2277 2277 2278 2278 dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n", 2279 2279 (void *)msg, msg_number, ch->partid, ch->number); 2280 2280 2281 - DBUG_ON((((u64)msg - (u64)ch->remote_msgqueue) / ch->msg_size) != 2281 + DBUG_ON((((u64)msg - (u64)ch->remote_msgqueue) / ch->entry_size) != 2282 2282 msg_number % ch->remote_nentries); 2283 - DBUG_ON(msg->flags & XPC_M_DONE); 2283 + DBUG_ON(msg->flags & XPC_M_SN2_DONE); 2284 2284 2285 - msg->flags |= XPC_M_DONE; 2285 + msg->flags |= XPC_M_SN2_DONE; 2286 2286 2287 2287 /* 2288 2288 * The preceding store of msg->flags must occur before the following ··· 2345 2337 2346 2338 xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2; 2347 2339 xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2; 2348 - xpc_n_of_deliverable_msgs = xpc_n_of_deliverable_msgs_sn2; 2349 - xpc_get_deliverable_msg = xpc_get_deliverable_msg_sn2; 2340 + xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2; 2341 + xpc_get_deliverable_payload = xpc_get_deliverable_payload_sn2; 2350 2342 2351 2343 xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2; 2352 2344 xpc_indicate_partition_disengaged = ··· 2355 2347 xpc_any_partition_engaged = xpc_any_partition_engaged_sn2; 2356 2348 xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2; 2357 2349 2358 - xpc_send_msg = xpc_send_msg_sn2; 2359 - xpc_received_msg = xpc_received_msg_sn2; 2350 + xpc_send_payload = xpc_send_payload_sn2; 2351 + xpc_received_payload = xpc_received_payload_sn2; 2352 + 2353 + if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) { 2354 + dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is " 2355 + "larger than %d\n", XPC_MSG_HDR_MAX_SIZE); 2356 + return -E2BIG; 2357 + } 2360 2358 2361 2359 buf_size = max(XPC_RP_VARS_SIZE, 2362 2360 XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2);
+772 -197
drivers/misc/sgi-xp/xpc_uv.c
··· 66 66 mq_order = get_order(mq_size); 67 67 page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, 68 68 mq_order); 69 - if (page == NULL) 69 + if (page == NULL) { 70 + dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " 71 + "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); 70 72 return NULL; 73 + } 71 74 72 75 mq = page_address(page); 73 76 ret = gru_create_message_queue(mq, mq_size); ··· 196 193 197 194 } 198 195 196 + static void 197 + xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, 198 + struct xpc_activate_mq_msghdr_uv *msg_hdr, 199 + int *wakeup_hb_checker) 200 + { 201 + unsigned long irq_flags; 202 + struct xpc_partition_uv *part_uv = &part->sn.uv; 203 + struct xpc_openclose_args *args; 204 + 205 + part_uv->remote_act_state = msg_hdr->act_state; 206 + 207 + switch (msg_hdr->type) { 208 + case XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV: 209 + /* syncing of remote_act_state was just done above */ 210 + break; 211 + 212 + case XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV: { 213 + struct xpc_activate_mq_msg_heartbeat_req_uv *msg; 214 + 215 + msg = container_of(msg_hdr, 216 + struct xpc_activate_mq_msg_heartbeat_req_uv, 217 + hdr); 218 + part_uv->heartbeat = msg->heartbeat; 219 + break; 220 + } 221 + case XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV: { 222 + struct xpc_activate_mq_msg_heartbeat_req_uv *msg; 223 + 224 + msg = container_of(msg_hdr, 225 + struct xpc_activate_mq_msg_heartbeat_req_uv, 226 + hdr); 227 + part_uv->heartbeat = msg->heartbeat; 228 + 229 + spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 230 + part_uv->flags |= XPC_P_HEARTBEAT_OFFLINE_UV; 231 + spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 232 + break; 233 + } 234 + case XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV: { 235 + struct xpc_activate_mq_msg_heartbeat_req_uv *msg; 236 + 237 + msg = container_of(msg_hdr, 238 + struct xpc_activate_mq_msg_heartbeat_req_uv, 239 + hdr); 240 + part_uv->heartbeat = msg->heartbeat; 241 + 242 + spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 243 + part_uv->flags &= ~XPC_P_HEARTBEAT_OFFLINE_UV; 244 + spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 245 + break; 246 + } 247 + case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { 248 + struct xpc_activate_mq_msg_activate_req_uv *msg; 249 + 250 + /* 251 + * ??? Do we deal here with ts_jiffies being different 252 + * ??? if act_state != XPC_P_AS_INACTIVE instead of 253 + * ??? below? 254 + */ 255 + msg = container_of(msg_hdr, struct 256 + xpc_activate_mq_msg_activate_req_uv, hdr); 257 + 258 + spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 259 + if (part_uv->act_state_req == 0) 260 + xpc_activate_IRQ_rcvd++; 261 + part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; 262 + part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ 263 + part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; 264 + part_uv->remote_activate_mq_gpa = msg->activate_mq_gpa; 265 + spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 266 + 267 + (*wakeup_hb_checker)++; 268 + break; 269 + } 270 + case XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV: { 271 + struct xpc_activate_mq_msg_deactivate_req_uv *msg; 272 + 273 + msg = container_of(msg_hdr, struct 274 + xpc_activate_mq_msg_deactivate_req_uv, hdr); 275 + 276 + spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 277 + if (part_uv->act_state_req == 0) 278 + xpc_activate_IRQ_rcvd++; 279 + part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 280 + part_uv->reason = msg->reason; 281 + spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 282 + 283 + (*wakeup_hb_checker)++; 284 + return; 285 + } 286 + case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { 287 + struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; 288 + 289 + msg = container_of(msg_hdr, struct 290 + xpc_activate_mq_msg_chctl_closerequest_uv, 291 + hdr); 292 + args = &part->remote_openclose_args[msg->ch_number]; 293 + args->reason = msg->reason; 294 + 295 + spin_lock_irqsave(&part->chctl_lock, irq_flags); 296 + part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREQUEST; 297 + spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 298 + 299 + xpc_wakeup_channel_mgr(part); 300 + break; 301 + } 302 + case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { 303 + struct xpc_activate_mq_msg_chctl_closereply_uv *msg; 304 + 305 + msg = container_of(msg_hdr, struct 306 + xpc_activate_mq_msg_chctl_closereply_uv, 307 + hdr); 308 + 309 + spin_lock_irqsave(&part->chctl_lock, irq_flags); 310 + part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREPLY; 311 + spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 312 + 313 + xpc_wakeup_channel_mgr(part); 314 + break; 315 + } 316 + case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { 317 + struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; 318 + 319 + msg = container_of(msg_hdr, struct 320 + xpc_activate_mq_msg_chctl_openrequest_uv, 321 + hdr); 322 + args = &part->remote_openclose_args[msg->ch_number]; 323 + args->entry_size = msg->entry_size; 324 + args->local_nentries = msg->local_nentries; 325 + 326 + spin_lock_irqsave(&part->chctl_lock, irq_flags); 327 + part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREQUEST; 328 + spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 329 + 330 + xpc_wakeup_channel_mgr(part); 331 + break; 332 + } 333 + case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { 334 + struct xpc_activate_mq_msg_chctl_openreply_uv *msg; 335 + 336 + msg = container_of(msg_hdr, struct 337 + xpc_activate_mq_msg_chctl_openreply_uv, hdr); 338 + args = &part->remote_openclose_args[msg->ch_number]; 339 + args->remote_nentries = msg->remote_nentries; 340 + args->local_nentries = msg->local_nentries; 341 + args->local_msgqueue_pa = msg->local_notify_mq_gpa; 342 + 343 + spin_lock_irqsave(&part->chctl_lock, irq_flags); 344 + part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY; 345 + spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 346 + 347 + xpc_wakeup_channel_mgr(part); 348 + break; 349 + } 350 + case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: 351 + spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 352 + part_uv->flags |= XPC_P_ENGAGED_UV; 353 + spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 354 + break; 355 + 356 + case XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV: 357 + spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 358 + part_uv->flags &= ~XPC_P_ENGAGED_UV; 359 + spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 360 + break; 361 + 362 + default: 363 + dev_err(xpc_part, "received unknown activate_mq msg type=%d " 364 + "from partition=%d\n", msg_hdr->type, XPC_PARTID(part)); 365 + 366 + /* get hb checker to deactivate from the remote partition */ 367 + spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 368 + if (part_uv->act_state_req == 0) 369 + xpc_activate_IRQ_rcvd++; 370 + part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 371 + part_uv->reason = xpBadMsgType; 372 + spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 373 + 374 + (*wakeup_hb_checker)++; 375 + return; 376 + } 377 + 378 + if (msg_hdr->rp_ts_jiffies != part->remote_rp_ts_jiffies && 379 + part->remote_rp_ts_jiffies != 0) { 380 + /* 381 + * ??? Does what we do here need to be sensitive to 382 + * ??? act_state or remote_act_state? 383 + */ 384 + spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 385 + if (part_uv->act_state_req == 0) 386 + xpc_activate_IRQ_rcvd++; 387 + part_uv->act_state_req = XPC_P_ASR_REACTIVATE_UV; 388 + spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 389 + 390 + (*wakeup_hb_checker)++; 391 + } 392 + } 393 + 199 394 static irqreturn_t 200 395 xpc_handle_activate_IRQ_uv(int irq, void *dev_id) 201 396 { 202 - unsigned long irq_flags; 203 397 struct xpc_activate_mq_msghdr_uv *msg_hdr; 204 398 short partid; 205 399 struct xpc_partition *part; 206 - struct xpc_partition_uv *part_uv; 207 - struct xpc_openclose_args *args; 208 400 int wakeup_hb_checker = 0; 209 401 210 402 while ((msg_hdr = gru_get_next_message(xpc_activate_mq_uv)) != NULL) { 211 403 212 404 partid = msg_hdr->partid; 213 405 if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { 214 - dev_err(xpc_part, "xpc_handle_activate_IRQ_uv() invalid" 215 - "partid=0x%x passed in message\n", partid); 216 - gru_free_message(xpc_activate_mq_uv, msg_hdr); 217 - continue; 218 - } 219 - part = &xpc_partitions[partid]; 220 - part_uv = &part->sn.uv; 221 - 222 - part_uv->remote_act_state = msg_hdr->act_state; 223 - 224 - switch (msg_hdr->type) { 225 - case XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV: 226 - /* syncing of remote_act_state was just done above */ 227 - break; 228 - 229 - case XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV: { 230 - struct xpc_activate_mq_msg_heartbeat_req_uv *msg; 231 - 232 - msg = (struct xpc_activate_mq_msg_heartbeat_req_uv *) 233 - msg_hdr; 234 - part_uv->heartbeat = msg->heartbeat; 235 - break; 236 - } 237 - case XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV: { 238 - struct xpc_activate_mq_msg_heartbeat_req_uv *msg; 239 - 240 - msg = (struct xpc_activate_mq_msg_heartbeat_req_uv *) 241 - msg_hdr; 242 - part_uv->heartbeat = msg->heartbeat; 243 - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 244 - part_uv->flags |= XPC_P_HEARTBEAT_OFFLINE_UV; 245 - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 246 - break; 247 - } 248 - case XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV: { 249 - struct xpc_activate_mq_msg_heartbeat_req_uv *msg; 250 - 251 - msg = (struct xpc_activate_mq_msg_heartbeat_req_uv *) 252 - msg_hdr; 253 - part_uv->heartbeat = msg->heartbeat; 254 - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 255 - part_uv->flags &= ~XPC_P_HEARTBEAT_OFFLINE_UV; 256 - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 257 - break; 258 - } 259 - case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { 260 - struct xpc_activate_mq_msg_activate_req_uv *msg; 261 - 262 - /* 263 - * ??? Do we deal here with ts_jiffies being different 264 - * ??? if act_state != XPC_P_AS_INACTIVE instead of 265 - * ??? below? 266 - */ 267 - msg = (struct xpc_activate_mq_msg_activate_req_uv *) 268 - msg_hdr; 269 - spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, 270 - irq_flags); 271 - if (part_uv->act_state_req == 0) 272 - xpc_activate_IRQ_rcvd++; 273 - part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; 274 - part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ 275 - part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; 276 - part_uv->remote_activate_mq_gpa = msg->activate_mq_gpa; 277 - spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, 278 - irq_flags); 279 - wakeup_hb_checker++; 280 - break; 281 - } 282 - case XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV: { 283 - struct xpc_activate_mq_msg_deactivate_req_uv *msg; 284 - 285 - msg = (struct xpc_activate_mq_msg_deactivate_req_uv *) 286 - msg_hdr; 287 - spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, 288 - irq_flags); 289 - if (part_uv->act_state_req == 0) 290 - xpc_activate_IRQ_rcvd++; 291 - part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 292 - part_uv->reason = msg->reason; 293 - spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, 294 - irq_flags); 295 - wakeup_hb_checker++; 296 - break; 297 - } 298 - case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { 299 - struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; 300 - 301 - msg = (struct xpc_activate_mq_msg_chctl_closerequest_uv 302 - *)msg_hdr; 303 - args = &part->remote_openclose_args[msg->ch_number]; 304 - args->reason = msg->reason; 305 - 306 - spin_lock_irqsave(&part->chctl_lock, irq_flags); 307 - part->chctl.flags[msg->ch_number] |= 308 - XPC_CHCTL_CLOSEREQUEST; 309 - spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 310 - 311 - xpc_wakeup_channel_mgr(part); 312 - break; 313 - } 314 - case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { 315 - struct xpc_activate_mq_msg_chctl_closereply_uv *msg; 316 - 317 - msg = (struct xpc_activate_mq_msg_chctl_closereply_uv *) 318 - msg_hdr; 319 - 320 - spin_lock_irqsave(&part->chctl_lock, irq_flags); 321 - part->chctl.flags[msg->ch_number] |= 322 - XPC_CHCTL_CLOSEREPLY; 323 - spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 324 - 325 - xpc_wakeup_channel_mgr(part); 326 - break; 327 - } 328 - case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { 329 - struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; 330 - 331 - msg = (struct xpc_activate_mq_msg_chctl_openrequest_uv 332 - *)msg_hdr; 333 - args = &part->remote_openclose_args[msg->ch_number]; 334 - args->msg_size = msg->msg_size; 335 - args->local_nentries = msg->local_nentries; 336 - 337 - spin_lock_irqsave(&part->chctl_lock, irq_flags); 338 - part->chctl.flags[msg->ch_number] |= 339 - XPC_CHCTL_OPENREQUEST; 340 - spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 341 - 342 - xpc_wakeup_channel_mgr(part); 343 - break; 344 - } 345 - case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { 346 - struct xpc_activate_mq_msg_chctl_openreply_uv *msg; 347 - 348 - msg = (struct xpc_activate_mq_msg_chctl_openreply_uv *) 349 - msg_hdr; 350 - args = &part->remote_openclose_args[msg->ch_number]; 351 - args->remote_nentries = msg->remote_nentries; 352 - args->local_nentries = msg->local_nentries; 353 - args->local_msgqueue_pa = msg->local_notify_mq_gpa; 354 - 355 - spin_lock_irqsave(&part->chctl_lock, irq_flags); 356 - part->chctl.flags[msg->ch_number] |= 357 - XPC_CHCTL_OPENREPLY; 358 - spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 359 - 360 - xpc_wakeup_channel_mgr(part); 361 - break; 362 - } 363 - case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: 364 - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 365 - part_uv->flags |= XPC_P_ENGAGED_UV; 366 - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 367 - break; 368 - 369 - case XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV: 370 - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); 371 - part_uv->flags &= ~XPC_P_ENGAGED_UV; 372 - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); 373 - break; 374 - 375 - default: 376 - dev_err(xpc_part, "received unknown activate_mq msg " 377 - "type=%d from partition=%d\n", msg_hdr->type, 406 + dev_err(xpc_part, "xpc_handle_activate_IRQ_uv() " 407 + "received invalid partid=0x%x in message\n", 378 408 partid); 379 - } 380 - 381 - if (msg_hdr->rp_ts_jiffies != part->remote_rp_ts_jiffies && 382 - part->remote_rp_ts_jiffies != 0) { 383 - /* 384 - * ??? Does what we do here need to be sensitive to 385 - * ??? act_state or remote_act_state? 386 - */ 387 - spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, 388 - irq_flags); 389 - if (part_uv->act_state_req == 0) 390 - xpc_activate_IRQ_rcvd++; 391 - part_uv->act_state_req = XPC_P_ASR_REACTIVATE_UV; 392 - spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, 393 - irq_flags); 394 - wakeup_hb_checker++; 409 + } else { 410 + part = &xpc_partitions[partid]; 411 + if (xpc_part_ref(part)) { 412 + xpc_handle_activate_mq_msg_uv(part, msg_hdr, 413 + &wakeup_hb_checker); 414 + xpc_part_deref(part); 415 + } 395 416 } 396 417 397 418 gru_free_message(xpc_activate_mq_uv, msg_hdr); ··· 643 616 } 644 617 } 645 618 619 + static void 620 + xpc_cancel_partition_deactivation_request_uv(struct xpc_partition *part) 621 + { 622 + /* nothing needs to be done */ 623 + return; 624 + } 625 + 626 + static void 627 + xpc_init_fifo_uv(struct xpc_fifo_head_uv *head) 628 + { 629 + head->first = NULL; 630 + head->last = NULL; 631 + spin_lock_init(&head->lock); 632 + head->n_entries = 0; 633 + } 634 + 635 + static void * 636 + xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head) 637 + { 638 + unsigned long irq_flags; 639 + struct xpc_fifo_entry_uv *first; 640 + 641 + spin_lock_irqsave(&head->lock, irq_flags); 642 + first = head->first; 643 + if (head->first != NULL) { 644 + head->first = first->next; 645 + if (head->first == NULL) 646 + head->last = NULL; 647 + } 648 + head->n_entries++; 649 + spin_unlock_irqrestore(&head->lock, irq_flags); 650 + first->next = NULL; 651 + return first; 652 + } 653 + 654 + static void 655 + xpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head, 656 + struct xpc_fifo_entry_uv *last) 657 + { 658 + unsigned long irq_flags; 659 + 660 + last->next = NULL; 661 + spin_lock_irqsave(&head->lock, irq_flags); 662 + if (head->last != NULL) 663 + head->last->next = last; 664 + else 665 + head->first = last; 666 + head->last = last; 667 + head->n_entries--; 668 + BUG_ON(head->n_entries < 0); 669 + spin_unlock_irqrestore(&head->lock, irq_flags); 670 + } 671 + 672 + static int 673 + xpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head) 674 + { 675 + return head->n_entries; 676 + } 677 + 646 678 /* 647 679 * Setup the channel structures that are uv specific. 648 680 */ 649 681 static enum xp_retval 650 682 xpc_setup_ch_structures_sn_uv(struct xpc_partition *part) 651 683 { 652 - /* !!! this function needs fleshing out */ 653 - return xpUnsupported; 684 + struct xpc_channel_uv *ch_uv; 685 + int ch_number; 686 + 687 + for (ch_number = 0; ch_number < part->nchannels; ch_number++) { 688 + ch_uv = &part->channels[ch_number].sn.uv; 689 + 690 + xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 691 + xpc_init_fifo_uv(&ch_uv->recv_msg_list); 692 + } 693 + 694 + return xpSuccess; 654 695 } 655 696 656 697 /* ··· 727 632 static void 728 633 xpc_teardown_ch_structures_sn_uv(struct xpc_partition *part) 729 634 { 730 - /* !!! this function needs fleshing out */ 635 + /* nothing needs to be done */ 731 636 return; 732 637 } 733 638 ··· 775 680 } 776 681 777 682 static enum xp_retval 778 - xpc_setup_msg_structures_uv(struct xpc_channel *ch) 683 + xpc_allocate_send_msg_slot_uv(struct xpc_channel *ch) 779 684 { 780 - /* !!! this function needs fleshing out */ 781 - return xpUnsupported; 685 + struct xpc_channel_uv *ch_uv = &ch->sn.uv; 686 + struct xpc_send_msg_slot_uv *msg_slot; 687 + unsigned long irq_flags; 688 + int nentries; 689 + int entry; 690 + size_t nbytes; 691 + 692 + for (nentries = ch->local_nentries; nentries > 0; nentries--) { 693 + nbytes = nentries * sizeof(struct xpc_send_msg_slot_uv); 694 + ch_uv->send_msg_slots = kzalloc(nbytes, GFP_KERNEL); 695 + if (ch_uv->send_msg_slots == NULL) 696 + continue; 697 + 698 + for (entry = 0; entry < nentries; entry++) { 699 + msg_slot = &ch_uv->send_msg_slots[entry]; 700 + 701 + msg_slot->msg_slot_number = entry; 702 + xpc_put_fifo_entry_uv(&ch_uv->msg_slot_free_list, 703 + &msg_slot->next); 704 + } 705 + 706 + spin_lock_irqsave(&ch->lock, irq_flags); 707 + if (nentries < ch->local_nentries) 708 + ch->local_nentries = nentries; 709 + spin_unlock_irqrestore(&ch->lock, irq_flags); 710 + return xpSuccess; 711 + } 712 + 713 + return xpNoMemory; 782 714 } 783 715 716 + static enum xp_retval 717 + xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch) 718 + { 719 + struct xpc_channel_uv *ch_uv = &ch->sn.uv; 720 + struct xpc_notify_mq_msg_uv *msg_slot; 721 + unsigned long irq_flags; 722 + int nentries; 723 + int entry; 724 + size_t nbytes; 725 + 726 + for (nentries = ch->remote_nentries; nentries > 0; nentries--) { 727 + nbytes = nentries * ch->entry_size; 728 + ch_uv->recv_msg_slots = kzalloc(nbytes, GFP_KERNEL); 729 + if (ch_uv->recv_msg_slots == NULL) 730 + continue; 731 + 732 + for (entry = 0; entry < nentries; entry++) { 733 + msg_slot = ch_uv->recv_msg_slots + entry * 734 + ch->entry_size; 735 + 736 + msg_slot->hdr.msg_slot_number = entry; 737 + } 738 + 739 + spin_lock_irqsave(&ch->lock, irq_flags); 740 + if (nentries < ch->remote_nentries) 741 + ch->remote_nentries = nentries; 742 + spin_unlock_irqrestore(&ch->lock, irq_flags); 743 + return xpSuccess; 744 + } 745 + 746 + return xpNoMemory; 747 + } 748 + 749 + /* 750 + * Allocate msg_slots associated with the channel. 751 + */ 752 + static enum xp_retval 753 + xpc_setup_msg_structures_uv(struct xpc_channel *ch) 754 + { 755 + static enum xp_retval ret; 756 + struct xpc_channel_uv *ch_uv = &ch->sn.uv; 757 + 758 + DBUG_ON(ch->flags & XPC_C_SETUP); 759 + 760 + ret = xpc_allocate_send_msg_slot_uv(ch); 761 + if (ret == xpSuccess) { 762 + 763 + ret = xpc_allocate_recv_msg_slot_uv(ch); 764 + if (ret != xpSuccess) { 765 + kfree(ch_uv->send_msg_slots); 766 + xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 767 + } 768 + } 769 + return ret; 770 + } 771 + 772 + /* 773 + * Free up msg_slots and clear other stuff that were setup for the specified 774 + * channel. 775 + */ 784 776 static void 785 777 xpc_teardown_msg_structures_uv(struct xpc_channel *ch) 786 778 { 787 779 struct xpc_channel_uv *ch_uv = &ch->sn.uv; 788 780 781 + DBUG_ON(!spin_is_locked(&ch->lock)); 782 + 789 783 ch_uv->remote_notify_mq_gpa = 0; 790 784 791 - /* !!! this function needs fleshing out */ 785 + if (ch->flags & XPC_C_SETUP) { 786 + xpc_init_fifo_uv(&ch_uv->msg_slot_free_list); 787 + kfree(ch_uv->send_msg_slots); 788 + xpc_init_fifo_uv(&ch_uv->recv_msg_list); 789 + kfree(ch_uv->recv_msg_slots); 790 + } 792 791 } 793 792 794 793 static void ··· 912 723 struct xpc_activate_mq_msg_chctl_openrequest_uv msg; 913 724 914 725 msg.ch_number = ch->number; 915 - msg.msg_size = ch->msg_size; 726 + msg.entry_size = ch->entry_size; 916 727 msg.local_nentries = ch->local_nentries; 917 728 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 918 729 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV); ··· 929 740 msg.local_notify_mq_gpa = uv_gpa(xpc_notify_mq_uv); 930 741 xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), 931 742 XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV); 743 + } 744 + 745 + static void 746 + xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) 747 + { 748 + unsigned long irq_flags; 749 + 750 + spin_lock_irqsave(&part->chctl_lock, irq_flags); 751 + part->chctl.flags[ch_number] |= XPC_CHCTL_MSGREQUEST; 752 + spin_unlock_irqrestore(&part->chctl_lock, irq_flags); 753 + 754 + xpc_wakeup_channel_mgr(part); 932 755 } 933 756 934 757 static void ··· 999 798 return 0; 1000 799 } 1001 800 1002 - static struct xpc_msg * 1003 - xpc_get_deliverable_msg_uv(struct xpc_channel *ch) 801 + static enum xp_retval 802 + xpc_allocate_msg_slot_uv(struct xpc_channel *ch, u32 flags, 803 + struct xpc_send_msg_slot_uv **address_of_msg_slot) 1004 804 { 1005 - /* !!! this function needs fleshing out */ 1006 - return NULL; 805 + enum xp_retval ret; 806 + struct xpc_send_msg_slot_uv *msg_slot; 807 + struct xpc_fifo_entry_uv *entry; 808 + 809 + while (1) { 810 + entry = xpc_get_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list); 811 + if (entry != NULL) 812 + break; 813 + 814 + if (flags & XPC_NOWAIT) 815 + return xpNoWait; 816 + 817 + ret = xpc_allocate_msg_wait(ch); 818 + if (ret != xpInterrupted && ret != xpTimeout) 819 + return ret; 820 + } 821 + 822 + msg_slot = container_of(entry, struct xpc_send_msg_slot_uv, next); 823 + *address_of_msg_slot = msg_slot; 824 + return xpSuccess; 825 + } 826 + 827 + static void 828 + xpc_free_msg_slot_uv(struct xpc_channel *ch, 829 + struct xpc_send_msg_slot_uv *msg_slot) 830 + { 831 + xpc_put_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list, &msg_slot->next); 832 + 833 + /* wakeup anyone waiting for a free msg slot */ 834 + if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) 835 + wake_up(&ch->msg_allocate_wq); 836 + } 837 + 838 + static void 839 + xpc_notify_sender_uv(struct xpc_channel *ch, 840 + struct xpc_send_msg_slot_uv *msg_slot, 841 + enum xp_retval reason) 842 + { 843 + xpc_notify_func func = msg_slot->func; 844 + 845 + if (func != NULL && cmpxchg(&msg_slot->func, func, NULL) == func) { 846 + 847 + atomic_dec(&ch->n_to_notify); 848 + 849 + dev_dbg(xpc_chan, "msg_slot->func() called, msg_slot=0x%p " 850 + "msg_slot_number=%d partid=%d channel=%d\n", msg_slot, 851 + msg_slot->msg_slot_number, ch->partid, ch->number); 852 + 853 + func(reason, ch->partid, ch->number, msg_slot->key); 854 + 855 + dev_dbg(xpc_chan, "msg_slot->func() returned, msg_slot=0x%p " 856 + "msg_slot_number=%d partid=%d channel=%d\n", msg_slot, 857 + msg_slot->msg_slot_number, ch->partid, ch->number); 858 + } 859 + } 860 + 861 + static void 862 + xpc_handle_notify_mq_ack_uv(struct xpc_channel *ch, 863 + struct xpc_notify_mq_msg_uv *msg) 864 + { 865 + struct xpc_send_msg_slot_uv *msg_slot; 866 + int entry = msg->hdr.msg_slot_number % ch->local_nentries; 867 + 868 + msg_slot = &ch->sn.uv.send_msg_slots[entry]; 869 + 870 + BUG_ON(msg_slot->msg_slot_number != msg->hdr.msg_slot_number); 871 + msg_slot->msg_slot_number += ch->local_nentries; 872 + 873 + if (msg_slot->func != NULL) 874 + xpc_notify_sender_uv(ch, msg_slot, xpMsgDelivered); 875 + 876 + xpc_free_msg_slot_uv(ch, msg_slot); 877 + } 878 + 879 + static void 880 + xpc_handle_notify_mq_msg_uv(struct xpc_partition *part, 881 + struct xpc_notify_mq_msg_uv *msg) 882 + { 883 + struct xpc_partition_uv *part_uv = &part->sn.uv; 884 + struct xpc_channel *ch; 885 + struct xpc_channel_uv *ch_uv; 886 + struct xpc_notify_mq_msg_uv *msg_slot; 887 + unsigned long irq_flags; 888 + int ch_number = msg->hdr.ch_number; 889 + 890 + if (unlikely(ch_number >= part->nchannels)) { 891 + dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received invalid " 892 + "channel number=0x%x in message from partid=%d\n", 893 + ch_number, XPC_PARTID(part)); 894 + 895 + /* get hb checker to deactivate from the remote partition */ 896 + spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); 897 + if (part_uv->act_state_req == 0) 898 + xpc_activate_IRQ_rcvd++; 899 + part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV; 900 + part_uv->reason = xpBadChannelNumber; 901 + spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags); 902 + 903 + wake_up_interruptible(&xpc_activate_IRQ_wq); 904 + return; 905 + } 906 + 907 + ch = &part->channels[ch_number]; 908 + xpc_msgqueue_ref(ch); 909 + 910 + if (!(ch->flags & XPC_C_CONNECTED)) { 911 + xpc_msgqueue_deref(ch); 912 + return; 913 + } 914 + 915 + /* see if we're really dealing with an ACK for a previously sent msg */ 916 + if (msg->hdr.size == 0) { 917 + xpc_handle_notify_mq_ack_uv(ch, msg); 918 + xpc_msgqueue_deref(ch); 919 + return; 920 + } 921 + 922 + /* we're dealing with a normal message sent via the notify_mq */ 923 + ch_uv = &ch->sn.uv; 924 + 925 + msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots + 926 + (msg->hdr.msg_slot_number % ch->remote_nentries) * 927 + ch->entry_size); 928 + 929 + BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number); 930 + BUG_ON(msg_slot->hdr.size != 0); 931 + 932 + memcpy(msg_slot, msg, msg->hdr.size); 933 + 934 + xpc_put_fifo_entry_uv(&ch_uv->recv_msg_list, &msg_slot->hdr.u.next); 935 + 936 + if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) { 937 + /* 938 + * If there is an existing idle kthread get it to deliver 939 + * the payload, otherwise we'll have to get the channel mgr 940 + * for this partition to create a kthread to do the delivery. 941 + */ 942 + if (atomic_read(&ch->kthreads_idle) > 0) 943 + wake_up_nr(&ch->idle_wq, 1); 944 + else 945 + xpc_send_chctl_local_msgrequest_uv(part, ch->number); 946 + } 947 + xpc_msgqueue_deref(ch); 948 + } 949 + 950 + static irqreturn_t 951 + xpc_handle_notify_IRQ_uv(int irq, void *dev_id) 952 + { 953 + struct xpc_notify_mq_msg_uv *msg; 954 + short partid; 955 + struct xpc_partition *part; 956 + 957 + while ((msg = gru_get_next_message(xpc_notify_mq_uv)) != NULL) { 958 + 959 + partid = msg->hdr.partid; 960 + if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) { 961 + dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received " 962 + "invalid partid=0x%x in message\n", partid); 963 + } else { 964 + part = &xpc_partitions[partid]; 965 + 966 + if (xpc_part_ref(part)) { 967 + xpc_handle_notify_mq_msg_uv(part, msg); 968 + xpc_part_deref(part); 969 + } 970 + } 971 + 972 + gru_free_message(xpc_notify_mq_uv, msg); 973 + } 974 + 975 + return IRQ_HANDLED; 976 + } 977 + 978 + static int 979 + xpc_n_of_deliverable_payloads_uv(struct xpc_channel *ch) 980 + { 981 + return xpc_n_of_fifo_entries_uv(&ch->sn.uv.recv_msg_list); 982 + } 983 + 984 + static void 985 + xpc_process_msg_chctl_flags_uv(struct xpc_partition *part, int ch_number) 986 + { 987 + struct xpc_channel *ch = &part->channels[ch_number]; 988 + int ndeliverable_payloads; 989 + 990 + xpc_msgqueue_ref(ch); 991 + 992 + ndeliverable_payloads = xpc_n_of_deliverable_payloads_uv(ch); 993 + 994 + if (ndeliverable_payloads > 0 && 995 + (ch->flags & XPC_C_CONNECTED) && 996 + (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)) { 997 + 998 + xpc_activate_kthreads(ch, ndeliverable_payloads); 999 + } 1000 + 1001 + xpc_msgqueue_deref(ch); 1002 + } 1003 + 1004 + static enum xp_retval 1005 + xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload, 1006 + u16 payload_size, u8 notify_type, xpc_notify_func func, 1007 + void *key) 1008 + { 1009 + enum xp_retval ret = xpSuccess; 1010 + struct xpc_send_msg_slot_uv *msg_slot = NULL; 1011 + struct xpc_notify_mq_msg_uv *msg; 1012 + u8 msg_buffer[XPC_NOTIFY_MSG_SIZE_UV]; 1013 + size_t msg_size; 1014 + 1015 + DBUG_ON(notify_type != XPC_N_CALL); 1016 + 1017 + msg_size = sizeof(struct xpc_notify_mq_msghdr_uv) + payload_size; 1018 + if (msg_size > ch->entry_size) 1019 + return xpPayloadTooBig; 1020 + 1021 + xpc_msgqueue_ref(ch); 1022 + 1023 + if (ch->flags & XPC_C_DISCONNECTING) { 1024 + ret = ch->reason; 1025 + goto out_1; 1026 + } 1027 + if (!(ch->flags & XPC_C_CONNECTED)) { 1028 + ret = xpNotConnected; 1029 + goto out_1; 1030 + } 1031 + 1032 + ret = xpc_allocate_msg_slot_uv(ch, flags, &msg_slot); 1033 + if (ret != xpSuccess) 1034 + goto out_1; 1035 + 1036 + if (func != NULL) { 1037 + atomic_inc(&ch->n_to_notify); 1038 + 1039 + msg_slot->key = key; 1040 + wmb(); /* a non-NULL func must hit memory after the key */ 1041 + msg_slot->func = func; 1042 + 1043 + if (ch->flags & XPC_C_DISCONNECTING) { 1044 + ret = ch->reason; 1045 + goto out_2; 1046 + } 1047 + } 1048 + 1049 + msg = (struct xpc_notify_mq_msg_uv *)&msg_buffer; 1050 + msg->hdr.partid = xp_partition_id; 1051 + msg->hdr.ch_number = ch->number; 1052 + msg->hdr.size = msg_size; 1053 + msg->hdr.msg_slot_number = msg_slot->msg_slot_number; 1054 + memcpy(&msg->payload, payload, payload_size); 1055 + 1056 + ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg, msg_size); 1057 + if (ret == xpSuccess) 1058 + goto out_1; 1059 + 1060 + XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); 1061 + out_2: 1062 + if (func != NULL) { 1063 + /* 1064 + * Try to NULL the msg_slot's func field. If we fail, then 1065 + * xpc_notify_senders_of_disconnect_uv() beat us to it, in which 1066 + * case we need to pretend we succeeded to send the message 1067 + * since the user will get a callout for the disconnect error 1068 + * by xpc_notify_senders_of_disconnect_uv(), and to also get an 1069 + * error returned here will confuse them. Additionally, since 1070 + * in this case the channel is being disconnected we don't need 1071 + * to put the the msg_slot back on the free list. 1072 + */ 1073 + if (cmpxchg(&msg_slot->func, func, NULL) != func) { 1074 + ret = xpSuccess; 1075 + goto out_1; 1076 + } 1077 + 1078 + msg_slot->key = NULL; 1079 + atomic_dec(&ch->n_to_notify); 1080 + } 1081 + xpc_free_msg_slot_uv(ch, msg_slot); 1082 + out_1: 1083 + xpc_msgqueue_deref(ch); 1084 + return ret; 1085 + } 1086 + 1087 + /* 1088 + * Tell the callers of xpc_send_notify() that the status of their payloads 1089 + * is unknown because the channel is now disconnecting. 1090 + * 1091 + * We don't worry about putting these msg_slots on the free list since the 1092 + * msg_slots themselves are about to be kfree'd. 1093 + */ 1094 + static void 1095 + xpc_notify_senders_of_disconnect_uv(struct xpc_channel *ch) 1096 + { 1097 + struct xpc_send_msg_slot_uv *msg_slot; 1098 + int entry; 1099 + 1100 + DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING)); 1101 + 1102 + for (entry = 0; entry < ch->local_nentries; entry++) { 1103 + 1104 + if (atomic_read(&ch->n_to_notify) == 0) 1105 + break; 1106 + 1107 + msg_slot = &ch->sn.uv.send_msg_slots[entry]; 1108 + if (msg_slot->func != NULL) 1109 + xpc_notify_sender_uv(ch, msg_slot, ch->reason); 1110 + } 1111 + } 1112 + 1113 + /* 1114 + * Get the next deliverable message's payload. 1115 + */ 1116 + static void * 1117 + xpc_get_deliverable_payload_uv(struct xpc_channel *ch) 1118 + { 1119 + struct xpc_fifo_entry_uv *entry; 1120 + struct xpc_notify_mq_msg_uv *msg; 1121 + void *payload = NULL; 1122 + 1123 + if (!(ch->flags & XPC_C_DISCONNECTING)) { 1124 + entry = xpc_get_fifo_entry_uv(&ch->sn.uv.recv_msg_list); 1125 + if (entry != NULL) { 1126 + msg = container_of(entry, struct xpc_notify_mq_msg_uv, 1127 + hdr.u.next); 1128 + payload = &msg->payload; 1129 + } 1130 + } 1131 + return payload; 1132 + } 1133 + 1134 + static void 1135 + xpc_received_payload_uv(struct xpc_channel *ch, void *payload) 1136 + { 1137 + struct xpc_notify_mq_msg_uv *msg; 1138 + enum xp_retval ret; 1139 + 1140 + msg = container_of(payload, struct xpc_notify_mq_msg_uv, payload); 1141 + 1142 + /* return an ACK to the sender of this message */ 1143 + 1144 + msg->hdr.partid = xp_partition_id; 1145 + msg->hdr.size = 0; /* size of zero indicates this is an ACK */ 1146 + 1147 + ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg, 1148 + sizeof(struct xpc_notify_mq_msghdr_uv)); 1149 + if (ret != xpSuccess) 1150 + XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret); 1151 + 1152 + msg->hdr.msg_slot_number += ch->remote_nentries; 1007 1153 } 1008 1154 1009 1155 int ··· 1372 824 xpc_request_partition_reactivation_uv; 1373 825 xpc_request_partition_deactivation = 1374 826 xpc_request_partition_deactivation_uv; 827 + xpc_cancel_partition_deactivation_request = 828 + xpc_cancel_partition_deactivation_request_uv; 1375 829 1376 830 xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_uv; 1377 831 xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_uv; ··· 1398 848 xpc_partition_engaged = xpc_partition_engaged_uv; 1399 849 xpc_any_partition_engaged = xpc_any_partition_engaged_uv; 1400 850 1401 - xpc_get_deliverable_msg = xpc_get_deliverable_msg_uv; 851 + xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv; 852 + xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv; 853 + xpc_send_payload = xpc_send_payload_uv; 854 + xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv; 855 + xpc_get_deliverable_payload = xpc_get_deliverable_payload_uv; 856 + xpc_received_payload = xpc_received_payload_uv; 857 + 858 + if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { 859 + dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n", 860 + XPC_MSG_HDR_MAX_SIZE); 861 + return -E2BIG; 862 + } 1402 863 1403 864 /* ??? The cpuid argument's value is 0, is that what we want? */ 1404 865 /* !!! The irq argument's value isn't correct. */ ··· 1418 857 if (xpc_activate_mq_uv == NULL) 1419 858 return -ENOMEM; 1420 859 860 + /* ??? The cpuid argument's value is 0, is that what we want? */ 861 + /* !!! The irq argument's value isn't correct. */ 862 + xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, 0, 863 + xpc_handle_notify_IRQ_uv); 864 + if (xpc_notify_mq_uv == NULL) { 865 + /* !!! The irq argument's value isn't correct. */ 866 + xpc_destroy_gru_mq_uv(xpc_activate_mq_uv, 867 + XPC_ACTIVATE_MQ_SIZE_UV, 0); 868 + return -ENOMEM; 869 + } 870 + 1421 871 return 0; 1422 872 } 1423 873 1424 874 void 1425 875 xpc_exit_uv(void) 1426 876 { 877 + /* !!! The irq argument's value isn't correct. */ 878 + xpc_destroy_gru_mq_uv(xpc_notify_mq_uv, XPC_NOTIFY_MQ_SIZE_UV, 0); 879 + 1427 880 /* !!! The irq argument's value isn't correct. */ 1428 881 xpc_destroy_gru_mq_uv(xpc_activate_mq_uv, XPC_ACTIVATE_MQ_SIZE_UV, 0); 1429 882 }
+6 -5
drivers/misc/sgi-xp/xpnet.c
··· 57 57 * 58 58 * XPC expects each message to exist in an individual cacheline. 59 59 */ 60 - #define XPNET_MSG_SIZE (L1_CACHE_BYTES - XPC_MSG_PAYLOAD_OFFSET) 60 + #define XPNET_MSG_SIZE XPC_MSG_PAYLOAD_MAX_SIZE 61 61 #define XPNET_MSG_DATA_MAX \ 62 - (XPNET_MSG_SIZE - (u64)(&((struct xpnet_message *)0)->data)) 63 - #define XPNET_MSG_ALIGNED_SIZE (L1_CACHE_ALIGN(XPNET_MSG_SIZE)) 64 - #define XPNET_MSG_NENTRIES (PAGE_SIZE / XPNET_MSG_ALIGNED_SIZE) 62 + (XPNET_MSG_SIZE - offsetof(struct xpnet_message, data)) 63 + #define XPNET_MSG_NENTRIES (PAGE_SIZE / XPC_MSG_MAX_SIZE) 65 64 66 65 #define XPNET_MAX_KTHREADS (XPNET_MSG_NENTRIES + 1) 67 66 #define XPNET_MAX_IDLE_KTHREADS (XPNET_MSG_NENTRIES + 1) ··· 407 408 { 408 409 u8 msg_buffer[XPNET_MSG_SIZE]; 409 410 struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer; 411 + u16 msg_size = sizeof(struct xpnet_message); 410 412 enum xp_retval ret; 411 413 412 414 msg->embedded_bytes = embedded_bytes; ··· 417 417 &msg->data, skb->data, (size_t)embedded_bytes); 418 418 skb_copy_from_linear_data(skb, &msg->data, 419 419 (size_t)embedded_bytes); 420 + msg_size += embedded_bytes - 1; 420 421 } else { 421 422 msg->version = XPNET_VERSION; 422 423 } ··· 436 435 atomic_inc(&queued_msg->use_count); 437 436 438 437 ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT, msg, 439 - XPNET_MSG_SIZE, xpnet_send_completed, queued_msg); 438 + msg_size, xpnet_send_completed, queued_msg); 440 439 if (unlikely(ret != xpSuccess)) 441 440 atomic_dec(&queued_msg->use_count); 442 441 }