Lines Matching refs:ch

27 xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
31 lockdep_assert_held(&ch->lock);
33 if (!(ch->flags & XPC_C_OPENREQUEST) ||
34 !(ch->flags & XPC_C_ROPENREQUEST)) {
38 DBUG_ON(!(ch->flags & XPC_C_CONNECTING));
40 if (!(ch->flags & XPC_C_SETUP)) {
41 spin_unlock_irqrestore(&ch->lock, *irq_flags);
42 ret = xpc_arch_ops.setup_msg_structures(ch);
43 spin_lock_irqsave(&ch->lock, *irq_flags);
46 XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
48 ch->flags |= XPC_C_SETUP;
50 if (ch->flags & XPC_C_DISCONNECTING)
54 if (!(ch->flags & XPC_C_OPENREPLY)) {
55 ch->flags |= XPC_C_OPENREPLY;
56 xpc_arch_ops.send_chctl_openreply(ch, irq_flags);
59 if (!(ch->flags & XPC_C_ROPENREPLY))
62 if (!(ch->flags & XPC_C_OPENCOMPLETE)) {
63 ch->flags |= (XPC_C_OPENCOMPLETE | XPC_C_CONNECTED);
64 xpc_arch_ops.send_chctl_opencomplete(ch, irq_flags);
67 if (!(ch->flags & XPC_C_ROPENCOMPLETE))
71 ch->number, ch->partid);
73 ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */
80 xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
82 struct xpc_partition *part = &xpc_partitions[ch->partid];
83 u32 channel_was_connected = (ch->flags & XPC_C_WASCONNECTED);
85 lockdep_assert_held(&ch->lock);
87 if (!(ch->flags & XPC_C_DISCONNECTING))
90 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
94 if (atomic_read(&ch->kthreads_assigned) > 0 ||
95 atomic_read(&ch->references) > 0) {
98 DBUG_ON((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
99 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE));
103 if (xpc_arch_ops.partition_engaged(ch->partid))
110 if (!(ch->flags & XPC_C_RCLOSEREQUEST))
113 if (!(ch->flags & XPC_C_CLOSEREPLY)) {
114 ch->flags |= XPC_C_CLOSEREPLY;
115 xpc_arch_ops.send_chctl_closereply(ch, irq_flags);
118 if (!(ch->flags & XPC_C_RCLOSEREPLY))
123 if (atomic_read(&ch->n_to_notify) > 0) {
124 /* we do callout while holding ch->lock, callout can't block */
125 xpc_arch_ops.notify_senders_of_disconnect(ch);
130 if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
131 spin_unlock_irqrestore(&ch->lock, *irq_flags);
132 xpc_disconnect_callout(ch, xpDisconnected);
133 spin_lock_irqsave(&ch->lock, *irq_flags);
136 DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
139 xpc_arch_ops.teardown_msg_structures(ch);
141 ch->func = NULL;
142 ch->key = NULL;
143 ch->entry_size = 0;
144 ch->local_nentries = 0;
145 ch->remote_nentries = 0;
146 ch->kthreads_assigned_limit = 0;
147 ch->kthreads_idle_limit = 0;
155 ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
161 "reason=%d\n", ch->number, ch->partid, ch->reason);
164 if (ch->flags & XPC_C_WDISCONNECT) {
165 /* we won't lose the CPU since we're holding ch->lock */
166 complete(&ch->wdisconnect_wait);
167 } else if (ch->delayed_chctl_flags) {
171 part->chctl.flags[ch->number] |=
172 ch->delayed_chctl_flags;
175 ch->delayed_chctl_flags = 0;
189 struct xpc_channel *ch = &part->channels[ch_number];
194 spin_lock_irqsave(&ch->lock, irq_flags);
198 if ((ch->flags & XPC_C_DISCONNECTED) &&
199 (ch->flags & XPC_C_WDISCONNECT)) {
204 ch->delayed_chctl_flags |= chctl_flags;
212 ch->partid, ch->number);
220 if (ch->flags & XPC_C_RCLOSEREQUEST) {
221 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING));
222 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
223 DBUG_ON(!(ch->flags & XPC_C_CLOSEREPLY));
224 DBUG_ON(ch->flags & XPC_C_RCLOSEREPLY);
228 ch->flags |= XPC_C_RCLOSEREPLY;
231 xpc_process_disconnect(ch, &irq_flags);
232 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
236 if (ch->flags & XPC_C_DISCONNECTED) {
241 DBUG_ON(ch->delayed_chctl_flags != 0);
250 XPC_SET_REASON(ch, 0, 0);
251 ch->flags &= ~XPC_C_DISCONNECTED;
254 ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
265 ch->flags |= XPC_C_RCLOSEREQUEST;
267 if (!(ch->flags & XPC_C_DISCONNECTING)) {
274 XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
280 xpc_process_disconnect(ch, &irq_flags);
286 "%d, channel=%d\n", ch->partid, ch->number);
288 if (ch->flags & XPC_C_DISCONNECTED) {
293 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
295 if (!(ch->flags & XPC_C_RCLOSEREQUEST)) {
299 DBUG_ON(ch->delayed_chctl_flags != 0);
308 ch->flags |= XPC_C_RCLOSEREPLY;
310 if (ch->flags & XPC_C_CLOSEREPLY) {
312 xpc_process_disconnect(ch, &irq_flags);
321 ch->partid, ch->number);
324 (ch->flags & XPC_C_ROPENREQUEST)) {
328 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
329 ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST;
332 DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED |
334 DBUG_ON(ch->flags & (XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
347 ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
348 ch->remote_nentries = args->local_nentries;
350 if (ch->flags & XPC_C_OPENREQUEST) {
351 if (args->entry_size != ch->entry_size) {
352 XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
357 ch->entry_size = args->entry_size;
359 XPC_SET_REASON(ch, 0, 0);
360 ch->flags &= ~XPC_C_DISCONNECTED;
365 xpc_process_connect(ch, &irq_flags);
374 args->remote_nentries, ch->partid, ch->number);
376 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
379 if (!(ch->flags & XPC_C_OPENREQUEST)) {
380 XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
385 DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
386 DBUG_ON(ch->flags & XPC_C_CONNECTED);
399 ret = xpc_arch_ops.save_remote_msgqueue_pa(ch,
402 XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags);
405 ch->flags |= XPC_C_ROPENREPLY;
407 if (args->local_nentries < ch->remote_nentries) {
411 args->local_nentries, ch->remote_nentries,
412 ch->partid, ch->number);
414 ch->remote_nentries = args->local_nentries;
416 if (args->remote_nentries < ch->local_nentries) {
420 args->remote_nentries, ch->local_nentries,
421 ch->partid, ch->number);
423 ch->local_nentries = args->remote_nentries;
426 xpc_process_connect(ch, &irq_flags);
432 "partid=%d, channel=%d\n", ch->partid, ch->number);
434 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
437 if (!(ch->flags & XPC_C_OPENREQUEST) ||
438 !(ch->flags & XPC_C_OPENREPLY)) {
439 XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
444 DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
445 DBUG_ON(!(ch->flags & XPC_C_ROPENREPLY));
446 DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
448 ch->flags |= XPC_C_ROPENCOMPLETE;
450 xpc_process_connect(ch, &irq_flags);
455 spin_unlock_irqrestore(&ch->lock, irq_flags);
458 xpc_create_kthreads(ch, 1, 0);
465 xpc_connect_channel(struct xpc_channel *ch)
468 struct xpc_registration *registration = &xpc_registrations[ch->number];
473 if (!XPC_CHANNEL_REGISTERED(ch->number)) {
478 spin_lock_irqsave(&ch->lock, irq_flags);
480 DBUG_ON(ch->flags & XPC_C_CONNECTED);
481 DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
483 if (ch->flags & XPC_C_DISCONNECTING) {
484 spin_unlock_irqrestore(&ch->lock, irq_flags);
486 return ch->reason;
491 ch->kthreads_assigned_limit = registration->assigned_limit;
492 ch->kthreads_idle_limit = registration->idle_limit;
493 DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
494 DBUG_ON(atomic_read(&ch->kthreads_idle) != 0);
495 DBUG_ON(atomic_read(&ch->kthreads_active) != 0);
497 ch->func = registration->func;
499 ch->key = registration->key;
501 ch->local_nentries = registration->nentries;
503 if (ch->flags & XPC_C_ROPENREQUEST) {
504 if (registration->entry_size != ch->entry_size) {
517 XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
519 spin_unlock_irqrestore(&ch->lock, irq_flags);
523 ch->entry_size = registration->entry_size;
525 XPC_SET_REASON(ch, 0, 0);
526 ch->flags &= ~XPC_C_DISCONNECTED;
528 atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
535 ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
536 xpc_arch_ops.send_chctl_openrequest(ch, &irq_flags);
538 xpc_process_connect(ch, &irq_flags);
540 spin_unlock_irqrestore(&ch->lock, irq_flags);
550 struct xpc_channel *ch;
564 ch = &part->channels[ch_number];
576 ch_flags = ch->flags; /* need an atomic snapshot of flags */
579 spin_lock_irqsave(&ch->lock, irq_flags);
580 xpc_process_disconnect(ch, &irq_flags);
581 spin_unlock_irqrestore(&ch->lock, irq_flags);
591 (void)xpc_connect_channel(ch);
621 struct xpc_channel *ch;
634 ch = &part->channels[ch_number];
636 xpc_msgqueue_ref(ch);
637 spin_lock_irqsave(&ch->lock, irq_flags);
639 XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
641 spin_unlock_irqrestore(&ch->lock, irq_flags);
642 xpc_msgqueue_deref(ch);
677 xpc_connected_callout(struct xpc_channel *ch)
681 if (ch->func != NULL) {
682 dev_dbg(xpc_chan, "ch->func() called, reason=xpConnected, "
683 "partid=%d, channel=%d\n", ch->partid, ch->number);
685 ch->func(xpConnected, ch->partid, ch->number,
686 (void *)(u64)ch->local_nentries, ch->key);
688 dev_dbg(xpc_chan, "ch->func() returned, reason=xpConnected, "
689 "partid=%d, channel=%d\n", ch->partid, ch->number);
712 struct xpc_channel *ch;
721 ch = &part->channels[ch_number];
722 xpc_msgqueue_ref(ch);
724 spin_lock_irqsave(&ch->lock, irq_flags);
726 if (!(ch->flags & XPC_C_DISCONNECTED)) {
727 ch->flags |= XPC_C_WDISCONNECT;
729 XPC_DISCONNECT_CHANNEL(ch, xpUnregistering,
733 spin_unlock_irqrestore(&ch->lock, irq_flags);
735 xpc_msgqueue_deref(ch);
753 xpc_disconnect_channel(const int line, struct xpc_channel *ch,
756 u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED);
758 lockdep_assert_held(&ch->lock);
760 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
763 DBUG_ON(!(ch->flags & (XPC_C_CONNECTING | XPC_C_CONNECTED)));
766 reason, line, ch->partid, ch->number);
768 XPC_SET_REASON(ch, reason, line);
770 ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
772 ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY |
776 xpc_arch_ops.send_chctl_closerequest(ch, irq_flags);
779 ch->flags |= XPC_C_WASCONNECTED;
781 spin_unlock_irqrestore(&ch->lock, *irq_flags);
784 if (atomic_read(&ch->kthreads_idle) > 0) {
785 wake_up_all(&ch->idle_wq);
787 } else if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
788 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
790 xpc_create_kthreads(ch, 1, 1);
794 if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
795 wake_up(&ch->msg_allocate_wq);
797 spin_lock_irqsave(&ch->lock, *irq_flags);
801 xpc_disconnect_callout(struct xpc_channel *ch, enum xp_retval reason)
809 if (ch->func != NULL) {
810 dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
811 "channel=%d\n", reason, ch->partid, ch->number);
813 ch->func(reason, ch->partid, ch->number, NULL, ch->key);
815 dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
816 "channel=%d\n", reason, ch->partid, ch->number);
825 xpc_allocate_msg_wait(struct xpc_channel *ch)
830 if (ch->flags & XPC_C_DISCONNECTING) {
831 DBUG_ON(ch->reason == xpInterrupted);
832 return ch->reason;
835 atomic_inc(&ch->n_on_msg_allocate_wq);
836 prepare_to_wait(&ch->msg_allocate_wq, &wait, TASK_INTERRUPTIBLE);
838 finish_wait(&ch->msg_allocate_wq, &wait);
839 atomic_dec(&ch->n_on_msg_allocate_wq);
841 if (ch->flags & XPC_C_DISCONNECTING) {
842 ret = ch->reason;
843 DBUG_ON(ch->reason == xpInterrupted);
949 xpc_deliver_payload(struct xpc_channel *ch)
953 payload = xpc_arch_ops.get_deliverable_payload(ch);
961 xpc_msgqueue_ref(ch);
963 atomic_inc(&ch->kthreads_active);
965 if (ch->func != NULL) {
966 dev_dbg(xpc_chan, "ch->func() called, payload=0x%p "
967 "partid=%d channel=%d\n", payload, ch->partid,
968 ch->number);
971 ch->func(xpMsgReceived, ch->partid, ch->number, payload,
972 ch->key);
974 dev_dbg(xpc_chan, "ch->func() returned, payload=0x%p "
975 "partid=%d channel=%d\n", payload, ch->partid,
976 ch->number);
979 atomic_dec(&ch->kthreads_active);
1001 struct xpc_channel *ch;
1006 ch = &part->channels[ch_number];
1007 xpc_arch_ops.received_payload(ch, payload);
1010 xpc_msgqueue_deref(ch);