network: replacing the continuation manager with simple queues
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 31 Oct 2016 14:08:59 +0000 (15:08 +0100)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Mon, 31 Oct 2016 14:08:59 +0000 (15:08 +0100)
e1000: small performance tweaks

Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

28 files changed:
if/net_queue_manager.if
if/net_soft_filters.if
include/net_queue_manager/net_queue_manager.h
kernel/arch/x86_64/irq.c
kernel/arch/x86_64/syscall.c
kernel/cap_delete.c
kernel/dispatch.c
kernel/include/dispatch.h
kernel/include/schedule.h
kernel/schedule_rbed.c
lib/lwip/src/barrelfish/idc_barrelfish.h
lib/lwip/src/barrelfish/idc_net_control.c
lib/lwip/src/core/memp.c
lib/lwip/src/netif/bfeth.c
lib/net_device_manager/Hakefile
lib/net_device_manager/port_service_impl.c
lib/net_device_manager/soft_filt_cl_impl.c
lib/net_interfaces/Hakefile
lib/net_interfaces/interface_raw.c
lib/net_queue_manager/Hakefile
lib/net_queue_manager/QM_benchmark.c
lib/net_queue_manager/net_soft_filters_srv_impl.c
lib/net_queue_manager/queue_manager.c
tools/qemu-wrapper.sh
usr/drivers/e1000/e1000n.c
usr/drivers/e1000/e1000n.h
usr/drivers/e1000/e1000n_hwinit.c
usr/netd/ARP_lookup_service.c

