sepherosa_gmail.com created this revision.
sepherosa_gmail.com added reviewers: network, adrian, delphij, royger, 
decui_microsoft.com, honzhan_microsoft.com, howard0su_gmail.com.
sepherosa_gmail.com added a subscriber: freebsd-net-list.

REVISION SUMMARY
  Due to the miss use of ffs, where ffsl should be used.  And use system atomic 
operation instead.
  
  While I'm here, strigent chimney sending index assertion.

REVISION DETAIL
  https://reviews.freebsd.org/D5159

AFFECTED FILES
  sys/dev/hyperv/netvsc/hv_net_vsc.c

CHANGE DETAILS
  diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c 
b/sys/dev/hyperv/netvsc/hv_net_vsc.c
  --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
  +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
  @@ -136,15 +136,15 @@
        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 @@
                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 */

EMAIL PREFERENCES
  https://reviews.freebsd.org/settings/panel/emailpreferences/

To: sepherosa_gmail.com, network, adrian, delphij, royger, decui_microsoft.com, 
honzhan_microsoft.com, howard0su_gmail.com
Cc: freebsd-net-list
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -136,15 +136,15 @@
 	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 @@
 		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 */

_______________________________________________
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to