From owner-svn-src-head@freebsd.org Fri Jan 22 07:29:33 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 618C5A8B57C; Fri, 22 Jan 2016 07:29:33 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 39BCC1F83; Fri, 22 Jan 2016 07:29:33 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0M7TWNZ065632; Fri, 22 Jan 2016 07:29:32 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0M7TVA5065629; Fri, 22 Jan 2016 07:29:31 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201601220729.u0M7TVA5065629@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Fri, 22 Jan 2016 07:29:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r294553 - head/sys/dev/hyperv/vmbus X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Jan 2016 07:29:33 -0000 Author: sephe Date: Fri Jan 22 07:29:31 2016 New Revision: 294553 URL: https://svnweb.freebsd.org/changeset/base/294553 Log: hyperv/vmbus: Lookup channel through id table Vmbus event handler will need to find the channel by its relative id, when software interrupt for event happens. The original lookup searches the channel list, which is not very efficient. We now create a table indexed by the channel relative id to speed up the channel lookup. Submitted by: Hongjiang Zhang Reviewed by: delphij, adrain, sephe, Dexuan Cui Approved by: adrian (mentor) Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D4802 Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c head/sys/dev/hyperv/vmbus/hv_connection.c head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Fri Jan 22 07:25:59 2016 (r294552) +++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Fri Jan 22 07:29:31 2016 (r294553) @@ -271,14 +271,16 @@ vmbus_channel_process_offer(hv_vmbus_cha boolean_t f_new; hv_vmbus_channel* channel; int ret; + uint32_t relid; f_new = TRUE; channel = NULL; - + relid = new_channel->offer_msg.child_rel_id; /* * Make sure this is a new offer */ mtx_lock(&hv_vmbus_g_connection.channel_lock); + hv_vmbus_g_connection.channels[relid] = new_channel; TAILQ_FOREACH(channel, &hv_vmbus_g_connection.channel_anchor, list_entry) @@ -322,16 +324,18 @@ vmbus_channel_process_offer(hv_vmbus_cha mtx_unlock(&channel->sc_lock); /* Insert new channel into channel_anchor. */ - printf("Storvsc get multi-channel offer, rel=%u.\n", - new_channel->offer_msg.child_rel_id); + printf("VMBUS get multi-channel offer, rel=%u,sub=%u\n", + new_channel->offer_msg.child_rel_id, + new_channel->offer_msg.offer.sub_channel_index); mtx_lock(&hv_vmbus_g_connection.channel_lock); TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor, new_channel, list_entry); mtx_unlock(&hv_vmbus_g_connection.channel_lock); if(bootverbose) - printf("VMBUS: new multi-channel offer <%p>.\n", - new_channel); + printf("VMBUS: new multi-channel offer <%p>, " + "its primary channel is <%p>.\n", + new_channel, new_channel->primary_channel); /*XXX add it to percpu_list */ @@ -521,11 +525,14 @@ vmbus_channel_on_offer_rescind(hv_vmbus_ rescind = (hv_vmbus_channel_rescind_offer*) hdr; - channel = hv_vmbus_get_channel_from_rel_id(rescind->child_rel_id); + channel = hv_vmbus_g_connection.channels[rescind->child_rel_id]; if (channel == NULL) return; hv_vmbus_child_device_unregister(channel->device); + mtx_lock(&hv_vmbus_g_connection.channel_lock); + hv_vmbus_g_connection.channels[rescind->child_rel_id] = NULL; + mtx_unlock(&hv_vmbus_g_connection.channel_lock); } /** @@ -779,6 +786,8 @@ hv_vmbus_release_unattached_channels(voi hv_vmbus_child_device_unregister(channel->device); hv_vmbus_free_vmbus_channel(channel); } + bzero(hv_vmbus_g_connection.channels, + sizeof(hv_vmbus_channel*) * HV_CHANNEL_MAX_COUNT); mtx_unlock(&hv_vmbus_g_connection.channel_lock); } Modified: head/sys/dev/hyperv/vmbus/hv_connection.c ============================================================================== --- head/sys/dev/hyperv/vmbus/hv_connection.c Fri Jan 22 07:25:59 2016 (r294552) +++ head/sys/dev/hyperv/vmbus/hv_connection.c Fri Jan 22 07:29:31 2016 (r294553) @@ -229,6 +229,9 @@ hv_vmbus_connect(void) { goto cleanup; } + hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) * + HV_CHANNEL_MAX_COUNT, + M_DEVBUF, M_WAITOK | M_ZERO); /* * Find the highest vmbus version number we can support. */ @@ -292,6 +295,7 @@ hv_vmbus_connect(void) { free(msg_info, M_DEVBUF); } + free(hv_vmbus_g_connection.channels, M_DEVBUF); return (ret); } @@ -322,6 +326,7 @@ hv_vmbus_disconnect(void) { hv_work_queue_close(hv_vmbus_g_connection.work_queue); sema_destroy(&hv_vmbus_g_connection.control_sema); + free(hv_vmbus_g_connection.channels, M_DEVBUF); hv_vmbus_g_connection.connect_state = HV_DISCONNECTED; free(msg, M_DEVBUF); @@ -330,35 +335,6 @@ hv_vmbus_disconnect(void) { } /** - * Get the channel object given its child relative id (ie channel id) - */ -hv_vmbus_channel* -hv_vmbus_get_channel_from_rel_id(uint32_t rel_id) { - - hv_vmbus_channel* channel; - hv_vmbus_channel* foundChannel = NULL; - - /* - * TODO: - * Consider optimization where relids are stored in a fixed size array - * and channels are accessed without the need to take this lock or search - * the list. - */ - mtx_lock(&hv_vmbus_g_connection.channel_lock); - TAILQ_FOREACH(channel, - &hv_vmbus_g_connection.channel_anchor, list_entry) { - - if (channel->offer_msg.child_rel_id == rel_id) { - foundChannel = channel; - break; - } - } - mtx_unlock(&hv_vmbus_g_connection.channel_lock); - - return (foundChannel); -} - -/** * Process a channel event notification */ static void @@ -374,7 +350,7 @@ VmbusProcessChannelEvent(uint32_t relid) * the channel callback to process the event */ - channel = hv_vmbus_get_channel_from_rel_id(relid); + channel = hv_vmbus_g_connection.channels[relid]; if (channel == NULL) { return; @@ -470,7 +446,7 @@ hv_vmbus_on_events(void *arg) if (recv_interrupt_page != NULL) { for (dword = 0; dword < maxdword; dword++) { if (recv_interrupt_page[dword]) { - for (bit = 0; bit < 32; bit++) { + for (bit = 0; bit < HV_CHANNEL_DWORD_LEN; bit++) { if (synch_test_and_clear_bit(bit, (uint32_t *) &recv_interrupt_page[dword])) { rel_id = (dword << 5) + bit; Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h ============================================================================== --- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Fri Jan 22 07:25:59 2016 (r294552) +++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Fri Jan 22 07:29:31 2016 (r294553) @@ -58,6 +58,12 @@ typedef uint16_t hv_vmbus_status; #define HV_EVENT_FLAGS_BYTE_COUNT (256) #define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(uint32_t)) +/** + * max channel count <== event_flags_dword_count * bit_of_dword + */ +#define HV_CHANNEL_DWORD_LEN (32) +#define HV_CHANNEL_MAX_COUNT \ + ((HV_EVENT_FLAGS_DWORD_COUNT) * HV_CHANNEL_DWORD_LEN) /* * MessageId: HV_STATUS_INSUFFICIENT_BUFFERS * MessageText: @@ -355,6 +361,10 @@ typedef struct { TAILQ_HEAD(, hv_vmbus_channel) channel_anchor; struct mtx channel_lock; + /** + * channel table for fast lookup through id. + */ + hv_vmbus_channel **channels; hv_vmbus_handle work_queue; struct sema control_sema; } hv_vmbus_connection; @@ -699,7 +709,6 @@ int hv_vmbus_child_device_register( struct hv_device *child_dev); int hv_vmbus_child_device_unregister( struct hv_device *child_dev); -hv_vmbus_channel* hv_vmbus_get_channel_from_rel_id(uint32_t rel_id); /** * Connection interfaces