index 33e2210..cf14ab6 100644 (file)
 interface net_queue_manager "Ethernet hardware RX/TX queue manager" {
     /* antoinek: I think most of the queue id arguments are not needed here */
 
-    message register_buffer(cap buf,
-                         cap sp,
-                         uint64 queueid,
-                         uint64 slots,
-                         uint8 role);
-    message new_buffer_id(errval err,
-                         uint64 queueid,
-                         uint64 idx);
-
-    message get_mac_address(uint64 queueid);
-    message get_mac_address_response(uint64 queueid, uint64 hwaddr);
+    rpc register_buffer(in cap buf,
+                         in cap sp,
+                         in uint64 queueid,
+                         in uint64 slots,
+                         in uint8 role,
+                         in cap queue,
+                         out uint64 idx);
+    rpc get_mac_address(in uint64 queueid, out uint64 hwaddr);
 
     message sp_notification_from_app(uint64 queueid, uint64 type,
                          uint64 ts);
@@ -32,7 +29,6 @@ interface net_queue_manager "Ethernet hardware RX/TX queue manager" {
     message raw_xmit_done(uint64 offset, uint64 length, uint64 more,
                            uint64 flags);
 
-
     message print_statistics(uint64 queueid);
     message print_cardinfo();
     message benchmark_control_request(uint64 queueid, uint8 state,
index 3a15a35..212a7cc 100644 (file)
@@ -9,49 +9,36 @@
 
 interface net_soft_filters "Software based filter Interface" {
 
-    message register_filter_memory_request(cap mem);
-    message register_filter_memory_response(errval err);
-
-    message register_filter_request(uint64 id,
-            uint64 len_rx,
-            uint64 len_tx,
-            uint64 buffer_id_rx,
-            uint64 buffer_id_tx,
-            uint64 filter_type,
-            uint64 paused);
-    message register_filter_response(uint64 id,
-            errval err,
-            uint64 filter_id,
-            uint64 buffer_id_rx,
-            uint64 buffer_id_tx,
-            uint64 filter_type);
-
-    message re_register_filter_request(uint64 filter_id,
-            uint64 buffer_id_rx,
-            uint64 buffer_id_tx);
-    message re_register_filter_response(errval err,
-            uint64 filter_id,
-            uint64 buffer_id_rx,
-            uint64 buffer_id_tx);
-
-    message deregister_filter_request(uint64 filter_id);
-    message deregister_filter_response(errval err,
-            uint64 filter_id);
-
-    message register_arp_filter_request(uint64 id,
-            uint64 len_rx,
-            uint64 len_tx);
-    message register_arp_filter_response(uint64 id,
-            errval err);
-
-    message pause(uint64 filter_id, uint64 buffer_id_rx, uint64 buffer_id_tx);
-    message pause_response(uint64 filter_id, errval err);
-    message unpause(uint64 filter_id);
-    message unpause_response(uint64 filter_id, errval err);
+    rpc register_filter_memory(in cap mem, out errval err);
+
+    rpc register_filter(in uint64 id,
+            in uint64 len_rx,
+            in uint64 len_tx,
+            in uint64 buffer_id_rx,
+            in uint64 buffer_id_tx,
+            in uint64 filter_type,
+            in uint64 paused,
+            out errval err,
+            out uint64 filter_id);
+
+    rpc re_register_filter(in uint64 filter_id,
+            in uint64 buffer_id_rx,
+            in uint64 buffer_id_tx,
+            out errval err);
+
+    rpc deregister_filter(in uint64 filter_id,
+            out errval err);
+
+    rpc register_arp_filter(in uint64 id,
+            in uint64 len_rx,
+            in uint64 len_tx,
+            out errval err);
+
+    rpc pause(in uint64 filter_id, in uint64 buffer_id_rx, in uint64 buffer_id_tx,
+            out errval err);
+    rpc unpause(in uint64 filter_id, out errval err);
 
     /* Hack to pass the mac addr info to */
-    message mac_address_request();
-    message mac_address_response(errval err, uint64 macaddr);
+    rpc mac_address(out errval err, out uint64 macaddr);
 };
 
-
index 7a98701..92a5613 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/bulk_transfer.h>
-#include <contmng/contmng.h>
 #include <contmng/netbench.h>
 #include <procon/procon.h>
 #include <barrelfish/net_constants.h>
@@ -135,7 +134,7 @@ struct client_closure {
     uint64_t queueid; // The queueid to which this buffer belongs
     struct net_queue_manager_binding *app_connection; // Binding pointer to talk back
     struct cont_queue *q; // Cont management queue to report events
-
+    uint64_t *queue;
 
     // Place to store data when there are multiple parts to the packet
     struct driver_buffer driver_buff_list[MAX_CHUNKS]; // list of already seen chunks
@@ -251,6 +250,8 @@ void do_pending_work_for_all(void);
 //debug
 void print_statistics(void);
 
+void check_queues(void);
+
 
 // For recording statistics
 
index f8b179c..b43e937 100644 (file)
@@ -643,7 +643,7 @@ errval_t irq_table_notify_domains(struct kcb *kcb)
         if (kcb->irq_dispatch[i].cap.type == ObjType_EndPoint) {
             struct capability *cap = &kcb->irq_dispatch[i].cap;
             // 1 word message as notification
-            errval_t err = lmp_deliver_payload(cap, NULL, msg, 1, false);
+            errval_t err = lmp_deliver_payload(cap, NULL, msg, 1, false, false);
             if (err_is_fail(err)) {
                 if (err_no(err) == SYS_ERR_LMP_BUF_OVERFLOW) {
                     struct dispatcher_shared_generic *disp =
@@ -1012,7 +1012,7 @@ static __attribute__ ((used)) void handle_irq(int vector)
                              NULL,
                              (uintptr_t*) &data,
                              payload_len,
-                             false);
+                             false, false);
 
             // Make sure delivery was okay. SYS_ERR_LMP_BUF_OVERFLOW is okay for now
             assert(err_is_ok(err) || err_no(err)==SYS_ERR_LMP_BUF_OVERFLOW);
index 2c6e7a4..7bca085 100644 (file)
@@ -1369,7 +1369,7 @@ struct sysret sys_syscall(uint64_t syscall, uint64_t arg0, uint64_t arg1,
             retval.error = lmp_deliver(to, dcb_current, args, length_words,
                                        arg1, send_level, give_away);
 
-            /* Switch to reciever upon successful delivery with sync flag,
+            /* Switch to receiver upon successful delivery with sync flag,
              * or (some cases of) unsuccessful delivery with yield flag */
             enum err_code err_code = err_no(retval.error);
             if ((sync && err_is_ok(retval.error)) ||
@@ -1400,52 +1400,55 @@ struct sysret sys_syscall(uint64_t syscall, uint64_t arg0, uint64_t arg1,
                     save_area = &disp->enabled_save_area;
                 }
 
-               // Should be enabled. Else, how do we do an invocation??
-               if(dcb_current->disabled) {
-                 panic("Dispatcher needs to be enabled for this invocation");
-               }
-
-               // save calling dispatcher's registers, so that when the dispatcher
-               // next runs, it has a valid state in the relevant save area.
-               // Save RIP, RFLAGS, RSP and set RAX (return value) for later resume
-               save_area->rax = retval.error; // XXX: x86 1st return register
-               save_area->rip = rip;
-               save_area->eflags = rflags;
-               save_area->rsp = user_stack_save;
-
-               if(!dcb_current->is_vm_guest) {
-                 /* save and zero FS/GS selectors (they're unmodified by the syscall path) */
-                 __asm ("mov     %%fs, %[fs]     \n\t"
-                        "mov     %%gs, %[gs]     \n\t"
-                        "mov     %[zero], %%fs   \n\t"
-                        "mov     %[zero], %%gs   \n\t"
-                        : /* No output */
-                        :
-                        [fs] "m" (save_area->fs),
-                        [gs] "m" (save_area->gs),
-                        [zero] "r" (0)
-                        );
-               } else {
+                // Should be enabled. Else, how do we do an invocation??
+                if (dcb_current->disabled) {
+                    panic("Dispatcher needs to be enabled for this invocation");
+                }
+
+                // save calling dispatcher's registers, so that when the dispatcher
+                // next runs, it has a valid state in the relevant save area.
+                // Save RIP, RFLAGS, RSP and set RAX (return value) for later resume
+                save_area->rax = retval.error; // XXX: x86 1st return register
+                save_area->rip = rip;
+                save_area->eflags = rflags;
+                save_area->rsp = user_stack_save;
+
+                if (!dcb_current->is_vm_guest) {
+                    /* save and zero FS/GS selectors (they're unmodified by the syscall path) */
+                    __asm ("mov     %%fs, %[fs]     \n\t"
+                    "mov     %%gs, %[gs]     \n\t"
+                    "mov     %[zero], %%fs   \n\t"
+                    "mov     %[zero], %%gs   \n\t"
+                    : /* No output */
+                    :
+                    [fs] "m" (save_area->fs),
+                    [gs] "m" (save_area->gs),
+                    [zero] "r" (0)
+                    );
+                } else {
 #ifndef __k1om__
 #ifdef CONFIG_SVM
-                 lpaddr_t lpaddr = gen_phys_to_local_phys(dcb_current->guest_desc.vmcb.cap.u.frame.base);
-                 amd_vmcb_t vmcb;
-                 amd_vmcb_initialize(&vmcb, (void *)local_phys_to_mem(lpaddr));
-                 save_area->fs = amd_vmcb_fs_selector_rd(&vmcb);
-                 save_area->gs = amd_vmcb_gs_selector_rd(&vmcb);
+                    lpaddr_t lpaddr = gen_phys_to_local_phys(dcb_current->guest_desc.vmcb.cap.u.frame.base);
+                    amd_vmcb_t vmcb;
+                    amd_vmcb_initialize(&vmcb, (void *)local_phys_to_mem(lpaddr));
+                    save_area->fs = amd_vmcb_fs_selector_rd(&vmcb);
+                    save_area->gs = amd_vmcb_gs_selector_rd(&vmcb);
 #else
-                  errval_t err;
-                  err = vmread(VMX_GUEST_FS_SEL, (uint64_t *)&save_area->fs);
-                  err += vmread(VMX_GUEST_GS_SEL, (uint64_t *)&save_area->gs);
-                  assert(err_is_ok(err));
+                    errval_t err;
+                    err = vmread(VMX_GUEST_FS_SEL, (uint64_t *)&save_area->fs);
+                    err += vmread(VMX_GUEST_GS_SEL, (uint64_t *)&save_area->gs);
+                    assert(err_is_ok(err));
 #endif
 #else
-          panic("VM Guests not supported on Xeon Phi");
+                    panic("VM Guests not supported on Xeon Phi");
 #endif
-               }
-
+                       }
                 dispatch(to->u.endpoint.listener);
                 panic("dispatch returned");
+            } else {
+                struct dcb *dcb = to->u.endpoint.listener;
+
+                schedule_now(dcb);
             }
         } else { // not endpoint cap, call kernel handler through dispatch table
             // printk(LOG_NOTE, "sys_invoke: to->type = %d, cmd = %"PRIu64"\n",
index 259055d..556ceb8 100644 (file)
@@ -135,7 +135,7 @@ errval_t caps_delete_last(struct cte *cte, struct cte *ret_ram_cap)
             monitor_ep.u.endpoint.listener = NULL;
         } else if (monitor_ep.u.endpoint.listener != NULL) {
             uintptr_t payload = dcb->domain_id;
-            err = lmp_deliver_payload(&monitor_ep, NULL, &payload, 1, false);
+            err = lmp_deliver_payload(&monitor_ep, NULL, &payload, 1, false, false);
             if (err_is_fail(err)) {
                 printk(LOG_NOTE, "while notifying monitor about domain exit: %"PRIuERRV".\n", err);
                 printk(LOG_NOTE, "please add the console output to the following bug report: https://code.systems.ethz.ch/T78\n");
@@ -292,7 +292,7 @@ cleanup_last(struct cte *cte, struct cte *ret_ram_cap)
             // XXX: This looks pretty ugly. We need an interface.
             err = lmp_deliver_payload(&monitor_ep, NULL,
                                       (uintptr_t *)&ram,
-                                      len, false);
+                                      len, false, false);
         }
         else {
             printk(LOG_WARN, "dropping ram cap base %08"PRIxGENPADDR" bytes 0x%"PRIxGENSIZE"\n", ram.base, ram.bytes);
index b19dc41..7eb7501 100644 (file)
@@ -180,11 +180,11 @@ void __attribute__ ((noreturn)) dispatch(struct dcb *dcb)
         disp->systime = kernel_now + kcb_current->kernel_off;
     }
     TRACE(KERNEL, SC_YIELD, 1);
-       
+
     if (dcb->disabled) {
         if (disp != NULL) {
-            debug(SUBSYS_DISPATCH, "resume %.*s at 0x%" PRIx64 ", %s\n", 
-                 DISP_NAME_LEN, disp->name, 
+            debug(SUBSYS_DISPATCH, "resume %.*s at 0x%" PRIx64 ", %s\n",
+                 DISP_NAME_LEN, disp->name,
                  (uint64_t)registers_get_ip(disabled_area),
                  disp->disabled ? "disp->disabled" : "disp->enabled"
                );
@@ -372,7 +372,7 @@ errval_t lmp_can_deliver_payload(struct capability *ep,
  */
 errval_t lmp_deliver_payload(struct capability *ep, struct dcb *send,
                              uintptr_t *payload, size_t payload_len,
-                             bool captransfer)
+                             bool captransfer, bool now)
 {
     assert(ep != NULL);
     assert(ep->type == ObjType_EndPoint);
@@ -433,6 +433,8 @@ errval_t lmp_deliver_payload(struct capability *ep, struct dcb *send,
 
     // Make target runnable
     make_runnable(recv);
+    if (now)
+        schedule_now(recv);
 
     return SYS_ERR_OK;
 }
@@ -479,7 +481,7 @@ errval_t lmp_deliver(struct capability *ep, struct dcb *send,
     }
 
     /* Send msg */
-    err = lmp_deliver_payload(ep, send, payload, len, captransfer);
+    err = lmp_deliver_payload(ep, send, payload, len, captransfer, false);
     // shouldn't fail, if we delivered the cap successfully
     assert(!(captransfer && err_is_fail(err)));
     return err;
index c3ea413..a36bdee 100644 (file)
@@ -83,7 +83,7 @@ errval_t lmp_can_deliver_payload(struct capability *ep,
                                  size_t payload_len);
 errval_t lmp_deliver_payload(struct capability *ep, struct dcb *send,
                              uintptr_t *payload, size_t payload_len,
-                             bool captransfer);
+                             bool captransfer, bool now);
 errval_t lmp_deliver(struct capability *ep, struct dcb *send,
                      uintptr_t *payload, size_t payload_len,
                      capaddr_t send_cptr, uint8_t send_bits, bool give_away);
@@ -91,7 +91,7 @@ errval_t lmp_deliver(struct capability *ep, struct dcb *send,
 /// Deliver an empty LMP as a notification
 static inline errval_t lmp_deliver_notification(struct capability *ep)
 {
-    return lmp_deliver_payload(ep, NULL, NULL, 0, false);
+    return lmp_deliver_payload(ep, NULL, NULL, 0, false, true);
 }
 
 /// Reset csc
index 2b2e02f..f898f48 100644 (file)
@@ -17,6 +17,7 @@
 
 struct dcb *schedule(void);
 void make_runnable(struct dcb *dcb);
+void schedule_now(struct dcb *dcb);
 void scheduler_remove(struct dcb *dcb);
 void scheduler_yield(struct dcb *dcb);
 void scheduler_reset_time(void);
index 11245b4..e5df532 100644 (file)
@@ -427,6 +427,14 @@ struct dcb *schedule(void)
     goto start_over;
 }
 
+void schedule_now(struct dcb *dcb)
+{
+    if (dcb->release_time >= kernel_now) {
+        dcb->release_time = kernel_now;
+    }
+    dcb->deadline = 1;
+}
+
 void make_runnable(struct dcb *dcb)
 {
     // No-Op if already in schedule
index 6ddb656..9c83337 100644 (file)
@@ -22,7 +22,6 @@
 #include <lwip/ip_addr.h>
 #include <if/net_queue_manager_defs.h>
 #include <procon/procon.h>
-#include <contmng/contmng.h>
 
 /**
  * \brief Receive and transmit sides
index 57ac9ee..c8f8141 100644 (file)
@@ -22,7 +22,6 @@
 #include <netif/etharp.h>
 #include <netif/bfeth.h>
 #include "lwip/init.h"
-#include <contmng/contmng.h>
 #include <contmng/netbench.h>
 #include <if/net_ports_defs.h>
 #include <if/net_ports_rpcclient_defs.h>
index a771261..4eddcc7 100644 (file)
@@ -399,7 +399,6 @@ void memp_initialize_pbuf_list(void)
 
         /* create a linked list of memp elements */
         for (j = 0; j < memp_num[i]; ++j) {
-            memp->next = NULL;
             memp->next = memp_tab[i];
             memp_tab[i] = memp;
             memp = (struct memp *) ((u8_t *) memp + memp_sizes[i]);
index 62c78e3..ad6f38b 100644 (file)
@@ -264,11 +264,6 @@ bfeth_input(struct netif *netif, uint64_t pbuf_id, uint64_t paddr, uint64_t len,
 
     }
 
-    // Check if there is anything else that we should before sending back the
-    // ack that we consumed packet.
-
-    perform_lwip_work();
-
     //now we have consumed the preregistered pbuf containing a received packet
     //which was processed in this function. Therefore we have to register a new
     //free buffer for receiving packets. We can reuse the odl buffer's index
index 7198427..e6760e7 100644 (file)
@@ -15,7 +15,8 @@
                   "soft_filt_cl_impl.c", "e10k_filt_cl_impl.c", "portalloc.c" ],
                   flounderBindings = [ "net_soft_filters", "net_ports",
                                        "e10k" ],
-                  addLibraries = [ "contmng", "bfdmuxtools", "trace"
+                  flounderExtraBindings = [ ("net_soft_filters", ["rpcclient"])],
+                  addLibraries = [ "bfdmuxtools", "trace"
 -- try to get rid of "lwip" as it is only used for hton[s/l]
                     , "lwip"
                   ]
index a7a4fd6..b1cf604 100644 (file)
@@ -276,6 +276,10 @@ static errval_t res_port(struct net_ports_binding *cc,
     bp->closing = false;
     bp->redirected = false;
 
+    // add this flow to the list of all flows for this app
+    bp->next = this_net_app->open_ports;
+    this_net_app->open_ports = bp;
+
     // FIXME: qlist[queueid].insert_rule();
     err = qlist[queueid].filt_mng->reg_filters(port, type, buffer_id_rx,
             buffer_id_tx, appid, queueid);
@@ -287,10 +291,6 @@ static errval_t res_port(struct net_ports_binding *cc,
         return err;
     } // end if: err
 
-    // add this flow to the list of all flows for this app
-    bp->next = this_net_app->open_ports;
-    this_net_app->open_ports = bp;
-
     NDM_DEBUG("res_port: waiting for response\n");
     return err;
 } // end function: res_port
@@ -701,3 +701,4 @@ static void wrapper_close_port_response(struct net_ports_binding *cc,
 }
 
 
+
index c6220d7..cd00f92 100755 (executable)
@@ -15,8 +15,8 @@
 #include <barrelfish/bulk_transfer.h>
 //#include <net_device_manager/net_ports_service.h>
 #include <if/net_soft_filters_defs.h>
+#include <if/net_soft_filters_rpcclient_defs.h>
 //#include <if/net_ports_defs.h>
-#include <contmng/contmng.h>
 
 // For filter generation
 #include <bfdmuxtools/tools.h>
 #define REDIRECT_FILTER      (2)
 
 /****************************************************************
-* Global datastructure
-*****************************************************************/
-// client closure for connection between netd and ethernet driver
-struct client_closure_ND {
-    struct cont_queue *q;
-};
-
-
-/****************************************************************
 * Local states
 *****************************************************************/
 
@@ -98,37 +89,10 @@ static struct filters_tx_vtbl soft_filts_mng = {
 static void share_common_memory_with_filter_manager(void);
 static void sf_mac_lookup(void);
 
-static void register_filter_memory_response(
-                        struct net_soft_filters_binding *st,
-                        errval_t err);
 static void send_soft_filter(uint64_t id, uint64_t len_rx, uint64_t len_tx,
                                 uint64_t buffer_id_rx, uint64_t buffer_id_tx,
                                 uint8_t ftype, uint8_t paused);
 
-
-static void deregister_filter_response(struct net_soft_filters_binding *st,
-                                       errval_t err, uint64_t filter_id);
-static void register_filter_response(struct net_soft_filters_binding *st,
-                                     uint64_t id, errval_t err,
-                                     uint64_t filter_id, uint64_t buffer_id_rx,
-                                     uint64_t buffer_id_tx, uint64_t ftype);
-static void register_arp_filter_response(struct net_soft_filters_binding *st,
-                                         uint64_t id, errval_t err);
-
-
-static void sf_mac_address_response(struct net_soft_filters_binding *st,
-                      errval_t err,  uint64_t mac);
-
-
-static struct net_soft_filters_rx_vtbl rx_vtbl = {
-    .register_filter_memory_response = register_filter_memory_response,
-    .register_filter_response = register_filter_response,
-    .deregister_filter_response = deregister_filter_response,
-    .register_arp_filter_response = register_arp_filter_response,
-//    .pause_response = pause_response,
-    .mac_address_response = sf_mac_address_response,
-};
-
 // *****************************************************************
 // * Get signature of this service
 // *****************************************************************
@@ -187,17 +151,9 @@ static void soft_filters_bind_cb(void *st, errval_t err,
     }
     NDM_DEBUG("soft_filters_bind_cb: started\n");
 
-
-    struct client_closure_ND *ccnd = (struct client_closure_ND *)
-      malloc(sizeof(struct client_closure_ND));
-
-    memset(ccnd, 0, sizeof(struct client_closure_ND));
-    ccnd->q = create_cont_q("SF_C");
-
-    // set client closure
-    enb->st = ccnd;
-    // copy my message receive handler vtable to the binding
-    enb->rx_vtbl = rx_vtbl;
+    struct net_soft_filters_rpc_client *rpc_client = malloc(sizeof(struct net_soft_filters_rpc_client));
+    net_soft_filters_rpc_client_init(rpc_client, enb);
+    enb->st = rpc_client;
 
     soft_filters_connection = enb;
     NDM_DEBUG(" soft_filters_bind_cb: connection made,"
@@ -264,38 +220,6 @@ static void connect_soft_filters_service(char *dev_name, qid_t qid)
 // * filter memory registration
 // * One time process
 // *****************************************************************
-static errval_t send_filter_memory_cap(struct q_entry e)
-{
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.register_filter_memory_request(b,
-                                                         MKCONT
-                                                         (cont_queue_callback,
-                                                          ccnc->q), e.cap);
-    } else {
-        NDM_DEBUG("send_filter_memory_cap: Flounder busy,rtry++\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-
-/**
-* \brief: Called by driver when memory is registered with driver.
-*/
-static void register_filter_memory_response(
-                        struct net_soft_filters_binding *st,
-                        errval_t err)
-{
-    assert(err_is_ok(err));
-    soft_filters_ready = true;
-    NDM_DEBUG("########################################################\n");
-    NDM_DEBUG("memory registration successful.\n");
-}
-
-
 /**
  * \brief sends cap to the memory which is to be shared between filter_manager
  *   of network driver and netd.
@@ -303,19 +227,14 @@ static void register_filter_memory_response(
  */
 static void register_filter_memory(struct capref cap)
 {
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_filter_memory_cap;
     struct net_soft_filters_binding *b = soft_filters_connection;
+    struct net_soft_filters_rpc_client *rpc = b->st;
 
-    entry.binding_ptr = (void *) b;
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    entry.cap = cap;
-    enqueue_cont_q(ccnc->q, &entry);
-
-    NDM_DEBUG("register_filter_memory: terminated\n");
+    errval_t err, rerr;
+    err = rpc->vtbl.register_filter_memory(rpc, cap, &rerr);
+    assert(err_is_ok(err));
+    assert(err_is_ok(rerr));
+    soft_filters_ready = true;
 }
 
 
@@ -350,95 +269,6 @@ static void share_common_memory_with_filter_manager(void)
     filter_mem_lock = false; // marking memory as ready to use
 } // end function: share_common_memory_with_filter_manager
 
-
-static errval_t send_mac_address_request(struct q_entry e)
-{
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.mac_address_request(b,
-                MKCONT(cont_queue_callback, ccnc->q));
-    } else {
-        NDM_DEBUG("send_mac_address_request: Flounder busy,rtry++\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-} // end function: send_mac_address_request
-
-// lookup the mac address
-static void sf_mac_lookup(void)
-{
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_mac_address_request;
-    struct net_soft_filters_binding *b = soft_filters_connection;
-
-    entry.binding_ptr = (void *) b;
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    enqueue_cont_q(ccnc->q, &entry);
-
-    // waiting for mac address response.
-    NDM_DEBUG("connect_to_ether_filter_manager: wait connection\n");
-    while (!valid_mac_addr_assigned) {
-        messages_wait_and_handle_next();
-    }
-
-
-    NDM_DEBUG("sf_mac_lookup: terminated\n");
-} // end function: sf_mac_lookup
-
-// *****************************************************************
-// * filter memory registration
-// * One time process
-// *****************************************************************
-
-static void deregister_filter_response(struct net_soft_filters_binding *st,
-                                       errval_t err, uint64_t filter_id)
-{
-    if (err_is_ok(err)) {
-        NDM_DEBUG("filter at id %" PRIu64 " deregistered.\n", filter_id);
-    }
-}
-
-static void register_filter_response(struct net_soft_filters_binding *st,
-                                     uint64_t id, errval_t err,
-                                     uint64_t filter_id, uint64_t buffer_id_rx,
-                                     uint64_t buffer_id_tx, uint64_t ftype)
-{
-    assert(err_is_ok(err));
-    NDM_DEBUG("filter at id [%" PRIu64 "] type[%" PRIu64
-               "] registered with filt_id %" PRIu64 ".\n", id, ftype,
-               filter_id);
-
-    /* free the memory in shared area */
-    errval_t free_err = bulk_free(&bt_filter_tx, id);
-
-    assert(err_is_ok(free_err));
-    filter_mem_lock = false; // NOTE: filter memory can be used by others now
-
-    handle_filter_response(id, err, filter_id, buffer_id_rx, buffer_id_tx,
-            ftype);
-
-}
-
-static void register_arp_filter_response(struct net_soft_filters_binding *st,
-                                         uint64_t id, errval_t err)
-{
-
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "register_arp_filter_response failed for ID %" PRIu64 "",
-                  id);
-        abort();
-    }
-    NDM_DEBUG("register_arp_filter_response: ARP filter ID %" PRIu64
-               " registered\n", id);
-
-    assert(!"NYI register_arp_filter_response");
-}
-
 // Support code to convert mac address from uint64_t into eth_addr type
 union mac_addr_un1 {
     struct eth_addr ethaddr;
@@ -454,46 +284,20 @@ static struct eth_addr my_convert_uint64_to_eth_addr(uint64_t given_mac)
     return tmp_mac.ethaddr;
 }
 
-
-static void sf_mac_address_response(struct net_soft_filters_binding *st,
-                      errval_t err,  uint64_t mac_addr)
+// lookup the mac address
+static void sf_mac_lookup(void)
 {
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "sf_mac_address_response failed\n");
-        abort();
-    }
-    assert(mac_addr != 0);
-
-    NDM_DEBUG("sf_mac_address_response: reported MAC addr %" PRIu64 "\n",
-            mac_addr);
+    struct net_soft_filters_binding *b = soft_filters_connection;
+    struct net_soft_filters_rpc_client *rpc = b->st;
 
+    uint64_t mac_addr;
+    errval_t err, rerr;
+    err = rpc->vtbl.mac_address(rpc, &rerr, &mac_addr);
+    assert(err_is_ok(err));
+    assert(err_is_ok(rerr));
     mac = my_convert_uint64_to_eth_addr(mac_addr);
     valid_mac_addr_assigned = true;
-}
-
-/*********  Functionality for filter registration *********/
-
-static errval_t send_filter_for_registration(struct q_entry e)
-{
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.register_filter_request(b,
-                                                  MKCONT(cont_queue_callback,
-                                                         ccnc->q), e.plist[0],
-                                                  e.plist[1], e.plist[2],
-                                                  e.plist[3], e.plist[4],
-                                                  e.plist[5], e.plist[6]);
-     // id, len_rx,  len_tx,  buf_id_rx, buf_id_rx, ftype, paused
-
-    } else {
-        NDM_DEBUG("send_filter_for_registration: ID %" PRIu64
-                   " Flounder busy,rtry++\n", e.plist[0]);
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-} // end function:
+} // end function: sf_mac_lookup
 
 /**
  * \brief sends the filter for registration to network driver.
@@ -507,98 +311,43 @@ static void send_soft_filter(uint64_t id, uint64_t len_rx,
     NDM_DEBUG("send_soft_filter: called for id %" PRIu64
                " and type %x, paused = %d\n", id, ftype, paused);
 
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_filter_for_registration;
-
     struct net_soft_filters_binding *b = soft_filters_connection;
+    struct net_soft_filters_rpc_client *rpc = b->st;
 
-    entry.binding_ptr = (void *) b;
-
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
+    errval_t err, rerr;
+    uint64_t filter_id;
+    err = rpc->vtbl.register_filter(rpc, id, len_rx, len_tx, buffer_id_rx, buffer_id_tx, ftype, paused, &rerr, &filter_id);
+    assert(err_is_ok(err));
+    assert(err_is_ok(rerr));
+    NDM_DEBUG("filter at id [%" PRIu64 "] type[%" PRIu64
+               "] registered with filt_id %" PRIu64 ".\n", id, ftype,
+               filter_id);
 
-    entry.plist[0] = id;
-    entry.plist[1] = len_rx;
-    entry.plist[2] = len_tx;
-    entry.plist[3] = buffer_id_rx;
-    entry.plist[4] = buffer_id_tx;
-    entry.plist[5] = ftype;
-    entry.plist[6] = paused;
-    /* e.plist[0], e.plist[1], e.plist[2], e.plist[3],     e.plist[4],     e.plist[4]);
-       e.id,       e.len_rx,   e.len_tx,   e.buffer_id_rx, e.buffer_id_rx, ftype */
+    /* free the memory in shared area */
+    err = bulk_free(&bt_filter_tx, id);
+    assert(err_is_ok(err));
 
-    enqueue_cont_q(ccnc->q, &entry);
+    filter_mem_lock = false; // NOTE: filter memory can be used by others now
 
-    NDM_DEBUG("send_soft_filter: terminated for id %" PRIu64 "\n", id);
+    handle_filter_response(id, err, filter_id, buffer_id_rx, buffer_id_tx,
+            ftype);
 } // end function: send_soft_filter
 
-static errval_t send_filterID_for_deregistration(struct q_entry e)
-{
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.deregister_filter_request(b,
-                                                    MKCONT(cont_queue_callback,
-                                                           ccnc->q),
-                                                    e.plist[0]);
-        /*  e.filterID */
-
-    } else {
-        NDM_DEBUG("send_filterID_for_deregistration: ID %" PRIu64
-                   " Flounder busy,rtry++\n", e.plist[0]);
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-} // end function: send_filterID_for_deregistration
-
 /**
  * \brief sends the filterID for de-registration to network driver.
  *
  */
 static void unregister_soft_filter(uint64_t filter_id, qid_t qid)
 {
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_filterID_for_deregistration;
-
     struct net_soft_filters_binding *b = soft_filters_connection;
+    struct net_soft_filters_rpc_client *rpc = b->st;
 
-    entry.binding_ptr = (void *) b;
-
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    entry.plist[0] = filter_id;
-    /*    e.plist[0]
-       e.filter_id */
-
-    enqueue_cont_q(ccnc->q, &entry);;
+    errval_t err, rerr;
+    err = rpc->vtbl.deregister_filter(rpc, filter_id, &rerr);
+    assert(err_is_ok(err));
+    assert(err_is_ok(rerr));
 } // end function: unregister_soft_filter
 
-
-static errval_t send_arp_filter_for_registration(struct q_entry e)
-{
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.register_arp_filter_request(b,
-                                                      MKCONT
-                                                      (cont_queue_callback,
-                                                       ccnc->q), e.plist[0],
-                                                      e.plist[1], e.plist[2]);
-        /*  id,         e.len_rx,   e.len_tx */
-
-    } else {
-        NDM_DEBUG("send_arp_filter_for_registration: Flounder busy,rtry++\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-
-}
-
 /**
  * \brief sends the filter for registration to network driver.
  *
@@ -607,31 +356,16 @@ static void register_arp_soft_filter(uint64_t id, uint64_t len_rx,
                                     uint64_t len_tx)
 {
     NDM_DEBUG("register_arp_soft_filter: called\n");
-
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_arp_filter_for_registration;
-
     struct net_soft_filters_binding *b = soft_filters_connection;
+    struct net_soft_filters_rpc_client *rpc = b->st;
 
-    entry.binding_ptr = (void *) b;
-
-    struct client_closure_ND *ccnc = (struct client_closure_ND *) b->st;
-
-    entry.plist[0] = id;
-    entry.plist[1] = len_rx;
-    entry.plist[2] = len_tx;
-    /*    e.plist[0], e.plist[1], e.plist[2]
-       id,         e.len_rx,   e.len_tx   */
-
-    enqueue_cont_q(ccnc->q, &entry);
+    errval_t err, rerr;
+    err = rpc->vtbl.register_arp_filter(rpc, id, len_rx, len_tx, &rerr);
+    assert(err_is_ok(err));
+    assert(err_is_ok(rerr));
 
-    NDM_DEBUG("register_arp_soft_filter: terminated\n");
 } // end function: register_arp_soft_filter
 
-
-
 static uint64_t populate_rx_tx_filter_mem(uint16_t port, net_ports_port_type_t type,
                                           int32_t * len_rx, int32_t * len_tx)
 {
@@ -704,5 +438,3 @@ static uint64_t populate_rx_tx_filter_mem(uint16_t port, net_ports_port_type_t t
     return id;
 }
 
-
-
index c05264e..f666a01 100644 (file)
@@ -13,6 +13,6 @@
 [ build library { target = "net_if_raw",
                   cFiles = [ "interface_raw.c" ],
                   flounderBindings = [ "net_queue_manager" ],
-                  addLibraries = [ "contmng" ] }
+                  flounderExtraBindings = [("net_queue_manager", ["rpcclient"])] }
 ]
 
index a8f3fa6..03f3f55 100644 (file)
 
 #include <barrelfish/net_constants.h>
 #include <if/net_queue_manager_defs.h>
-#include <contmng/contmng.h>
 
 #define MAX_SERVICE_NAME_LEN  256   // Max len that a name of service can have
 #define BUFFER_SIZE 2048
 #define BUFFER_COUNT ((128*1024*1024) / BUFFER_SIZE)
 
-
-static void idc_register_buffer(struct net_queue_manager_binding *binding,
-                                struct capref buf, struct capref sp,
-                                uint64_t qid, uint64_t slots, uint8_t role);
+#define QUEUE_SIZE 512
 
 static errval_t idc_raw_add_buffer(struct net_queue_manager_binding *binding,
-                               uint64_t offset, uint64_t len,
+                               uint64_t *queue, uint64_t offset, uint64_t len,
                                uint64_t more_chunks, uint64_t flags,
                                bool blocking);
 
-static void idc_get_mac_address(struct net_queue_manager_binding *binding,
-                                uint64_t qid);
-
 static uint64_t queue = 0;
 static uint64_t card_mac = -1ULL;
 
@@ -52,7 +45,104 @@ void *buffer_base = NULL;
 size_t buffer_size = 2048;
 size_t buffer_count = BUFFER_COUNT;
 
+static struct capref rx_queue_frame;
+uint64_t *rx_queue_base = NULL;
+static struct capref tx_queue_frame;
+uint64_t *tx_queue_base = NULL;
+
+static void init_queue(uint64_t *q)
+{
+    q[0] = 1;
+    q[1] = 1;
+    q[2] = 0;
+    q[3] = 0;
+}
+
+static int put_to_queue(uint64_t *q, uint64_t v1, uint64_t v2, uint64_t v3, uint64_t v4)
+{
+    uint64_t start = q[0];
+    uint64_t end = q[1];
+
+    if (end == (QUEUE_SIZE - 1)) {
+        assert(start > 1);
+    } else {
+        assert((end + 1) != start);
+    }
+
+    q[4 * end] = v1;
+    q[4 * end + 1] = v2;
+    q[4 * end + 2] = v3;
+    q[4 * end + 3] = v4;
+    bool s = start == end;
+    if (end == (QUEUE_SIZE - 1))
+        q[1] = 1;
+    else
+        q[1]++;
+    end = q[1];
+    bool f = (end == (QUEUE_SIZE - 1)) ? (start == 1): (start == end + 1);
+    return s + 2 * f;
+}
+
+static bool check_queue(uint64_t *q)
+{
+    uint64_t start = q[0];
+    uint64_t end = q[1];
+
+    return start != end;
+}
+
+static bool get_from_queue(uint64_t *q, uint64_t *v1, uint64_t *v2, uint64_t *v3, uint64_t *v4)
+{
+    uint64_t start = q[0];
+    uint64_t end = q[1];
+
+    assert(start != end);
+    *v1 = q[4 * start];
+    *v2 = q[4 * start + 1];
+    *v3 = q[4 * start + 2];
+    *v4 = q[4 * start + 3];
+    if (start == (QUEUE_SIZE - 1))
+        q[0] = 1;
+    else
+        q[0]++;
+    return !q[2];
+}
+
+static errval_t register_buffer(struct net_queue_manager_binding *b, struct capref buf, struct capref sp, uint64_t queueid, uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx)
+{
+    errval_t _err = SYS_ERR_OK;
+    b->error = SYS_ERR_OK;
+    thread_set_outgoing_token(thread_set_token(b->message_chanstate + net_queue_manager_register_buffer_response__msgnum));
+    _err = b->tx_vtbl.register_buffer_call(b, BLOCKING_CONT, buf, sp, queueid, slots, role, queue_cap);
+    if (err_is_fail(_err))
+        goto out;
+    _err = wait_for_channel(get_default_waitset(), b->message_chanstate + net_queue_manager_register_buffer_response__msgnum, &b->error);
+    if (err_is_fail(_err))
+        goto out;
+    *idx = b->rx_union.register_buffer_response.idx;
+    _err = b->receive_next(b);
+out:
+    thread_clear_token(b->get_receiving_chanstate(b));
+    return(_err);
+}
 
+static errval_t get_mac_address(struct net_queue_manager_binding *b, uint64_t queueid, uint64_t *hwaddr)
+{
+    errval_t _err = SYS_ERR_OK;
+    b->error = SYS_ERR_OK;
+    thread_set_outgoing_token(thread_set_token(b->message_chanstate + net_queue_manager_get_mac_address_response__msgnum));
+    _err = b->tx_vtbl.get_mac_address_call(b, BLOCKING_CONT, queueid);
+    if (err_is_fail(_err))
+        goto out;
+    _err = wait_for_channel(get_default_waitset(), b->message_chanstate + net_queue_manager_get_mac_address_response__msgnum, &b->error);
+    if (err_is_fail(_err))
+        goto out;
+    *hwaddr = b->rx_union.get_mac_address_response.hwaddr;
+    _err = b->receive_next(b);
+out:
+    thread_clear_token(b->get_receiving_chanstate(b));
+    return(_err);
+}
 
 /******************************************************************************/
 /* Buffer management */
@@ -62,7 +152,7 @@ errval_t buffer_tx_add(size_t idx, size_t offset, size_t len,
 {
 
     errval_t err = SYS_ERR_OK;
-    err = idc_raw_add_buffer(binding_tx, idx * BUFFER_SIZE + offset, len,
+    err = idc_raw_add_buffer(binding_tx, tx_queue_base, idx * BUFFER_SIZE + offset, len,
             (uint64_t)more_chunks, flags, 0);
     return err;
 }
@@ -71,7 +161,7 @@ errval_t buffer_rx_add(size_t idx)
 {
 
     errval_t err = SYS_ERR_OK;
-    err = idc_raw_add_buffer(binding_rx, idx * BUFFER_SIZE, BUFFER_SIZE, 0, 0, 1);
+    err = idc_raw_add_buffer(binding_rx, rx_queue_base, idx * BUFFER_SIZE, BUFFER_SIZE, 0, 0, 0);
     return err;
 }
 
@@ -96,156 +186,54 @@ static void alloc_mem(struct capref *frame, void** virt, size_t size)
 
 static void buffers_init(size_t count)
 {
-    struct waitset *ws = get_default_waitset();
-
     alloc_mem(&buffer_frame, &buffer_base, BUFFER_SIZE * count);
 
-    idc_register_buffer(binding_rx, buffer_frame, NULL_CAP, queue, count,
-                        RX_BUFFER_ID);
-    while (bufid_rx == -1ULL) { event_dispatch(ws); }
-
-    idc_register_buffer(binding_tx, buffer_frame, NULL_CAP, queue, count,
-                        TX_BUFFER_ID);
-    while (bufid_tx == -1ULL) { event_dispatch(ws); }
+    errval_t err;
+    void *va;
+
+    alloc_mem(&rx_queue_frame, &va, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
+    rx_queue_base = va;
+    alloc_mem(&tx_queue_frame, &va, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
+    tx_queue_base = va;
+    memset(rx_queue_base, 0, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
+    memset(tx_queue_base, 0, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2);
+    init_queue(rx_queue_base);
+    init_queue(rx_queue_base + QUEUE_SIZE * 4);
+    init_queue(tx_queue_base);
+    init_queue(tx_queue_base + QUEUE_SIZE * 4);
+
+    err = register_buffer(binding_rx, buffer_frame, NULL_CAP, queue, count,
+        RX_BUFFER_ID, rx_queue_frame, &bufid_rx);
+    assert(err_is_ok(err));
+    err = register_buffer(binding_tx, buffer_frame, NULL_CAP, queue, count,
+        TX_BUFFER_ID, tx_queue_frame, &bufid_tx);
+    assert(err_is_ok(err));
 }
 
 
 /******************************************************************************/
 /* Flounder interface */
 
-static errval_t send_raw_add_buffer(struct q_entry entry)
-{
-    struct net_queue_manager_binding *b = entry.binding_ptr;
-
-    if (b->can_send(b)) {
-
-        errval_t err = b->tx_vtbl.raw_add_buffer(
-                b, MKCONT(cont_queue_callback, b->st),
-                   entry.plist[0], entry.plist[1], entry.plist[2],
-                   entry.plist[3]);
-        return err;
-    } else {
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-
-static errval_t idc_raw_add_buffer(struct net_queue_manager_binding *binding,
+static errval_t idc_raw_add_buffer(struct net_queue_manager_binding *binding, uint64_t *q,
                                uint64_t offset, uint64_t len,
                                uint64_t more_chunks, uint64_t flags, bool blocking)
 {
-
-    struct q_entry entry;
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_raw_add_buffer;
-    entry.binding_ptr = binding;
-    entry.plist[0] = offset;
-    entry.plist[1] = len;
-    entry.plist[2] = more_chunks;
-    entry.plist[3] = flags;
-
-
-    struct waitset *ws = get_default_waitset();
-    int passed_events = 0;
-    while (can_enqueue_cont_q(binding->st) == false) {
-        if (passed_events > 5) {
-            return CONT_ERR_NO_MORE_SLOTS;
+    int r;
+    r = put_to_queue(q, offset, len, more_chunks, flags);
+    if (r) {
+        if (r == 2) {//} || binding == binding_tx) {
+            binding->control(binding, IDC_CONTROL_SET_SYNC);
         }
-        event_dispatch(ws);
-        ++passed_events;
-    }
-
-
-    if (blocking) {
-        while (queue_used_slots(binding->st) > 1) {
-            /*
-            printf("%s:The event count is %d\n", disp_name(),
-                        queue_used_slots(binding->st));
-            cont_queue_show_queue(binding->st);
-            */
-            event_dispatch(ws);
+        errval_t err = binding->tx_vtbl.raw_add_buffer(binding, BLOCKING_CONT, offset, len, more_chunks, flags);
+        assert(err_is_ok(err));
+        if (r == 2) {//} || binding == binding_tx)
+            binding->control(binding, IDC_CONTROL_CLEAR_SYNC);
         }
     }
-
-    enqueue_cont_q(binding->st, &entry);
     return SYS_ERR_OK;
 }
 
 
-static errval_t send_register_buffer(struct q_entry entry)
-{
-    struct net_queue_manager_binding *b = entry.binding_ptr;
-
-    if (b->can_send(b)) {
-//        printf("#### send_register_buffer, calling continuation\n");
-        errval_t err = b->tx_vtbl.register_buffer(
-                b, MKCONT(cont_queue_callback, b->st),
-                entry.cap, entry.cap2,
-                entry.plist[0], entry.plist[1], entry.plist[2]);
-        return err;
-    } else {
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-
-static void idc_register_buffer(struct net_queue_manager_binding *binding,
-                                struct capref buf, struct capref sp,
-                                uint64_t qid, uint64_t slots, uint8_t role)
-{
-    struct q_entry entry;
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_register_buffer;
-    entry.binding_ptr = binding;
-    entry.cap = buf;
-    entry.cap2 = sp;
-    entry.plist[0] = qid;
-    entry.plist[1] = slots;
-    entry.plist[2] = role;
-
-    enqueue_cont_q(binding->st, &entry);
-}
-
-static errval_t send_get_mac_address(struct q_entry entry)
-{
-    struct net_queue_manager_binding *b = entry.binding_ptr;
-
-    if (b->can_send(b)) {
- //       printf("#### send_get_mac_address, calling continuation\n");
-        errval_t err = b->tx_vtbl.get_mac_address(
-                b, MKCONT(cont_queue_callback, b->st),
-                entry.plist[0]);
-        return err;
-    } else {
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-
-static void idc_get_mac_address(struct net_queue_manager_binding *binding,
-                                uint64_t qid)
-{
-    struct q_entry entry;
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_get_mac_address;
-    entry.binding_ptr = binding;
-    entry.plist[0] = qid;
-
-    enqueue_cont_q(binding->st, &entry);
-}
-
-static void new_buffer_id(struct net_queue_manager_binding *st, errval_t err,
-                          uint64_t queueid, uint64_t buffer_id)
-{
-    assert(err_is_ok(err));
-
-    if (st == binding_rx) {
-        bufid_rx = buffer_id;
-    } else {
-        bufid_tx = buffer_id;
-    }
-}
-
 // Returns the bufferid for specified type (RX, TX)
 uint64_t get_rx_bufferid(void)
 {
@@ -261,25 +249,31 @@ static void raw_xmit_done(struct net_queue_manager_binding *st,
                           uint64_t offset, uint64_t len, uint64_t more,
                           uint64_t flags)
 {
-    size_t idx = offset / BUFFER_SIZE;
-
     if (st == binding_rx) {
-        benchmark_rx_done(idx, len, more, flags);
+        for (;;) {
+            bool c = check_queue(rx_queue_base + QUEUE_SIZE * 4);
+            if (c) {
+                get_from_queue(rx_queue_base + QUEUE_SIZE * 4, &offset, &len, &more, &flags);
+                size_t idx = offset / BUFFER_SIZE;
+                benchmark_rx_done(idx, len, more, flags);
+            } else
+                break;
+        }
     } else {
-        benchmark_tx_done(idx);
+        for (;;) {
+            bool c = check_queue(tx_queue_base + QUEUE_SIZE * 4);
+            if (c) {
+                get_from_queue(tx_queue_base + QUEUE_SIZE * 4, &offset, &len, &more, &flags);
+                size_t idx = offset / BUFFER_SIZE;
+                benchmark_tx_done(idx);
+            } else
+                break;
+        }
     }
 }
 
-static void get_mac_address_response(struct net_queue_manager_binding *st,
-                                     uint64_t qid, uint64_t mac)
-{
-    card_mac = mac;
-}
-
 static struct net_queue_manager_rx_vtbl rx_vtbl = {
-    .new_buffer_id = new_buffer_id,
     .raw_xmit_done = raw_xmit_done,
-    .get_mac_address_response = get_mac_address_response,
 };
 
 
@@ -287,10 +281,8 @@ static void bind_cb_rx(void *st, errval_t err, struct net_queue_manager_binding
 {
     assert(err_is_ok(err));
 
-    b->st = create_cont_q("interface_raw_rx");
-//    struct cont_queue *q = (struct cont_queue *)b->st;
-//    q->debug = 1;
     b->rx_vtbl = rx_vtbl;
+    b->control(b, IDC_CONTROL_CLEAR_SYNC);
     binding_rx = b;
 }
 
@@ -298,15 +290,13 @@ static void bind_cb_tx(void *st, errval_t err, struct net_queue_manager_binding
 {
     assert(err_is_ok(err));
 
-    b->st = create_cont_q("interface_raw_tx");
-//   struct cont_queue *q = (struct cont_queue *)b->st;
-//   q->debug = 1;
     b->rx_vtbl = rx_vtbl;
+    b->control(b, IDC_CONTROL_CLEAR_SYNC);
     binding_tx = b;
 }
 
 
-static void connect_to_driver(const char *cname, uint64_t qid, bool isRX)
+static void connect_to_driver(const char *cname, uint64_t qid, bool isRX, struct waitset *ws)
 {
     errval_t err;
     iref_t iref;
@@ -316,15 +306,9 @@ static void connect_to_driver(const char *cname, uint64_t qid, bool isRX)
     err = nameservice_blocking_lookup(qm_name, &iref);
     assert(err_is_ok(err));
 
-    if (isRX) {
-        err = net_queue_manager_bind(iref, bind_cb_rx, NULL, get_default_waitset(),
-                IDC_BIND_FLAGS_DEFAULT);
-        assert(err_is_ok(err));
-    } else {
-        err = net_queue_manager_bind(iref, bind_cb_tx, NULL, get_default_waitset(),
-                IDC_BIND_FLAGS_DEFAULT);
-        assert(err_is_ok(err));
-    }
+    err = net_queue_manager_bind(iref, isRX ? bind_cb_rx: bind_cb_tx, NULL, ws,
+            IDC_BIND_FLAGS_DEFAULT);
+    assert(err_is_ok(err));
 }
 
 void net_if_init(const char* cardname, uint64_t qid)
@@ -340,19 +324,19 @@ void net_if_init(const char* cardname, uint64_t qid)
     queue = qid;
 
     // Connect RX path
-    connect_to_driver(cardname, queue, true);
-    while (binding_rx == NULL) { event_dispatch(ws); }
-
+    connect_to_driver(cardname, queue, true, ws);
     // Connect TX path
-    connect_to_driver(cardname, queue, false);
-    while (binding_tx == NULL) { event_dispatch(ws); }
+    connect_to_driver(cardname, queue, false, ws);
+
+    while (binding_rx == NULL  || binding_tx == NULL) {
+        event_dispatch(ws);
+    }
 
     buffers_init(BUFFER_COUNT);
 
     // Get MAC address
-    idc_get_mac_address(binding_rx, queue);
-    while (card_mac == -1ULL) { event_dispatch(ws); }
-
+    errval_t err = get_mac_address(binding_rx, queue, &card_mac);
+    assert(err_is_ok(err));
 
     initialized = true;
 }
@@ -367,5 +351,3 @@ void benchmark_get_mac_address(uint8_t *mac)
 {
     memcpy(mac, &card_mac, 6);
 }
-
-
index cc4ebdf..273e2e9 100644 (file)
@@ -16,5 +16,6 @@
                   flounderDefs = [ "net_queue_manager"],
                   flounderBindings = [ "net_queue_manager",
                                        "net_soft_filters" ],
-                  addLibraries = [ "contmng", "procon", "bfdmuxvm", "trace"] }
+                  flounderExtraBindings = [ ("net_soft_filters", ["rpcclient"]) ],
+                  addLibraries = [ "procon", "bfdmuxvm", "trace"] }
 ]
index 2b461b3..8ea861c 100644 (file)
@@ -77,40 +77,11 @@ void reset_client_closure_stat(struct client_closure *cc)
 // Interface: benchmark_control
 // *****************************************************
 
-// Wrapper function:
-static errval_t send_benchmark_control_response(struct q_entry e)
-{
-    struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
-        e.binding_ptr;
-    struct client_closure *ccl = (struct client_closure *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.benchmark_control_response(b,
-                    MKCONT(cont_queue_callback, ccl->q),
-                    e.plist[0], e.plist[1], e.plist[2], e.plist[3]);
-                    // queueid, state, delta, cl
-    } else {
-        ETHERSRV_DEBUG("send_benchmark_control_response Flounder busy.."
-                " will retry\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
 static void send_benchmark_control(struct net_queue_manager_binding *cc,
         uint64_t queueid, uint64_t state, uint64_t delta, uint64_t cl)
 {
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_benchmark_control_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure *ccl = (struct client_closure *) cc->st;
-
-    entry.plist[0] = queueid;
-    entry.plist[1] = state;
-    entry.plist[2] = delta;
-    entry.plist[3] = cl;
-    enqueue_cont_q(ccl->q, &entry);
+    errval_t err = cc->tx_vtbl.benchmark_control_response(cc, NOP_CONT, queueid, state, delta, cl);
+    assert(err_is_ok(err));
 }
 
 
index 769ebe9..61a8064 100644 (file)
@@ -29,6 +29,7 @@
 #include <net_queue_manager/net_queue_manager.h>
 #include <bfdmuxvm/vm.h>
 #include <if/net_soft_filters_defs.h>
+#include <if/net_soft_filters_rpcclient_defs.h>
 #include <if/net_queue_manager_defs.h>
 #include "queue_manager_local.h"
 #include "queue_manager_debug.h"
 /* This is client_closure for filter management */
 struct client_closure_FM {
     struct net_soft_filters_binding *app_connection;       /* FIXME: Do I need this? */
-    struct cont_queue *q;
 /* FIXME: this should contain the registered buffer ptr */
 };
 
-static void register_filter_memory_request(struct net_soft_filters_binding *cc,
-                                           struct capref mem_cap);
-static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
+static errval_t register_filter_memory(struct net_soft_filters_binding *cc,
+                                           struct capref mem_cap, errval_t *rerr);
+static errval_t register_filter(struct net_soft_filters_binding *cc, uint64_t id,
                             uint64_t len_rx, uint64_t len_tx,
                             uint64_t buffer_id_rx, uint64_t buffer_id_tx,
-                            uint64_t ftype, uint64_t paused);
-static void register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
-                                uint64_t len_rx, uint64_t len_tx);
-static void deregister_filter(struct net_soft_filters_binding *cc,
-                              uint64_t filter_id);
-static void re_register_filter(struct net_soft_filters_binding *cc,
+                            uint64_t ftype, uint64_t paused, errval_t *rerr,
+                            uint64_t *filter_id);
+static errval_t register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
+                                uint64_t len_rx, uint64_t len_tx, errval_t *rerr);
+static errval_t deregister_filter(struct net_soft_filters_binding *cc,
+                              uint64_t filter_id, errval_t *rerr);
+static errval_t re_register_filter(struct net_soft_filters_binding *cc,
                                uint64_t filter_id, uint64_t buffer_id_rx,
-                               uint64_t buffer_id_tx);
-static void pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
-                         uint64_t buffer_id_rx, uint64_t buffer_id_tx);
-static void mac_address_request_sf(struct net_soft_filters_binding *cc);
+                               uint64_t buffer_id_tx, errval_t *rerr);
+static errval_t pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
+                         uint64_t buffer_id_rx, uint64_t buffer_id_tx, errval_t *rerr);
+static errval_t mac_address_request_sf(struct net_soft_filters_binding *cc,
+                                        errval_t *rerr, uint64_t *mac);
 
 // Initialize interface for soft_filters channel
-static struct net_soft_filters_rx_vtbl rx_net_soft_filters_vtbl = {
-    .register_filter_memory_request = register_filter_memory_request,
-    .register_filter_request = register_filter,
-    .re_register_filter_request = re_register_filter,
-    .deregister_filter_request = deregister_filter,
-    .register_arp_filter_request = register_arp_filter,
-    .pause = pause_filter,
-    .mac_address_request = mac_address_request_sf,
+static struct net_soft_filters_rpc_rx_vtbl rpc_rx_net_soft_filters_vtbl = {
+    .register_filter_memory_call = register_filter_memory,
+    .register_filter_call = register_filter,
+    .re_register_filter_call = re_register_filter,
+    .deregister_filter_call = deregister_filter,
+    .register_arp_filter_call = register_arp_filter,
+    .pause_call = pause_filter,
+    .mac_address_call = mac_address_request_sf,
 };
 
 
@@ -124,21 +126,19 @@ static void export_soft_filters_cb(void *st, errval_t err, iref_t iref)
     }
 }
 
-
 static errval_t connect_soft_filters_cb(void *st,
                                          struct net_soft_filters_binding *b)
 {
     ETHERSRV_DEBUG("ether_netd service got a connection!55\n");
 
     // copy my message receive handler vtable to the binding
-    b->rx_vtbl = rx_net_soft_filters_vtbl;
+    b->rpc_rx_vtbl = rpc_rx_net_soft_filters_vtbl;
     //b->error_handler = error_handler;
 
     struct client_closure_FM *ccfm =
       (struct client_closure_FM *) malloc(sizeof(struct client_closure_FM));
 
     b->st = ccfm;
-    ccfm->q = create_cont_q("FILTER-MANAGER");
     ccfm->app_connection = b;
 
     // FIXME: should I refuse more than one connections for FM services?
@@ -148,82 +148,29 @@ static errval_t connect_soft_filters_cb(void *st,
     return SYS_ERR_OK;
 } // end function: connect_soft_filters_cb
 
-
-
 /*****************************************************************
  *   filter registration
  *****************************************************************/
 
-static errval_t send_mac_address_response(struct q_entry entry)
-{
-    //    ETHERSRV_DEBUG("send_mac_address_response -----\n");
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) entry.binding_ptr;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.mac_address_response(b,
-                            MKCONT(cont_queue_callback, ccfm->q),
-                                  entry.plist[0], entry.plist[1]);
-        // entry.error, entry.mac
-    } else {
-        ETHERSRV_DEBUG("send_resigered_netd_memory Flounder bsy will retry\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-static void mac_address_request_sf(struct net_soft_filters_binding *cc)
+static errval_t mac_address_request_sf(struct net_soft_filters_binding *cc,
+    errval_t *err, uint64_t *mac)
 {
-    // call mac_address_request_sf with mac address
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_mac_address_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
-    entry.plist[0] = SYS_ERR_OK;
-    entry.plist[1] = get_mac_addr_from_device();
-       // e.error , e.mac
-
-    enqueue_cont_q(ccfm->q, &entry);
-    ETHERSRV_DEBUG("register_netd_memory: sent IDC\n");
-
+    *err = SYS_ERR_OK;
+    *mac = get_mac_addr_from_device();
+    return SYS_ERR_OK;
 } // end function: mac_address_request_sf
 
-/* FIXME: provide proper handler here */
-static errval_t send_resiger_filter_memory_response(struct q_entry entry)
-{
-    //    ETHERSRV_DEBUG("send_resigered_netd_memory  -----\n");
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) entry.binding_ptr;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.register_filter_memory_response(b,
-                                                          MKCONT
-                                                          (cont_queue_callback,
-                                                           ccfm->q),
-                                                          entry.plist[0]);
-        /* entry.error */
-    } else {
-        ETHERSRV_DEBUG("send_resigered_netd_memory Flounder bsy will retry\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
 static struct bulk_transfer_slave bt_filter_rx;
 
-static void register_filter_memory_request(struct net_soft_filters_binding *cc,
-                                           struct capref mem_cap)
+static errval_t register_filter_memory(struct net_soft_filters_binding *cc,
+                                           struct capref mem_cap, errval_t *err)
 {
-
-    errval_t err = SYS_ERR_OK;
+    *err = SYS_ERR_OK;
 
     struct frame_identity pa;
 
-    err = frame_identify(mem_cap, &pa);
-    if(!err_is_ok(err)) {
+    *err = frame_identify(mem_cap, &pa);
+    if(!err_is_ok(*err)) {
         printf("invoke_frame_identity failed\n");
         abort();
     }
@@ -232,115 +179,42 @@ static void register_filter_memory_request(struct net_soft_filters_binding *cc,
     // 2 is rx + tx
     if (pa.bytes < BASE_PAGE_SIZE * 2) {
         ETHERSRV_DEBUG("netd did not provided enough for filter transfer\n");
-        err = FILTER_ERR_NOT_ENOUGH_MEMORY;     /* ps: FIXME: enable this error */
+        *err = FILTER_ERR_NOT_ENOUGH_MEMORY;     /* ps: FIXME: enable this error */
 
     } /* end if: not enough memory */
     else {                      /* enough memory, try to map it */
         void *pool;
 
-        err = vspace_map_one_frame_attr((void *) (&pool), BASE_PAGE_SIZE * 2,
+        *err = vspace_map_one_frame_attr((void *) (&pool), BASE_PAGE_SIZE * 2,
                                         mem_cap,
                                         VREGION_FLAGS_READ_WRITE_NOCACHE, NULL,
                                         NULL);
 
-        if (err_is_fail(err)) {
-            DEBUG_ERR(err, "vspace_map_one_frame failed");
+        if (err_is_fail(*err)) {
+            DEBUG_ERR(*err, "vspace_map_one_frame failed");
             //            abort();
         } /* end if: mapping failed */
         else {
             // Init receiver
-            err = bulk_slave_init(pool, BASE_PAGE_SIZE * 2, &bt_filter_rx);
+            *err = bulk_slave_init(pool, BASE_PAGE_SIZE * 2, &bt_filter_rx);
             //            assert(err_is_ok(err));
 
         }                       /* end else: mapping sucessful */
 
     }                           /* end else : */
-
-    /* call registered_netd_memory with new IDC */
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_resiger_filter_memory_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
-    entry.plist[0] = err;
-    /* entry.plist[0]
-       entry.error */
-
-    enqueue_cont_q(ccfm->q, &entry);
-    ETHERSRV_DEBUG("register_netd_memory: sent IDC\n");
-
+    return SYS_ERR_OK;
 } /* end function : register_netd_memory */
 
-/* Handler for sending response to register_filter */
-static errval_t send_register_filter_response(struct q_entry e)
-{
-    //    ETHERSRV_DEBUG("send_resigered_filter for ID %lu  --\n", e.plist[0]);
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.register_filter_response(b,
-                                                   MKCONT(cont_queue_callback,
-                                                          ccfm->q), e.plist[0],
-                                                   e.plist[1], e.plist[2],
-                                                   e.plist[3], e.plist[4],
-                                                   e.plist[5]);
-        /* e.id,       e.error,    e.filter_id, e.buffer_id_rx,
-         * e.buffer_id_tx, e.filter_type */
-
-    } else {
-        ETHERSRV_DEBUG("send_resigered_filter: ID %" PRIu64
-                       ": Flounder bsy will retry\n", e.plist[0]);
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-static void wrapper_send_filter_registered_msg(struct net_soft_filters_binding *cc,
-                                               uint64_t id, errval_t err,
-                                               uint64_t filter_id,
-                                               uint64_t buffer_id_rx,
-                                               uint64_t buffer_id_tx,
-                                               uint64_t ftype)
-{
-
-    /* call registered_netd_memory with new IDC */
-
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_register_filter_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
-    entry.plist[0] = id;
-    entry.plist[1] = err;
-    entry.plist[2] = filter_id;
-    entry.plist[3] = buffer_id_rx;
-    entry.plist[4] = buffer_id_tx;
-    entry.plist[5] = ftype;
-    // e.plist[0], e.plist[1], e.plist[2],  e.plist[3], e.plist[4], e.plist[5])
-    // id, error, filter_id, buffer_id_rx, buffer_id_tx, filter_type
-
-    enqueue_cont_q(ccfm->q, &entry);
-
-}
-
 /**
  * \brief: Registers the filter with network driver
  */
-static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
+static errval_t register_filter(struct net_soft_filters_binding *cc, uint64_t id,
                             uint64_t len_rx, uint64_t len_tx,
                             uint64_t buffer_id_rx, uint64_t buffer_id_tx,
-                            uint64_t ftype, uint64_t paused)
+                            uint64_t ftype, uint64_t paused, errval_t *err,
+                            uint64_t *filter_id)
 {
-    errval_t err = SYS_ERR_OK;
-
-    ETHERSRV_DEBUG("Register_filter: ID:%" PRIu64 " of type[%" PRIu64
-                   "] buffers RX[%" PRIu64 "] and TX[%" PRIu64 "]\n", id, ftype,
-                   buffer_id_rx, buffer_id_tx);
+    *err = SYS_ERR_OK;
 
     struct buffer_descriptor *buffer_rx = NULL;
     struct buffer_descriptor *buffer_tx = NULL;
@@ -365,11 +239,9 @@ static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
 
     if (buffer_rx == NULL || buffer_tx == NULL) {
         ETHERSRV_DEBUG("no buffer found for the provided buffer id\n");
-        err = FILTER_ERR_BUFF_NOT_FOUND;
-
-        wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
-                                           buffer_id_tx, ftype);
-        return;
+        *err = FILTER_ERR_BUFF_NOT_FOUND;
+        *filter_id = 0;
+        return SYS_ERR_OK;
     }
 
     if (len_rx > BASE_PAGE_SIZE) {
@@ -385,10 +257,9 @@ static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
 
     if (buf == NULL) {
         ETHERSRV_DEBUG("no memory available for filter transfer\n");
-        err = FILTER_ERR_NO_NETD_MEM;
-        wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
-                                           buffer_id_tx, ftype);
-        return;
+        *err = FILTER_ERR_NO_NETD_MEM;
+        *filter_id = 0;
+        return SYS_ERR_OK;
     }
 
     /* Create the filter data-structures */
@@ -400,9 +271,8 @@ static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
     /* FIXME: use goto to deal with failure conditions and reduce the code */
     if (new_filter_rx == NULL || new_filter_tx == NULL) {
         ETHERSRV_DEBUG("out of memory for filter registration\n");
-        err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
-        wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
-                                           buffer_id_tx, ftype);
+        *err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
+        *filter_id = 0;
 
         if (new_filter_rx) {
             free(new_filter_rx);
@@ -411,7 +281,7 @@ static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
         if (new_filter_tx) {
             free(new_filter_tx);
         }
-        return;
+        return SYS_ERR_OK;
     }
 
     /* Zero out the filters */
@@ -424,9 +294,8 @@ static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
 
     if (new_filter_rx->data == NULL || new_filter_tx->data == NULL) {
         ETHERSRV_DEBUG("out of memory for filter data registration\n");
-        err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
-        wrapper_send_filter_registered_msg(cc, id, err, 0, buffer_id_rx,
-                                           buffer_id_tx, ftype);
+        *err = ETHERSRV_ERR_NOT_ENOUGH_MEM;
+        *filter_id = 0;
 
         if (new_filter_rx->data) {
             free(new_filter_rx->data);
@@ -439,7 +308,7 @@ static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
         free(new_filter_rx);
         free(new_filter_tx);
 
-        return;
+        return SYS_ERR_OK;
     }
 
     /* Zero-out the area of filter-data */
@@ -475,58 +344,10 @@ static void register_filter(struct net_soft_filters_binding *cc, uint64_t id,
     buffer_rx->tx_filters = new_filter_tx;      // sometimes rx buffers transmit
 
     /* reporting back the success/failure */
-    wrapper_send_filter_registered_msg(cc, id, err, filter_id_counter,
-                                       buffer_id_rx, buffer_id_tx, ftype);
-
-    ETHERSRV_DEBUG("Register_filter: ID %" PRIu64 ": type[%" PRIu64
-                   "] successful [%" PRIu64 "]\n", id, ftype,
-                   filter_id_counter);
-
+    *filter_id = filter_id_counter;
+    return SYS_ERR_OK;
 }                               /* end function: register filter */
 
-
-/* Handler for sending response to deregister_filter */
-static errval_t send_deregister_filter_response(struct q_entry e)
-{
-    //    ETHERSRV_DEBUG("send_deresigered_filter_response for ID %lu  -----\n", e.plist[0]);
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.deregister_filter_response(b,
-                                                     MKCONT(cont_queue_callback,
-                                                            ccfm->q),
-                                                     e.plist[0], e.plist[1]);
-        /* e.error,    e.filter_id,  */
-
-    } else {
-        ETHERSRV_DEBUG("send_deresiger_filter_response: Filter_ID %" PRIu64
-                       ": Flounder bsy will retry\n", e.plist[1]);
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-static void wrapper_send_filter_deregister_msg(struct net_soft_filters_binding *cc,
-                                               errval_t err, uint64_t filter_id)
-{
-
-    /* call registered_netd_memory with new IDC */
-
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_deregister_filter_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
-    entry.plist[0] = err;
-    entry.plist[1] = filter_id;
-    /* e.plist[0], e.plist[1] );
-       e.error,    e.filter_id */
-    enqueue_cont_q(ccfm->q, &entry);
-}
-
 static struct filter *delete_from_filter_list(struct filter *head,
                                               uint64_t filter_id)
 {
@@ -545,14 +366,13 @@ static struct filter *delete_from_filter_list(struct filter *head,
     return NULL;                /* could not not find the id. */
 }
 
-
 /**
  * \brief: Deregisters the filter with network driver
  */
-static void deregister_filter(struct net_soft_filters_binding *cc,
-                              uint64_t filter_id)
+static errval_t deregister_filter(struct net_soft_filters_binding *cc,
+                              uint64_t filter_id, errval_t *err)
 {
-    errval_t err = SYS_ERR_OK;
+    *err = SYS_ERR_OK;
 
     ETHERSRV_DEBUG("DeRegister_filter: ID:%" PRIu64 "\n", filter_id);
 
@@ -567,7 +387,7 @@ static void deregister_filter(struct net_soft_filters_binding *cc,
     if (rx_filter == NULL /*|| tx_filter == NULL */ ) {
         ETHERSRV_DEBUG("Deregister_filter:requested filter_ID [%" PRIu64
                        "] not found\n", filter_id);
-        err = FILTER_ERR_FILTER_NOT_FOUND;
+        *err = FILTER_ERR_FILTER_NOT_FOUND;
     }
 
     if (rx_filter) {
@@ -579,104 +399,11 @@ static void deregister_filter(struct net_soft_filters_binding *cc,
     }
 
     /* reporting back the success/failure */
-    wrapper_send_filter_deregister_msg(cc, err, filter_id);
-
     ETHERSRV_DEBUG("Deregister_filter: ID %" PRIu64 ": Done\n", filter_id);
 
+    return SYS_ERR_OK;
 }                               /* end function: deregister_filter */
 
-
-
-/* Handler for sending response to re register_filter */
-static errval_t send_re_register_filter_response(struct q_entry e)
-{
-    //    ETHERSRV_DEBUG("send_re_register_filter_response for ID %lu  -----\n", e.plist[0]);
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.re_register_filter_response(b,
-                                                      MKCONT
-                                                      (cont_queue_callback,
-                                                       ccfm->q), e.plist[0],
-                                                      e.plist[1], e.plist[2],
-                                                      e.plist[2]);
-        /* e.error,    e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
-
-    } else {
-        ETHERSRV_DEBUG("send_re_register_filter_response: Filter_ID %" PRIu64
-                       ": Flounder bsy will retry\n", e.plist[1]);
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}                               /* end function: send_re_register_filter_response */
-
-static errval_t send_pause_filter_response(struct q_entry e)
-{
-    //    ETHERSRV_DEBUG("send_re_register_filter_response for ID %lu  -----\n", e.plist[0]);
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) e.binding_ptr;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.pause_response(b,
-                                         MKCONT(cont_queue_callback, ccfm->q),
-                                         e.plist[0], e.plist[1]);
-        /* e.error,    e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
-
-    } else {
-        ETHERSRV_DEBUG("send_re_register_filter_response: Filter_ID %" PRIu64
-                       ": Flounder bsy will retry\n", e.plist[1]);
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}                               /* end function: send_re_register_filter_response */
-
-static void wrapper_send_filter_re_register_msg(struct net_soft_filters_binding
-                                                *cc, errval_t err,
-                                                uint64_t filter_id,
-                                                uint64_t buffer_id_rx,
-                                                uint64_t buffer_id_tx)
-{
-
-    /* call registered_netd_memory with new IDC */
-
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_re_register_filter_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
-    entry.plist[0] = err;
-    entry.plist[1] = filter_id;
-    entry.plist[2] = buffer_id_rx;
-    entry.plist[3] = buffer_id_tx;
-/*    e.plist[0], e.plist[1],  e.plist[2],     e.plist[2]
-      e.error,    e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
-    enqueue_cont_q(ccfm->q, &entry);
-}                               /* end function: wrapper_send_filter_re_register_msg */
-
-static void wrapper_send_filter_pause_msg(struct net_soft_filters_binding *cc,
-                                          errval_t err, uint64_t filter_id)
-{
-
-    /* call registered_netd_memory with new IDC */
-
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_pause_filter_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
-    entry.plist[0] = filter_id;
-    entry.plist[1] = err;
-/*    e.plist[0], e.plist[1],  e.plist[2],     e.plist[2]
-      e.error,    e.filter_id, e.buffer_id_rx, e.buffer_id_rx */
-    enqueue_cont_q(ccfm->q, &entry);
-}                               /* end function: wrapper_send_filter_re_register_msg */
-
-
 static struct filter *find_from_filter_list(struct filter *head,
                                             uint64_t filter_id)
 {
@@ -692,11 +419,11 @@ static struct filter *find_from_filter_list(struct filter *head,
 /**
  * \brief: re-registers the filter with network driver
  */
-static void re_register_filter(struct net_soft_filters_binding *cc,
+static errval_t re_register_filter(struct net_soft_filters_binding *cc,
                                uint64_t filter_id, uint64_t buffer_id_rx,
-                               uint64_t buffer_id_tx)
+                               uint64_t buffer_id_tx, errval_t *err)
 {
-    errval_t err = SYS_ERR_OK;
+    *err = SYS_ERR_OK;
 
     ETHERSRV_DEBUG("re_register_filter: ID:%" PRIu64 "\n", filter_id);
 
@@ -712,10 +439,8 @@ static void re_register_filter(struct net_soft_filters_binding *cc,
     if (rx_filter == NULL /*|| tx_filter == NULL */ ) {
         ETHERSRV_DEBUG("re_register_filter: requested filter_ID [%" PRIu64
                        "] not found\n", filter_id);
-        err = FILTER_ERR_FILTER_NOT_FOUND;
-        wrapper_send_filter_re_register_msg(cc, err, filter_id,
-                                            buffer_id_rx, buffer_id_tx);
-        return;
+        *err = FILTER_ERR_FILTER_NOT_FOUND;
+        return SYS_ERR_OK;
     }
 
     /* Find the buffer with given buffer_id */
@@ -728,27 +453,24 @@ static void re_register_filter(struct net_soft_filters_binding *cc,
         ETHERSRV_DEBUG("re_register_filter: rx=[[%" PRIu64 "] = %p], tx=[[%"
                        PRIu64 "] = %p]\n", buffer_id_rx, buffer_rx,
                        buffer_id_tx, buffer_tx);
-        err = FILTER_ERR_BUFFER_NOT_FOUND;      /* set error value */
-        wrapper_send_filter_re_register_msg(cc, err, filter_id, buffer_id_rx,
-                                            buffer_id_tx);
+        *err = FILTER_ERR_BUFFER_NOT_FOUND;      /* set error value */
+        return SYS_ERR_OK;
     }
     rx_filter->buffer = buffer_rx;
     /* FIXME: Also, set the new buffer for tx_filters */
     /* reporting back the success/failure */
-    wrapper_send_filter_re_register_msg(cc, err, filter_id, buffer_id_rx,
-                                        buffer_id_tx);
-
     ETHERSRV_DEBUG("re_register_filter: ID %" PRIu64 ": Done\n", filter_id);
 
+    return SYS_ERR_OK;
 }                               /* end function: re_register_filter */
 
 /**
  * \brief: pause the filter with network driver
  */
-static void pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
-                         uint64_t buffer_id_rx, uint64_t buffer_id_tx)
+static errval_t pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id,
+                         uint64_t buffer_id_rx, uint64_t buffer_id_tx, errval_t *err)
 {
-    errval_t err = SYS_ERR_OK;
+    *err = SYS_ERR_OK;
 
     ETHERSRV_DEBUG("(un)pause_filter: ID:%" PRIu64 "\n", filter_id);
 
@@ -764,11 +486,11 @@ static void pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id
     if (rx_filter == NULL /*|| tx_filter == NULL */ ) {
         ETHERSRV_DEBUG("pause_filter: requested filter_ID [%" PRIu64
                        "] not found\n", filter_id);
-        err = FILTER_ERR_FILTER_NOT_FOUND;
+        *err = FILTER_ERR_FILTER_NOT_FOUND;
         assert(!"NYI");
         /* wrapper_send_filter_re_register_msg(cc, err, filter_id, */
         /*         buffer_id_rx, buffer_id_tx); */
-        return;
+        return SYS_ERR_OK;
     }
 
     /* Find the buffer with given buffer_id */
@@ -789,7 +511,6 @@ static void pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id
     rx_filter->buffer = buffer_rx;
     /* FIXME: Also, set the new buffer for tx_filters */
     /* reporting back the success/failure */
-    wrapper_send_filter_pause_msg(cc, err, filter_id);
 
     rx_filter->paused = false;
     if (rx_filter->pause_bufpos > 0) {
@@ -807,60 +528,13 @@ static void pause_filter(struct net_soft_filters_binding *cc, uint64_t filter_id
     rx_filter->pause_bufpos = 0;
 
     ETHERSRV_DEBUG("(un)pause_filter: ID %" PRIu64 ": Done\n", filter_id);
-
+    return SYS_ERR_OK;
 }                               /* end function: re_register_filter */
 
-
-/* Handler for sending response to register_filter */
-static errval_t send_register_arp_filter_response(struct q_entry entry)
-{
-    //    ETHERSRV_DEBUG("send_resigered_arp_filter  -----\n");
-    struct net_soft_filters_binding *b =
-      (struct net_soft_filters_binding *) entry.binding_ptr;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.register_arp_filter_response(b,
-                                                       MKCONT
-                                                       (cont_queue_callback,
-                                                        ccfm->q),
-                                                       entry.plist[0],
-                                                       entry.plist[1]);
-        /* e.id,        e.error */
-
-    } else {
-        ETHERSRV_DEBUG("send_resigered_arp_filter Flounder bsy will retry\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-static void wrapper_send_arp_filter_registered_msg(struct net_soft_filters_binding
-                                                   *cc, uint64_t id,
-                                                   errval_t err)
-{
-
-    /* call registered_netd_memory with new IDC */
-
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_register_arp_filter_response;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure_FM *ccfm = (struct client_closure_FM *) cc->st;
-
-    entry.plist[0] = id;
-    entry.plist[1] = err;
-    /* entry.plist[0], entry.plist[1]
-       id,             e.error */
-
-    enqueue_cont_q(ccfm->q, &entry);
-}
-
-static void register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
-                                uint64_t len_rx, uint64_t len_tx)
+static errval_t register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id,
+                                uint64_t len_rx, uint64_t len_tx, errval_t *err)
 {
-
-    errval_t err = SYS_ERR_OK;
+    *err = SYS_ERR_OK;
 
     if (len_rx > BASE_PAGE_SIZE) {
         len_rx = BASE_PAGE_SIZE;
@@ -874,9 +548,8 @@ static void register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id
 
     if (buf == NULL) {
         ETHERSRV_DEBUG("no memory available for arp_filter transfer\n");
-        err = FILTER_ERR_NO_NETD_MEM;
-        wrapper_send_arp_filter_registered_msg(cc, id, err);
-        return;
+        *err = FILTER_ERR_NO_NETD_MEM;
+        return SYS_ERR_OK;
     }
 
     arp_filter_rx.data = (uint8_t *) malloc(len_rx);
@@ -894,12 +567,9 @@ static void register_arp_filter(struct net_soft_filters_binding *cc, uint64_t id
     arp_filter_tx.len = len_tx;
     ETHERSRV_DEBUG("#### The received arp RX filter is\n");
     //    show_binary_blob(arp_filter_tx.data, arp_filter_tx.len);
-
-    wrapper_send_arp_filter_registered_msg(cc, id, err);
+    return SYS_ERR_OK;
 }
 
-
-
 static void send_arp_to_all(void *data, uint64_t len, uint64_t flags)
 {
     struct filter *head = rx_filters;
@@ -939,7 +609,6 @@ static void send_arp_to_all(void *data, uint64_t len, uint64_t flags)
     copy_packet_to_user(buffer, data, len, flags);
 }
 
-
 struct filter *execute_filters(void *data, size_t len)
 {
     struct filter *head = rx_filters;
@@ -1350,4 +1019,3 @@ out:
      rx_ring_register_buffer(opaque);
 } // end function: process_received_packet
 
-
index 9b908b2..48718a5 100755 (executable)
@@ -41,6 +41,8 @@
 // FIXME: This is repeated, make it common
 #define MAX_SERVICE_NAME_LEN  256   // Max len that a name of service can have
 
+#define QUEUE_SIZE 512
+
 /*****************************************************************
  * Global datastructure
  *****************************************************************/
@@ -62,14 +64,17 @@ struct buffer_descriptor *buffers_list = NULL;
  * Prototypes
  *****************************************************************/
 
-static void register_buffer(struct net_queue_manager_binding *cc,
+static errval_t register_buffer(struct net_queue_manager_binding *cc,
         struct capref cap, struct capref sp, uint64_t queueid,
-        uint64_t slots, uint8_t role);
+        uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx);
+static void raw_add_buffer_signal(struct net_queue_manager_binding *cc,
+                           uint64_t offset, uint64_t length,
+                           uint64_t more, uint64_t flags);
 static void raw_add_buffer(struct net_queue_manager_binding *cc,
                            uint64_t offset, uint64_t length,
                            uint64_t more, uint64_t flags);
-static void get_mac_addr_qm(struct net_queue_manager_binding *cc,
-        uint64_t queueid);
+static errval_t get_mac_addr_qm(struct net_queue_manager_binding *cc,
+        uint64_t queueid, uint64_t *mac);
 static void print_statistics_handler(struct net_queue_manager_binding *cc,
         uint64_t queueid);
 static void terminate_queue(struct net_queue_manager_binding *cc);
@@ -82,14 +87,17 @@ static void do_pending_work(struct net_queue_manager_binding *b);
 
 // Initialize service
 static struct net_queue_manager_rx_vtbl rx_nqm_vtbl = {
-    .register_buffer = register_buffer,
-    .raw_add_buffer = raw_add_buffer,
-    .get_mac_address = get_mac_addr_qm,
+    .raw_add_buffer = raw_add_buffer_signal,
     .print_statistics = print_statistics_handler,
     .benchmark_control_request = benchmark_control_request,
     .terminate_queue = terminate_queue,
 };
 
+static struct net_queue_manager_rpc_rx_vtbl rpc_rx_nqm_vtbl = {
+    .register_buffer_call = register_buffer,
+    .get_mac_address_call = get_mac_addr_qm,
+};
+
 /*****************************************************************
  * Pointers to driver functionalities:
  *****************************************************************/
@@ -137,6 +145,74 @@ static struct loopback_mapping lo_map_tbl[4] = {{0,0, NULL},};
 // client_no initialization value
 static int lo_tbl_idx = 0;
 
+static int put_to_queue(uint64_t *q, uint64_t v1, uint64_t v2, uint64_t v3, uint64_t v4)
+{
+    uint64_t start = q[0];
+    uint64_t end = q[1];
+
+    if (end == (QUEUE_SIZE - 1)) {
+        assert(start > 1);
+    } else {
+        assert((end + 1) != start);
+    }
+
+    q[4 * end] = v1;
+    q[4 * end + 1] = v2;
+    q[4 * end + 2] = v3;
+    q[4 * end + 3] = v4;
+    bool s = start == end;
+    if (end == (QUEUE_SIZE - 1))
+        q[1] = 1;
+    else
+        q[1]++;
+    end = q[1];
+    bool f = (end == (QUEUE_SIZE - 1)) ? (start == 1): (start == end + 1);
+    return s + 2 * f;
+}
+
+static bool check_queue(uint64_t *q)
+{
+    uint64_t start = q[0];
+    uint64_t end = q[1];
+
+    return start != end;
+}
+
+static bool get_from_queue(uint64_t *q, uint64_t *v1, uint64_t *v2, uint64_t *v3, uint64_t *v4)
+{
+    uint64_t start = q[0];
+    uint64_t end = q[1];
+
+    assert(start != end);
+    *v1 = q[4 * start];
+    *v2 = q[4 * start + 1];
+    *v3 = q[4 * start + 2];
+    *v4 = q[4 * start + 3];
+    if (start == (QUEUE_SIZE - 1))
+        q[0] = 1;
+    else
+        q[0]++;
+    return !q[2];
+}
+
+void check_queues(void)
+{
+    int i;
+
+    for (i = 0; i < client_no; i++) {
+        struct client_closure *cc = all_apps[i]->st;
+        for (;;) {
+            if (!cc->queue)
+                break;
+            bool r = check_queue(cc->queue);
+            if (r)
+                raw_add_buffer(cc->app_connection, 0, 0, 0, 0);
+            else
+                break;
+        }
+    }
+}
+
 // fill up the lo_map_tbl with valid entries
 // Assumptions:
 //  * client_no starts at 0
@@ -274,14 +350,6 @@ static struct client_closure *create_new_client(
     char name[64];
     sprintf(name, "ether_a_%d_%s", cc->cl_no,
                 ((cc->cl_no % 2) == 0)? "RX" : "TX");
-    cc->q = create_cont_q(name);
-    if (cc->q == NULL) {
-        ETHERSRV_DEBUG("create_new_client: queue allocation failed\n");
-        free(buffer);
-        free(cc);
-        return NULL;
-    }
-    // cc->q->debug = 1;
     return cc;
 } // end function: create_new_client
 
@@ -351,64 +419,11 @@ struct buffer_descriptor *find_buffer(uint64_t buffer_id)
 // Interface  implementation
 // **********************************************************
 
-// *********** Interface: register_buffer *******************
-static errval_t send_new_buffer_id(struct q_entry entry)
-{
-    struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
-                    entry.binding_ptr;
-    struct client_closure *ccl = (struct client_closure *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.new_buffer_id(b, MKCONT(cont_queue_callback, ccl->q),
-                                        entry.plist[0],
-                                        entry.plist[1],
-                                        entry.plist[2]);
-        // entry.error, entry.queueid, entry.buffer_id
-    } else {
-        ETHERSRV_DEBUG("send_new_buffer_id Flounder busy.. will retry\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
-static void report_register_buffer_result(struct net_queue_manager_binding *cc,
-        errval_t err, uint64_t queueid, uint64_t buffer_id)
-{
-    struct q_entry entry;
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = send_new_buffer_id;
-    entry.binding_ptr = (void *) cc;
-    struct client_closure *ccl = (struct client_closure *) cc->st;
-
-    entry.plist[0] = err;
-    entry.plist[1] = queueid;
-    entry.plist[2] = buffer_id;
-    //   error, queue_id, buffer_id
-
-    struct waitset *ws = get_default_waitset();
-    int passed_events = 0;
-    while (can_enqueue_cont_q(ccl->q) == false) {
-
-       // USER_PANIC("queue full, can go further\n");
-
-        if (passed_events > 5) {
-            USER_PANIC("queue full, can go further\n");
-            //return CONT_ERR_NO_MORE_SLOTS;
-        }
-        event_dispatch_debug(ws);
-        ++passed_events;
-    }
-
-
-    enqueue_cont_q(ccl->q, &entry);
-}
-
-
 // Actual register_buffer function with all it's logic
-static void register_buffer(struct net_queue_manager_binding *cc,
+static errval_t register_buffer(struct net_queue_manager_binding *cc,
             struct capref cap, struct capref sp, uint64_t queueid,
-            uint64_t slots, uint8_t role)
+            uint64_t slots, uint8_t role, struct capref queue_cap, uint64_t *idx)
 {
-
     ETHERSRV_DEBUG("ethersrv:register buffer called with slots %"PRIu64"\n",
             slots);
     errval_t err;
@@ -419,14 +434,13 @@ static void register_buffer(struct net_queue_manager_binding *cc,
     struct buffer_descriptor *buffer = closure->buffer_ptr;
     err = populate_buffer(buffer, cap);
     if (err_is_fail(err)) {
-        report_register_buffer_result(cc, err, queueid, 0);
-        return;
+        *idx = 0;
+        return SYS_ERR_OK;
     }
     buffer->role = role;
     buffer->con = cc;
     buffer->queueid = queueid;
 
-
     // Create a list to hold metadata for sending
     buffer->rxq.buffer_state_size = slots;
     buffer->rxq.buffer_state = calloc(slots,
@@ -443,6 +457,14 @@ static void register_buffer(struct net_queue_manager_binding *cc,
     buffer->txq.buffer_state_head = 0;
     buffer->txq.buffer_state_used = 0;
 
+    void *va;
+    uint64_t *ptr;
+
+    err = vspace_map_one_frame(&va, QUEUE_SIZE * 4 * sizeof(uint64_t) * 2, queue_cap, NULL, NULL);
+    assert(err_is_ok(err));
+    ptr = va;
+    closure->queue = ptr;
+
     if (is_loopback_device) {
         populate_lo_mapping_table(closure->cl_no, closure->buffer_ptr);
     } // end if: loopback device
@@ -452,28 +474,12 @@ static void register_buffer(struct net_queue_manager_binding *cc,
     use_raw_if = true;
 
     buffers_list = buffer;
-    report_register_buffer_result(cc, SYS_ERR_OK, queueid,
-                                      buffer->buffer_id);
-    return;
+    *idx = buffer->buffer_id;
+
+    return SYS_ERR_OK;
 } // end function: register_buffer
 
 
-static errval_t wrapper_send_raw_xmit_done(struct q_entry e)
-{
-    struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
-        e.binding_ptr;
-    struct client_closure *ccl = (struct client_closure *) b->st;
-
-    if (b->can_send(b)) {
-        errval_t err = b->tx_vtbl.raw_xmit_done(b,
-                MKCONT(cont_queue_callback, ccl->q),
-                e.plist[0], e.plist[1], e.plist[2], e.plist[3]);
-        return err;
-    } else {
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
 static __attribute__((unused))  void
 handle_single_event_nonblock(struct waitset *ws)
 {
@@ -498,78 +504,28 @@ handle_single_event_nonblock(struct waitset *ws)
 } // end function: handle_single_event_nonblock
 
 
-
-static errval_t send_raw_xmit_done(struct net_queue_manager_binding *b,
+static errval_t send_raw_xmit_done(struct net_queue_manager_binding *binding,
                                    uint64_t offset, uint64_t length,
                                    uint64_t more, uint64_t flags)
 {
-    struct client_closure *ccl = (struct client_closure *) b->st;
-
-    // Send notification to application
-    struct q_entry entry;
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = wrapper_send_raw_xmit_done;
-    entry.binding_ptr = b;
-    entry.plist[0] = offset;
-    entry.plist[1] = length;
-    entry.plist[2] = more;
-    entry.plist[3] = flags;
-
-    struct waitset *ws = get_default_waitset();
-    int passed_events = 0;
-    while (can_enqueue_cont_q(ccl->q) == false) {
-
-//        USER_PANIC("queue full, can go further\n");
-
-        if (passed_events > 5) {
-            cont_queue_show_queue(ccl->q);
-            printf("## queue full, dropping raw_xmit_done notification\n");
-            // USER_PANIC("queue full, can't go further\n");
-            return CONT_ERR_NO_MORE_SLOTS;
-        }
-
-//        errval_t err = handle_single_event_nonblock(ws);
-        errval_t err = event_dispatch_debug(ws);
-        if (err_is_fail(err)) {
-            ETHERSRV_DEBUG("Error in event_dispatch, returned %d\n",
-                        (unsigned int)err);
-            // There should be a serious panic and failure here
-            USER_PANIC_ERR(err, "event_dispatch_non_block failed in handle_single_event\n");
-            break;
-        }
-
-        ++passed_events;
+    struct client_closure *cl = (struct client_closure *) binding->st;
+    errval_t err = SYS_ERR_OK;
+    int r;
+    r = put_to_queue(cl->queue + QUEUE_SIZE * 4, offset, length, more, flags);
+    if (r) {
+        if (r == 2)
+            binding->control(binding, IDC_CONTROL_SET_SYNC);
+        err = binding->tx_vtbl.raw_xmit_done(binding, BLOCKING_CONT, offset, length, more, flags);
+        assert(err_is_ok(err));
+        if (r == 2)
+            binding->control(binding, IDC_CONTROL_CLEAR_SYNC);
     }
-
-    enqueue_cont_q(ccl->q, &entry);
-    return SYS_ERR_OK;
+    return err;
 } // end function: send_raw_xmit_done
 
-
-
-
-
-
 // *********** Interface: get_mac_address ****************
 
 // wrapper function for responce
-static errval_t wrapper_send_mac_addr_response(struct q_entry entry)
-{
-    struct net_queue_manager_binding *b = (struct net_queue_manager_binding *)
-        entry.binding_ptr;
-    struct client_closure *ccl = (struct client_closure *) b->st;
-
-    if (b->can_send(b)) {
-        return b->tx_vtbl.get_mac_address_response(b,
-                          MKCONT(cont_queue_callback, ccl->q),
-                          entry.plist[0], entry.plist[1]);
-        // queueid, hwaddr
-    } else {
-        ETHERSRV_DEBUG("send_mac_addr_response Flounder busy.. will retry\n");
-        return FLOUNDER_ERR_TX_BUSY;
-    }
-}
-
 uint64_t get_mac_addr_from_device(void)
 {
     union {
@@ -583,37 +539,13 @@ uint64_t get_mac_addr_from_device(void)
 }
 
 // function to handle incoming mac address requests
-static void get_mac_addr_qm(struct net_queue_manager_binding *cc,
-        uint64_t queueid)
+static errval_t get_mac_addr_qm(struct net_queue_manager_binding *cc,
+        uint64_t queueid, uint64_t *mac)
 {
-    struct q_entry entry;
-
-    memset(&entry, 0, sizeof(struct q_entry));
-    entry.handler = wrapper_send_mac_addr_response;
-    entry.binding_ptr = (void *) cc;
     struct client_closure *ccl = (struct client_closure *) cc->st;
     assert(ccl->queueid == queueid);
-
-    entry.plist[0] = queueid;
-    entry.plist[1] = get_mac_addr_from_device();
-       // queueid,  hwaddr
-
-    struct waitset *ws = get_default_waitset();
-    int passed_events = 0;
-    while (can_enqueue_cont_q(ccl->q) == false) {
-
-       // USER_PANIC("queue full, can go further\n");
-
-        if (passed_events > 5) {
-            USER_PANIC("queue full, can go further\n");
-           // return CONT_ERR_NO_MORE_SLOTS;
-        }
-        event_dispatch_debug(ws);
-        ++passed_events;
-    }
-
-
-    enqueue_cont_q(ccl->q, &entry);
+    *mac = get_mac_addr_from_device();
+    return SYS_ERR_OK;
 }
 
 // *********** Interface: print_statistics ****************
@@ -759,18 +691,6 @@ bool copy_packet_to_user(struct buffer_descriptor *buffer,
         return false;
     }
 
-    if (!is_enough_space_in_queue(cl->q)) {
-
-        printf("[%s] Dropping packet as app [%d] is not processing packets"
-                "fast enough.  Cont queue is almost full [%d], pkt count [%"PRIu64"]\n",
-                disp_name(), cl->cl_no, queue_free_slots(cl->q), sent_packets);
-        if (cl->debug_state == 4) {
-            ++cl->in_dropped_app_buf_full;
-        }
-//        abort(); // FIXME: temparary halt to simplify debugging
-        return false;
-    }
-
     // pop the latest buffer from head of queue (this is stack)
     --buffer->rxq.buffer_state_head;
     struct buffer_state_metadata *bsm = buffer->rxq.buffer_state +
@@ -820,6 +740,21 @@ bool copy_packet_to_user(struct buffer_descriptor *buffer,
 /*****************************************************************
  * Interface related: raw interface
  ****************************************************************/
+static void raw_add_buffer_signal(struct net_queue_manager_binding *cc,
+                           uint64_t offset, uint64_t length,
+                           uint64_t more, uint64_t flags)
+{
+    struct client_closure *cl = (struct client_closure *) cc->st;
+
+    for (;;) {
+        bool c = check_queue(cl->queue);
+        if (c)
+            raw_add_buffer(cc, offset, length, more, flags);
+        else
+            break;
+    }
+}
+
 static void raw_add_buffer(struct net_queue_manager_binding *cc,
                            uint64_t offset, uint64_t length,
                            uint64_t more, uint64_t flags)
@@ -830,6 +765,12 @@ static void raw_add_buffer(struct net_queue_manager_binding *cc,
     uint64_t paddr;
     void *vaddr, *opaque;
 
+    bool c = check_queue(cl->queue);
+    if (!c)
+        return;
+    get_from_queue(cl->queue, &offset, &length, &more, &flags);
+    c = check_queue(cl->queue);
+
     paddr = ((uint64_t)(uintptr_t) buffer->pa) + offset;
     vaddr = (void*) ((uintptr_t) buffer->va + (size_t)offset);
 
@@ -866,6 +807,8 @@ static void raw_add_buffer(struct net_queue_manager_binding *cc,
             }
             err = ether_transmit_pbuf_list_ptr(cl->driver_buff_list,
                     cl->chunk_counter);
+            if (c == false) // no more buffers -> start sending
+                ether_transmit_pbuf_list_ptr(cl->driver_buff_list, 0);
             assert(err_is_ok(err));
             cl->chunk_counter = 0;
         }
@@ -951,7 +894,9 @@ static errval_t connect_ether_cb(void *st, struct net_queue_manager_binding *b)
 
     // copy my message receive handler vtable to the binding
     b->rx_vtbl = rx_nqm_vtbl;
+    b->rpc_rx_vtbl = rpc_rx_nqm_vtbl;
     b->error_handler = error_handler;
+    b->control(b, IDC_CONTROL_CLEAR_SYNC);
 
     // Create a new client for this connection
     struct client_closure *cc = create_new_client(b);
@@ -1094,4 +1039,3 @@ memcpy_fast(void *dst0, const void *src0, size_t length)
 {
     return memcpy(dst0, src0, length);
 }
-
index 6fee7a5..df71890 100755 (executable)
@@ -143,11 +143,11 @@ echo "Requested architecture is $ARCH."
 case "$ARCH" in
     "x86_64")
     QEMU_CMD="${QEMU_PATH}qemu-system-x86_64 \
-        -machine type=q35
-        -smp $SMP \
+        -machine type=q35 -cpu host -enable-kvm \
+        -smp 2 \
         -m 1024 \
-        -net nic,model=$NIC_MODEL \
-        -net user \
+        -net nic,model=e1000 \
+        -net bridge,br=br0 \
         -device ahci,id=ahci \
         -device ide-drive,drive=disk,bus=ahci.0 \
         -drive id=disk,file="$HDFILE",if=none"
index a6dde3f..0137304 100644 (file)
@@ -288,6 +288,13 @@ static bool handle_free_TX_slot_fn(void)
     return sent;
 }
 
+static void update_e1000_tdt(void)
+{
+    e1000_dqval_t dqval = 0;
+    dqval = e1000_dqval_val_insert(dqval, ether_transmit_index);
+    e1000_tdt_wr(&(e1000), 0, dqval);
+}
+
 /*****************************************************************
  * Setup transmit descriptor for packet transmission.
  *
@@ -295,7 +302,6 @@ static bool handle_free_TX_slot_fn(void)
  static uint64_t transmit_pbuf(uint64_t buffer_address,
                               size_t packet_len, bool last, void *opaque)
 {
-    e1000_dqval_t dqval = 0;
     struct tx_desc tdesc;
 
     /*
@@ -323,10 +329,7 @@ static bool handle_free_TX_slot_fn(void)
      * application can't temper with it. */
     transmit_ring[ether_transmit_index] = tdesc;
     pbuf_list_tx[ether_transmit_index].opaque = opaque;
-
     ether_transmit_index = (ether_transmit_index + 1) % DRIVER_TRANSMIT_BUFFERS;
-    dqval = e1000_dqval_val_insert(dqval, ether_transmit_index);
-    e1000_tdt_wr(&(e1000), 0, dqval);
 
     E1000_DEBUG("ether_transmit_index %"PRIu32"\n", ether_transmit_index);
 
@@ -350,6 +353,10 @@ static errval_t transmit_pbuf_list_fn(struct driver_buffer *buffers,
                                       size_t                count)
 
 {
+    if (!count) { // flush
+        update_e1000_tdt();
+        return SYS_ERR_OK;
+    }
     E1000_DEBUG("transmit_pbuf_list_fn(count=%"PRIu64")\n", count);
     if (!can_transmit(count)){
         while(handle_free_TX_slot_fn());
@@ -624,16 +631,20 @@ static bool parse_mac(uint8_t *mac, const char *str)
     return true;
 }
 
+static void update_e1000_rdt(void)
+{
+    e1000_dqval_t dqval = 0;
+    dqval = e1000_dqval_val_insert(dqval, receive_index);
+    e1000_rdt_wr(&e1000, 0, dqval);
+}
 
 static int add_desc(uint64_t paddr, void *opaque)
 {
-    e1000_dqval_t dqval = 0;
     union rx_desc desc;
 
     desc.raw[0] = desc.raw[1] = 0;
     desc.rx_read_format.buffer_address = paddr;
 
-
     if(receive_free == DRIVER_RECEIVE_BUFFERS) {
         // This is serious error condition.
         // Printing debug information to help user!
@@ -652,8 +663,6 @@ static int add_desc(uint64_t paddr, void *opaque)
     receive_opaque[receive_index] = opaque;
 
     receive_index = (receive_index + 1) % DRIVER_RECEIVE_BUFFERS;
-    dqval = e1000_dqval_val_insert(dqval, receive_index);
-    e1000_rdt_wr(&e1000, 0, dqval);
 
     receive_free++;
     return 0;
@@ -699,6 +708,7 @@ static void e1000_init_fn(struct device_mem *bar_info, int nr_allocated_bars)
                   NULL, transmit_pbuf_list_fn, find_tx_free_slot_count_fn,
                   handle_free_TX_slot_fn, receive_buffer_size,rx_register_buffer_fn,
                   rx_find_free_slot_count_fn);
+    update_e1000_rdt();
 #else
     ethernetif_backend_init(global_service_name, assumed_queue_id, get_mac_address_fn,
                  NULL,
@@ -743,16 +753,18 @@ static void e1000_interrupt_handler_fn(void *arg)
         }
     }
 
-    if (e1000_intreg_rxt0_extract(icr) == 0) {
-        return;
-    }
+    if (e1000_intreg_rxt0_extract(icr) != 0) {
 
 #ifndef LIBRARY
-    E1000_DEBUG("e1000 interrupt came in\n");
-    handle_multiple_packets(MAX_ALLOWED_PKT_PER_ITERATION);
+        E1000_DEBUG("e1000 interrupt came in\n");
+        if (handle_multiple_packets(MAX_ALLOWED_PKT_PER_ITERATION))
+            update_e1000_rdt();
 #else
-    handle_multiple_packets(1);
+        handle_multiple_packets(1);
 #endif
+    }
+    check_queues();
+    while(handle_free_TX_slot_fn());
 }
 
 
@@ -1025,13 +1037,21 @@ int e1000n_driver_init(int argc, char **argv)
     e1000_print_link_status(&e1000_device);
 
 #ifndef LIBRARY
-    E1000_DEBUG("#### starting polling.\n");
-    // FIXME: hack to force the driver in polling mode, as interrupts are
-    // not reliably working
-    use_interrupt = false;
-    polling_loop();
+    if (!use_interrupt) {
+        E1000_DEBUG("#### starting polling.\n");
+        polling_loop();
+    } else {
+        struct waitset *ws = get_default_waitset();
+
+        while (1) {
+            err = event_dispatch(ws);
+            if (err_is_fail(err)) {
+                DEBUG_ERR(err, "in event_dispatch");
+                break;
+            }
+        } // end while: infinite
+    }
 #endif
 
     return 1;
 }
-
index 9cccb2e..bba5eac 100644 (file)
  * Initial default values
  */
 
-#define E1000_DEFAULT_INT_THROTTLE_RATE 5580
+#define E1000_DEFAULT_INT_THROTTLE_RATE 130
 #define E1000_INT_THROTTLE_RATE_DISABLED 0
 
 
index dcf5c5d..c5bb63a 100644 (file)
@@ -145,7 +145,7 @@ static errval_t e1000_get_auto_rd_done(e1000_device_t *dev)
 {
     uint16_t data;
     errval_t err;
-    
+
     if(dev->mac_type == e1000_82574){
         // For the 82574  we just check the auto rd flag without issuing
         // an eeprom read. (FreeBSD does it like this)
@@ -357,7 +357,7 @@ static int e1000_reset(e1000_device_t *dev)
 
     /*
      * If acquired, release mdio ownership
-     */ 
+     */
     if (mdio_acquired) {
         timeout = 1000;
         do {
@@ -718,33 +718,36 @@ static void e1000_configure_rx(e1000_device_t *dev)
 /*
  * Set interrupt throttle for all interrupts
  */
-void e1000_set_interrupt_throttle(e1000_device_t *dev, uint16_t rate){
-        /* Enable interrupt throttling rate.
-         *
-         * The optimal performance setting for this register is very system and
-         * configuration specific. A initial suggested range is 651-5580 (28Bh - 15CCh).
-         * The value 0 will disable interrupt throttling
-         */
-        if (dev->mac_type == e1000_82575
-            || dev->mac_type == e1000_82576
-            || dev->mac_type == e1000_I210
-            || dev->mac_type == e1000_I350) {
-            // TODO(lh): Check if these cards really dont need the itr set as well.
-            e1000_eitr_interval_wrf(dev->device, 0, rate);
-            e1000_eitr_interval_wrf(dev->device, 1, rate);
-            e1000_eitr_interval_wrf(dev->device, 2, rate);
-            e1000_eitr_interval_wrf(dev->device, 3, rate);
-        }
-        else if(dev->mac_type == e1000_82574){
-            e1000_itr_interval_wrf(dev->device, rate);
-            e1000_eitr_82574_interval_wrf(dev->device, 0, rate);
-            e1000_eitr_82574_interval_wrf(dev->device, 1, rate);
-            e1000_eitr_82574_interval_wrf(dev->device, 2, rate);
-            e1000_eitr_82574_interval_wrf(dev->device, 3, rate);
-        }
-        else {
-            e1000_itr_interval_wrf(dev->device, 5580);
-        }
+void e1000_set_interrupt_throttle(e1000_device_t *dev, uint16_t usec)
+{
+    /* Enable interrupt throttling rate.
+     *
+     * The optimal performance setting for this register is very system and
+     * configuration specific. A initial suggested range is 651-5580 (28Bh - 15CCh).
+     * The value 0 will disable interrupt throttling
+     */
+    int16_t rate = usec * 4;
+    
+    if (dev->mac_type == e1000_82575
+        || dev->mac_type == e1000_82576
+        || dev->mac_type == e1000_I210
+        || dev->mac_type == e1000_I350) {
+        // TODO(lh): Check if these cards really dont need the itr set as well.
+        e1000_eitr_interval_wrf(dev->device, 0, rate);
+        e1000_eitr_interval_wrf(dev->device, 1, rate);
+        e1000_eitr_interval_wrf(dev->device, 2, rate);
+        e1000_eitr_interval_wrf(dev->device, 3, rate);
+    }
+    else if(dev->mac_type == e1000_82574){
+        e1000_itr_interval_wrf(dev->device, rate);
+        e1000_eitr_82574_interval_wrf(dev->device, 0, rate);
+        e1000_eitr_82574_interval_wrf(dev->device, 1, rate);
+        e1000_eitr_82574_interval_wrf(dev->device, 2, rate);
+        e1000_eitr_82574_interval_wrf(dev->device, 3, rate);
+    }
+    else {
+        e1000_itr_interval_wrf(dev->device, rate);
+    }
 }
 
 /*****************************************************************
@@ -775,7 +778,7 @@ void e1000_hwinit(e1000_device_t *dev, struct device_mem *bar_info,
     }
 
     e1000_initialize(dev->device, (void *) bar_info[0].vaddr);
-       
+
        /*
         * XXX: This is a check if we are using legacy descriptors and virtual functions
         *      are enabled to display an error message and abort execution.
@@ -1084,4 +1087,3 @@ void e1000_hwinit(e1000_device_t *dev, struct device_mem *bar_info,
         }
     }
 }
-
index 60012b1..8abf9c4 100755 (executable)
@@ -14,9 +14,6 @@
 
 #include <barrelfish/waitset.h>
 
-// for handling contiuations
-#include <contmng/contmng.h>
-
 // standard libraries
 #include <stdio.h>
 #include <string.h>