ia64/xen-unstable
changeset 2364:cc7f31b32068
bitkeeper revision 1.1159.56.1 (412f28f2oorf9i_6akPMKOUodxF7qg)
Towards new device-interface setup code for the frontend drivers.
Added a synchronous send-and-get-response call to the control
interface API. Modified and extended the domain-controller messaging
protocol.
Towards new device-interface setup code for the frontend drivers.
Added a synchronous send-and-get-response call to the control
interface API. Modified and extended the domain-controller messaging
protocol.
author | kaf24@labyrinth.cl.cam.ac.uk |
---|---|
date | Fri Aug 27 12:28:34 2004 +0000 (2004-08-27) |
parents | cfe5c20ae78e |
children | 401dcd9a4f0b |
files | linux-2.6.8.1-xen-sparse/arch/xen/kernel/ctrl_if.c linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6.8.1-xen-sparse/include/asm-xen/ctrl_if.h tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/server/netif.py xen/include/hypervisor-ifs/io/domain_controller.h |
line diff
1.1 --- a/linux-2.6.8.1-xen-sparse/arch/xen/kernel/ctrl_if.c Fri Aug 27 02:47:12 2004 +0000 1.2 +++ b/linux-2.6.8.1-xen-sparse/arch/xen/kernel/ctrl_if.c Fri Aug 27 12:28:34 2004 +0000 1.3 @@ -201,7 +201,8 @@ static irqreturn_t ctrl_if_interrupt(int 1.4 return IRQ_HANDLED; 1.5 } 1.6 1.7 -int ctrl_if_send_message_noblock( 1.8 +int 1.9 +ctrl_if_send_message_noblock( 1.10 ctrl_msg_t *msg, 1.11 ctrl_msg_handler_t hnd, 1.12 unsigned long id) 1.13 @@ -245,7 +246,8 @@ int ctrl_if_send_message_noblock( 1.14 return 0; 1.15 } 1.16 1.17 -int ctrl_if_send_message_block( 1.18 +int 1.19 +ctrl_if_send_message_block( 1.20 ctrl_msg_t *msg, 1.21 ctrl_msg_handler_t hnd, 1.22 unsigned long id, 1.23 @@ -280,7 +282,59 @@ int ctrl_if_send_message_block( 1.24 return rc; 1.25 } 1.26 1.27 -int ctrl_if_enqueue_space_callback(struct tq_struct *task) 1.28 +/* Allow a reponse-callback handler to find context of a blocked requester. */ 1.29 +struct rsp_wait { 1.30 + ctrl_msg_t *msg; /* Buffer for the response message. */ 1.31 + struct task_struct *task; /* The task that is blocked on the response. */ 1.32 + int done; /* Indicate to 'task' that response is rcv'ed. */ 1.33 +}; 1.34 + 1.35 +static void __ctrl_if_get_response(ctrl_msg_t *msg, unsigned long id) 1.36 +{ 1.37 + struct rsp_wait *wait = (struct rsp_wait *)id; 1.38 + struct task_struct *task = wait->task; 1.39 + 1.40 + memcpy(wait->msg, msg, sizeof(*msg)); 1.41 + wmb(); 1.42 + wait->done = 1; 1.43 + 1.44 + wake_up_process(task); 1.45 +} 1.46 + 1.47 +int 1.48 +ctrl_if_send_message_and_get_response( 1.49 + ctrl_msg_t *msg, 1.50 + ctrl_msg_t *rmsg, 1.51 + long wait_state) 1.52 +{ 1.53 + struct rsp_wait wait; 1.54 + int rc; 1.55 + 1.56 + wait.msg = rmsg; 1.57 + wait.done = 0; 1.58 + wait.task = current; 1.59 + 1.60 + if ( (rc = ctrl_if_send_message_block(msg, __ctrl_if_get_response, 1.61 + (unsigned long)&wait, 1.62 + wait_state)) != 0 ) 1.63 + return rc; 1.64 + 1.65 + for ( ; ; ) 1.66 + { 1.67 + /* NB. Can't easily support TASK_INTERRUPTIBLE here. */ 1.68 + set_current_state(TASK_UNINTERRUPTIBLE); 1.69 + if ( wait.done ) 1.70 + break; 1.71 + schedule(); 1.72 + } 1.73 + 1.74 + set_current_state(TASK_RUNNING); 1.75 + return 0; 1.76 +} 1.77 + 1.78 +int 1.79 +ctrl_if_enqueue_space_callback( 1.80 + struct tq_struct *task) 1.81 { 1.82 control_if_t *ctrl_if = get_ctrl_if(); 1.83 1.84 @@ -299,7 +353,9 @@ int ctrl_if_enqueue_space_callback(struc 1.85 return TX_FULL(ctrl_if); 1.86 } 1.87 1.88 -void ctrl_if_send_response(ctrl_msg_t *msg) 1.89 +void 1.90 +ctrl_if_send_response( 1.91 + ctrl_msg_t *msg) 1.92 { 1.93 control_if_t *ctrl_if = get_ctrl_if(); 1.94 unsigned long flags; 1.95 @@ -327,7 +383,8 @@ void ctrl_if_send_response(ctrl_msg_t *m 1.96 ctrl_if_notify_controller(); 1.97 } 1.98 1.99 -int ctrl_if_register_receiver( 1.100 +int 1.101 +ctrl_if_register_receiver( 1.102 u8 type, 1.103 ctrl_msg_handler_t hnd, 1.104 unsigned int flags) 1.105 @@ -361,7 +418,10 @@ int ctrl_if_register_receiver( 1.106 return !inuse; 1.107 } 1.108 1.109 -void ctrl_if_unregister_receiver(u8 type, ctrl_msg_handler_t hnd) 1.110 +void 1.111 +ctrl_if_unregister_receiver( 1.112 + u8 type, 1.113 + ctrl_msg_handler_t hnd) 1.114 { 1.115 unsigned long flags; 1.116
2.1 --- a/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c Fri Aug 27 02:47:12 2004 +0000 2.2 +++ b/linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c Fri Aug 27 12:28:34 2004 +0000 2.3 @@ -814,9 +814,10 @@ static void netif_driver_status_change( 2.4 int err = 0; 2.5 int i; 2.6 2.7 - DPRINTK("> nr_interfaces=%d\n", status->nr_interfaces); 2.8 + DPRINTK("> max_handle=%d\n", status->max_handle); 2.9 2.10 - netctrl.interface_n = status->nr_interfaces; 2.11 + /* XXX FIXME: Abuse of 'max_handle' as interface count. */ 2.12 + netctrl.interface_n = status->max_handle; 2.13 netctrl.connected_n = 0; 2.14 2.15 for ( i = 0; i < netctrl.interface_n; i++ ) 2.16 @@ -913,7 +914,7 @@ static int __init netif_init(void) 2.17 cmsg.subtype = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED; 2.18 cmsg.length = sizeof(netif_fe_driver_status_changed_t); 2.19 st.status = NETIF_DRIVER_STATUS_UP; 2.20 - st.nr_interfaces = 0; 2.21 + st.max_handle = 0; 2.22 memcpy(cmsg.msg, &st, sizeof(st)); 2.23 ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 2.24 2.25 @@ -999,7 +1000,7 @@ void netif_resume(void) 2.26 cmsg.subtype = CMSG_NETIF_FE_DRIVER_STATUS_CHANGED; 2.27 cmsg.length = sizeof(netif_fe_driver_status_changed_t); 2.28 st.status = NETIF_DRIVER_STATUS_UP; 2.29 - st.nr_interfaces = 0; 2.30 + st.max_handle = 0; 2.31 memcpy(cmsg.msg, &st, sizeof(st)); 2.32 ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 2.33 #endif
3.1 --- a/linux-2.6.8.1-xen-sparse/include/asm-xen/ctrl_if.h Fri Aug 27 02:47:12 2004 +0000 3.2 +++ b/linux-2.6.8.1-xen-sparse/include/asm-xen/ctrl_if.h Fri Aug 27 12:28:34 2004 +0000 3.3 @@ -37,7 +37,8 @@ typedef void (*ctrl_msg_handler_t)(ctrl_ 3.4 * function returns. 3.5 * 2. If @hnd is NULL then no callback is executed. 3.6 */ 3.7 -int ctrl_if_send_message_noblock( 3.8 +int 3.9 +ctrl_if_send_message_noblock( 3.10 ctrl_msg_t *msg, 3.11 ctrl_msg_handler_t hnd, 3.12 unsigned long id); 3.13 @@ -52,20 +53,33 @@ int ctrl_if_send_message_noblock( 3.14 * function returns. 3.15 * 2. If @hnd is NULL then no callback is executed. 3.16 */ 3.17 -int ctrl_if_send_message_block( 3.18 +int 3.19 +ctrl_if_send_message_block( 3.20 ctrl_msg_t *msg, 3.21 ctrl_msg_handler_t hnd, 3.22 unsigned long id, 3.23 long wait_state); 3.24 3.25 /* 3.26 + * Send @msg to the domain controller. Block until the response is received, 3.27 + * and then copy it into the provided buffer, @rmsg. 3.28 + */ 3.29 +int 3.30 +ctrl_if_send_message_and_get_response( 3.31 + ctrl_msg_t *msg, 3.32 + ctrl_msg_t *rmsg, 3.33 + long wait_state); 3.34 + 3.35 +/* 3.36 * Request a callback when there is /possibly/ space to immediately send a 3.37 * message to the domain controller. This function returns 0 if there is 3.38 * already space to trasnmit a message --- in this case the callback task /may/ 3.39 * still be executed. If this function returns 1 then the callback /will/ be 3.40 * executed when space becomes available. 3.41 */ 3.42 -int ctrl_if_enqueue_space_callback(struct tq_struct *task); 3.43 +int 3.44 +ctrl_if_enqueue_space_callback( 3.45 + struct tq_struct *task); 3.46 3.47 /* 3.48 * Send a response (@msg) to a message from the domain controller. This will 3.49 @@ -74,7 +88,9 @@ int ctrl_if_enqueue_space_callback(struc 3.50 * 1. The @msg is copied and so can be freed after this function returns. 3.51 * 2. The @msg may be the original request message, modified in-place. 3.52 */ 3.53 -void ctrl_if_send_response(ctrl_msg_t *msg); 3.54 +void 3.55 +ctrl_if_send_response( 3.56 + ctrl_msg_t *msg); 3.57 3.58 /* 3.59 * Register a receiver for typed messages from the domain controller. The 3.60 @@ -93,7 +109,9 @@ int ctrl_if_register_receiver( 3.61 * Unregister a receiver for typed messages from the domain controller. The 3.62 * handler (@hnd) will not be executed after this function returns. 3.63 */ 3.64 -void ctrl_if_unregister_receiver(u8 type, ctrl_msg_handler_t hnd); 3.65 +void 3.66 +ctrl_if_unregister_receiver( 3.67 + u8 type, ctrl_msg_handler_t hnd); 3.68 3.69 /* Suspend/resume notifications. */ 3.70 void ctrl_if_suspend(void);
4.1 --- a/tools/python/xen/lowlevel/xu/xu.c Fri Aug 27 02:47:12 2004 +0000 4.2 +++ b/tools/python/xen/lowlevel/xu/xu.c Fri Aug 27 12:28:34 2004 +0000 4.3 @@ -325,10 +325,10 @@ static PyObject *xu_message_set_response 4.4 switch ( TYPE(xum->msg.type, xum->msg.subtype) ) 4.5 { 4.6 case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED): 4.7 - P2C(blkif_fe_driver_status_changed_t, nr_interfaces, u32); 4.8 + P2C(blkif_fe_driver_status_changed_t, max_handle, u32); 4.9 break; 4.10 case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED): 4.11 - P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32); 4.12 + P2C(netif_fe_driver_status_changed_t, max_handle, u32); 4.13 break; 4.14 } 4.15 4.16 @@ -435,7 +435,7 @@ static PyObject *xu_message_get_payload( 4.17 return dict; 4.18 case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED): 4.19 C2P(netif_fe_driver_status_changed_t, status, Int, Long); 4.20 - C2P(netif_fe_driver_status_changed_t, nr_interfaces, Int, Long); 4.21 + C2P(netif_fe_driver_status_changed_t, max_handle, Int, Long); 4.22 return dict; 4.23 case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT): 4.24 C2P(netif_fe_interface_connect_t, handle, Int, Long); 4.25 @@ -630,7 +630,7 @@ static PyObject *xu_message_new(PyObject 4.26 break; 4.27 case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED): 4.28 P2C(netif_fe_driver_status_changed_t, status, u32); 4.29 - P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32); 4.30 + P2C(netif_fe_driver_status_changed_t, max_handle, u32); 4.31 break; 4.32 } 4.33
5.1 --- a/tools/python/xen/xend/server/netif.py Fri Aug 27 02:47:12 2004 +0000 5.2 +++ b/tools/python/xen/xend/server/netif.py Fri Aug 27 12:28:34 2004 +0000 5.3 @@ -333,8 +333,9 @@ class NetifController(controller.SplitCo 5.4 def recv_fe_driver_status_changed(self, msg, req): 5.5 if not req: return 5.6 msg = packMsg('netif_fe_driver_status_changed_t', 5.7 - { 'status' : NETIF_DRIVER_STATUS_UP, 5.8 - 'nr_interfaces' : len(self.devices) }) 5.9 + { 'status' : NETIF_DRIVER_STATUS_UP, 5.10 + ## FIXME: max_handle should be max active interface id 5.11 + 'max_handle' : len(self.devices) }) 5.12 self.writeRequest(msg) 5.13 for dev in self.devices.values(): 5.14 dev.attach_fe_device()
6.1 --- a/xen/include/hypervisor-ifs/io/domain_controller.h Fri Aug 27 02:47:12 2004 +0000 6.2 +++ b/xen/include/hypervisor-ifs/io/domain_controller.h Fri Aug 27 12:28:34 2004 +0000 6.3 @@ -76,6 +76,7 @@ typedef struct { 6.4 #define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED 32 6.5 #define CMSG_BLKIF_FE_INTERFACE_CONNECT 33 6.6 #define CMSG_BLKIF_FE_INTERFACE_DISCONNECT 34 6.7 +#define CMSG_BLKIF_FE_INTERFACE_QUERY 35 6.8 6.9 /* These are used by both front-end and back-end drivers. */ 6.10 #define blkif_vdev_t u16 6.11 @@ -87,7 +88,7 @@ typedef struct { 6.12 * Notify a guest about a status change on one of its block interfaces. 6.13 * If the interface is DESTROYED or DOWN then the interface is disconnected: 6.14 * 1. The shared-memory frame is available for reuse. 6.15 - * 2. Any unacknowledged messgaes pending on the interface were dropped. 6.16 + * 2. Any unacknowledged messages pending on the interface were dropped. 6.17 */ 6.18 #define BLKIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */ 6.19 #define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */ 6.20 @@ -103,10 +104,13 @@ typedef struct { 6.21 * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED: 6.22 * Notify the domain controller that the front-end driver is DOWN or UP. 6.23 * When the driver goes DOWN then the controller will send no more 6.24 - * status-change notifications. When the driver comes UP then the controller 6.25 - * will send a notification for each interface that currently exists. 6.26 + * status-change notifications. 6.27 * If the driver goes DOWN while interfaces are still UP, the domain 6.28 * will automatically take the interfaces DOWN. 6.29 + * 6.30 + * NB. The controller should not send an INTERFACE_STATUS_CHANGED message 6.31 + * for interfaces that are active when it receives an UP notification. We 6.32 + * expect that the frontend driver will query those interfaces itself. 6.33 */ 6.34 #define BLKIF_DRIVER_STATUS_DOWN 0 6.35 #define BLKIF_DRIVER_STATUS_UP 1 6.36 @@ -114,11 +118,8 @@ typedef struct { 6.37 /* IN */ 6.38 u32 status; /* 0: BLKIF_DRIVER_STATUS_??? */ 6.39 /* OUT */ 6.40 - /* 6.41 - * Tells driver how many interfaces it should expect to immediately 6.42 - * receive notifications about. 6.43 - */ 6.44 - u32 nr_interfaces; /* 4 */ 6.45 + /* Driver should query interfaces [0..max_handle]. */ 6.46 + u32 max_handle; /* 4 */ 6.47 } PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */ 6.48 6.49 /* 6.50 @@ -142,6 +143,18 @@ typedef struct { 6.51 u32 handle; /* 0 */ 6.52 } PACKED blkif_fe_interface_disconnect_t; /* 4 bytes */ 6.53 6.54 +/* 6.55 + * CMSG_BLKIF_FE_INTERFACE_QUERY: 6.56 + */ 6.57 +typedef struct { 6.58 + /* IN */ 6.59 + u32 handle; /* 0 */ 6.60 + /* OUT */ 6.61 + u32 status; /* 4 */ 6.62 + u16 evtchn; /* 8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */ 6.63 + domid_t domid; /* 10: status != BLKIF_INTERFACE_STATUS_DESTROYED */ 6.64 +} PACKED blkif_fe_interface_query_t; /* 12 bytes */ 6.65 + 6.66 6.67 /****************************************************************************** 6.68 * BLOCK-INTERFACE BACKEND DEFINITIONS 6.69 @@ -332,6 +345,7 @@ typedef struct { 6.70 #define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED 32 6.71 #define CMSG_NETIF_FE_INTERFACE_CONNECT 33 6.72 #define CMSG_NETIF_FE_INTERFACE_DISCONNECT 34 6.73 +#define CMSG_NETIF_FE_INTERFACE_QUERY 35 6.74 6.75 /* 6.76 * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED: 6.77 @@ -355,10 +369,13 @@ typedef struct { 6.78 * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED: 6.79 * Notify the domain controller that the front-end driver is DOWN or UP. 6.80 * When the driver goes DOWN then the controller will send no more 6.81 - * status-change notifications. When the driver comes UP then the controller 6.82 - * will send a notification for each interface that currently exists. 6.83 + * status-change notifications. 6.84 * If the driver goes DOWN while interfaces are still UP, the domain 6.85 * will automatically take the interfaces DOWN. 6.86 + * 6.87 + * NB. The controller should not send an INTERFACE_STATUS_CHANGED message 6.88 + * for interfaces that are active when it receives an UP notification. We 6.89 + * expect that the frontend driver will query those interfaces itself. 6.90 */ 6.91 #define NETIF_DRIVER_STATUS_DOWN 0 6.92 #define NETIF_DRIVER_STATUS_UP 1 6.93 @@ -366,11 +383,8 @@ typedef struct { 6.94 /* IN */ 6.95 u32 status; /* 0: NETIF_DRIVER_STATUS_??? */ 6.96 /* OUT */ 6.97 - /* 6.98 - * Tells driver how many interfaces it should expect to immediately 6.99 - * receive notifications about. 6.100 - */ 6.101 - u32 nr_interfaces; /* 4 */ 6.102 + /* Driver should query interfaces [0..max_handle]. */ 6.103 + u32 max_handle; /* 4 */ 6.104 } PACKED netif_fe_driver_status_changed_t; /* 8 bytes */ 6.105 6.106 /* 6.107 @@ -396,6 +410,19 @@ typedef struct { 6.108 u32 handle; /* 0 */ 6.109 } PACKED netif_fe_interface_disconnect_t; /* 4 bytes */ 6.110 6.111 +/* 6.112 + * CMSG_NETIF_FE_INTERFACE_QUERY: 6.113 + */ 6.114 +typedef struct { 6.115 + /* IN */ 6.116 + u32 handle; /* 0 */ 6.117 + /* OUT */ 6.118 + u32 status; /* 4 */ 6.119 + u16 evtchn; /* 8: status == NETIF_INTERFACE_STATUS_CONNECTED */ 6.120 + u8 mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */ 6.121 + domid_t domid; /* 16: status != NETIF_INTERFACE_STATUS_DESTROYED */ 6.122 +} PACKED netif_fe_interface_query_t; /* 18 bytes */ 6.123 + 6.124 6.125 /****************************************************************************** 6.126 * NETWORK-INTERFACE BACKEND DEFINITIONS