From: Lei Xia Date: Tue, 23 Feb 2010 05:05:36 +0000 (-0600) Subject: Add lock to vnet X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=610d3af422ae2f0eb43d156984bf5d56d3352e46;p=palacios.releases.git Add lock to vnet --- diff --git a/palacios/src/devices/lnx_virtio_nic.c b/palacios/src/devices/lnx_virtio_nic.c index 26b32f6..d3d5cfb 100644 --- a/palacios/src/devices/lnx_virtio_nic.c +++ b/palacios/src/devices/lnx_virtio_nic.c @@ -85,6 +85,8 @@ struct virtio_net_state { struct v3_dev_net_ops * net_ops; + v3_lock_t lock; + void * backend_data; struct virtio_dev_state * virtio_dev; struct list_head dev_link; @@ -120,6 +122,10 @@ static int virtio_init_state(struct virtio_net_state * virtio) //virtio->virtio_cfg.status = VIRTIO_NET_S_LINK_UP; virtio->virtio_cfg.pci_isr = 0; + if (v3_lock_init(&(virtio->lock)) == -1){ + PrintError("Virtio NIC: Failure to init lock for net_state\n"); + } + virtio->pkt_sent = virtio->pkt_recv = virtio->pkt_drop = 0; return 0; @@ -476,14 +482,15 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) { uint32_t hdr_len = sizeof(struct virtio_net_hdr); uint32_t data_len = size; uint32_t offset = 0; + unsigned long flags; + + flags = v3_lock_irqsave(virtio->lock); PrintDebug("VIRTIO NIC: sending packet to virtio nic %p, size:%d", virtio, size); virtio->pkt_recv ++; - data_len -= hdr_len; - build_receive_header(&hdr, buf, 1); if (q->ring_avail_addr == 0) { @@ -554,6 +561,7 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) { } #endif + v3_unlock_irqrestore(virtio->lock, flags); return offset; } diff --git a/palacios/src/palacios/vmm_vnet.c b/palacios/src/palacios/vmm_vnet.c index dca5b7b..137c4d8 100644 --- a/palacios/src/palacios/vmm_vnet.c +++ b/palacios/src/palacios/vmm_vnet.c @@ -142,26 +142,8 @@ static int add_route_to_cache(struct v3_vnet_pkt * pkt, struct route_list * rout static int clear_hash_cache() { - /* USE the hash table iterators. - * See v3_swap_flush(struct v3_vm_info * vm) in vmm_shdw_pg_swapbypass.c - */ - - // MAKE SURE YOU DELETE the route_list entries - struct hashtable_iter * ht_iter = v3_create_htable_iter(vnet_state.route_cache); - - if (!ht_iter) { - PrintError("NULL iterator in vnet cache!\n"); - } - - while (ht_iter->entry) { - struct route_list * route_list_ptr = (struct route_list *)v3_htable_get_iter_value(ht_iter); - V3_Free(route_list_ptr); - v3_htable_iter_advance(ht_iter); - } - - V3_Free(ht_iter); - - //v3_free_htable(vnet_state.route_cache, 0, 1); + v3_free_htable(vnet_state.route_cache, 1, 1); + vnet_state.route_cache = v3_create_htable(0, &hash_fn, &hash_eq); return 0; } @@ -174,6 +156,30 @@ static int look_into_cache(struct v3_vnet_pkt * pkt, struct route_list ** routes } +struct vnet_dev * find_dev_by_id(int idx) { + struct vnet_dev * dev = NULL; + + list_for_each_entry(dev, &(vnet_state.devs), node) { + int dev_id = dev->dev_id; + + if (dev_id == idx) + return dev; + } + + return NULL; +} + +static struct vnet_dev * find_dev_by_mac(char * name) { + struct vnet_dev * dev = NULL; + + list_for_each_entry(dev, &(vnet_state.devs), node) { + if (!memcmp(dev->mac_addr, name, 6)) + return dev; + } + + return NULL; +} + int v3_vnet_add_route(struct v3_vnet_route route) { struct vnet_route_info * new_route = NULL; @@ -188,11 +194,11 @@ int v3_vnet_add_route(struct v3_vnet_route route) { /* TODO: Find devices */ if (new_route->route_def.dst_type == LINK_INTERFACE) { - //new_route->dst_dev = FIND_DEV(); + new_route->dst_dev = find_dev_by_id(new_route->route_def.dst_id); } if (new_route->route_def.src_type == LINK_INTERFACE) { - // new_route->src_dev = FIND_DEV() + new_route->src_dev = find_dev_by_id(new_route->route_def.src_id); } flags = v3_lock_irqsave(vnet_state.lock); @@ -334,6 +340,7 @@ static struct route_list * match_route(struct v3_vnet_pkt * pkt) { static int handle_one_pkt(struct v3_vnet_pkt * pkt) { struct route_list * matched_routes = NULL; + unsigned long flags; int i; @@ -349,18 +356,22 @@ static int handle_one_pkt(struct v3_vnet_pkt * pkt) { } #endif + flags = v3_lock_irqsave(vnet_state.lock); + look_into_cache(pkt, &matched_routes); - + if (matched_routes == NULL) { - matched_routes = match_route(pkt); - + matched_routes = match_route(pkt); + if (matched_routes) { - add_route_to_cache(pkt, matched_routes); + add_route_to_cache(pkt, matched_routes); } else { PrintError("Could not find route for packet...\n"); return -1; } } + + v3_unlock_irqrestore(vnet_state.lock, flags); for (i = 0; i < matched_routes->num_routes; i++) { @@ -400,30 +411,6 @@ int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt) { return 0; } -struct vnet_dev * find_dev_by_id(int idx) { - struct vnet_dev * dev = NULL; - - list_for_each_entry(dev, &(vnet_state.devs), node) { - int dev_id = dev->dev_id; - - if (dev_id == idx) - return dev; - } - - return NULL; -} - -static struct vnet_dev * find_dev_by_mac(char * name) { - struct vnet_dev * dev = NULL; - - list_for_each_entry(dev, &(vnet_state.devs), node) { - if (!memcmp(dev->mac_addr, name, 6)) - return dev; - } - - return NULL; -} - int v3_vnet_add_dev(struct v3_vm_info *vm,uint8_t mac[6], int (*netif_input)(struct v3_vm_info * vm, struct v3_vnet_pkt * pkt, void * private_data), void * priv_data){