[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
send messages from the kernel to the user space
From: |
Da Zheng |
Subject: |
send messages from the kernel to the user space |
Date: |
Wed, 05 Aug 2009 21:38:28 +0800 |
User-agent: |
Thunderbird 2.0.0.22 (Macintosh/20090605) |
Hi,
Whenever an interrupt occurs, I need to send a message to the user space.
An RPC device_intr_notify is defined, so the user-level driver can register its
port in the kernel. The server side of the RPC is below:
io_return_t
ds_device_intr_notify (ipc_port_t master_port, int irq,
int id, ipc_port_t receive_port)
{
/* Open must be called on the master device port. */
if (master_port != master_device_port)
return D_INVALID_OPERATION;
if (irq < 0 || irq >= 16)
return D_INVALID_OPERATION;
intr_rcv_ports[irq] = receive_port;
return 0;
}
deliver_irq() is to send a notification message to the port registered by the
user. The code is below:
boolean_t
deliver_irq (int irq)
{
ipc_kmsg_t kmsg;
mach_irq_notification_t *n;
ipc_port_t dest_port = intr_rcv_ports[irq];
mach_port_t dest = (mach_port_t) dest_port;
if (dest == MACH_PORT_NULL)
return FALSE;
kmsg = ikm_alloc(sizeof *n);
if (kmsg == IKM_NULL)
return FALSE;
ikm_init(kmsg, sizeof *n);
n = (mach_irq_notification_t *) &kmsg->ikm_header;
mach_msg_header_t *m = &n->irq_header;
mach_msg_type_t *t = &n->irq_type;
m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
m->msgh_size = sizeof *n;
m->msgh_seqno = IRQ_NOTIFY_MSGH_SEQNO;
m->msgh_local_port = MACH_PORT_NULL;
m->msgh_remote_port = MACH_PORT_NULL;
m->msgh_id = MACH_NOTIFY_IRQ;
t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
t->msgt_size = 32;
t->msgt_number = 1;
t->msgt_inline = TRUE;
t->msgt_longform = FALSE;
t->msgt_deallocate = FALSE;
t->msgt_unused = 0;
n->irq_header.msgh_remote_port = dest;
n->irq = irq;
ipc_port_copy_send (dest_port);
ipc_mqueue_send_always(kmsg);
return TRUE;
}
It can work most of time. However, it seems that the code above causes a bug in
the kernel.
The kernel might crash with the following error:
Assertion '(&dest_mqueue->imq_threads)->ithq_base == (receiver)' failed in file
"../gnumach/ipc/mach_msg.c", line 998
I traced the stack, and it is:
(null):~/gnumach# addr2line -e ../gnumach-build/gnumach 0x117a06 0x117a57
0x145b57
/root/gnumach-build/../gnumach/kern/debug.c:103
??:0
/root/gnumach-build/../gnumach/ipc/mach_msg.c:892
I don't understand how the assertion can fail here. mach_msg_trap() locks the
message queue before accessing it and my code seems to do the same.
Could anyone tell me whether I did something wrong in the code above?
Thank you,
Zheng Da
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- send messages from the kernel to the user space,
Da Zheng <=