Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Feb 2016 05:31:31 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r295303 - head/sys/dev/hyperv/netvsc
Message-ID:  <201602050531.u155VVH0072682@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Fri Feb  5 05:31:31 2016
New Revision: 295303
URL: https://svnweb.freebsd.org/changeset/base/295303

Log:
  hyperv/hn: Recover half of the chimney sending space
  
  We lost half of the chimney sending space, because we mis-used
  ffs() on a 64 bits mask, where ffsl() should be used.
  
  While I'm here:
  - Use system atomic operation instead.
  - Stringent chimney sending index assertion.
  
  Reviewed by:	adrian
  Approved by:	adrian (mentor)
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D5159

Modified:
  head/sys/dev/hyperv/netvsc/hv_net_vsc.c

Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.c	Fri Feb  5 05:25:11 2016	(r295302)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c	Fri Feb  5 05:31:31 2016	(r295303)
@@ -136,15 +136,15 @@ hv_nv_get_next_send_section(netvsc_dev *
 	int i;
 
 	for (i = 0; i < bitsmap_words; i++) {
-		idx = ffs(~bitsmap[i]);
+		idx = ffsl(~bitsmap[i]);
 		if (0 == idx)
 			continue;
 
 		idx--;
-		if (i * BITS_PER_LONG + idx >= net_dev->send_section_count)
-			return (ret);
+		KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
+		    ("invalid i %d and idx %lu", i, idx));
 
-		if (synch_test_and_set_bit(idx, &bitsmap[i]))
+		if (atomic_testandset_long(&bitsmap[i], idx))
 			continue;
 
 		ret = i * BITS_PER_LONG + idx;
@@ -789,8 +789,27 @@ hv_nv_on_send_completion(netvsc_dev *net
 		if (NULL != net_vsc_pkt) {
 			if (net_vsc_pkt->send_buf_section_idx !=
 			    NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
-				synch_change_bit(net_vsc_pkt->send_buf_section_idx,
-				    net_dev->send_section_bitsmap);
+				u_long mask;
+				int idx;
+
+				idx = net_vsc_pkt->send_buf_section_idx /
+				    BITS_PER_LONG;
+				KASSERT(idx < net_dev->bitsmap_words,
+				    ("invalid section index %u",
+				     net_vsc_pkt->send_buf_section_idx));
+				mask = 1UL <<
+				    (net_vsc_pkt->send_buf_section_idx %
+				     BITS_PER_LONG);
+
+				KASSERT(net_dev->send_section_bitsmap[idx] &
+				    mask,
+				    ("index bitmap 0x%lx, section index %u, "
+				     "bitmap idx %d, bitmask 0x%lx",
+				     net_dev->send_section_bitsmap[idx],
+				     net_vsc_pkt->send_buf_section_idx,
+				     idx, mask));
+				atomic_clear_long(
+				    &net_dev->send_section_bitsmap[idx], mask);
 			}
 			
 			/* Notify the layer above us */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201602050531.u155VVH0072682>