Comments (1)
A simple lock/unlock as shown below resolves the data race but fails the unit tests.
I wonder why.
Click to expand
$ git --no-pager diff
diff --git a/virtio/blk.go b/virtio/blk.go
index 4dfeaf10f3f9..4f57874598e4 100644
--- a/virtio/blk.go
+++ b/virtio/blk.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"os"
+ "sync"
"unsafe"
"github.com/bobuhiro11/gokvm/pci"
@@ -28,6 +29,7 @@ type Blk struct {
irq uint8
IRQInjector IRQInjector
+ mux sync.Mutex
}
type blkHdr struct {
@@ -49,7 +51,10 @@ type blkHeader struct {
capacity uint64
}
-func (v Blk) GetDeviceHeader() pci.DeviceHeader {
+func (v *Blk) GetDeviceHeader() pci.DeviceHeader {
+ v.mux.Lock()
+ defer v.mux.Unlock()
+
return pci.DeviceHeader{
DeviceID: 0x1001,
VendorID: 0x1AF4,
@@ -66,7 +71,10 @@ func (v Blk) GetDeviceHeader() pci.DeviceHeader {
}
}
-func (v Blk) IOInHandler(port uint64, bytes []byte) error {
+func (v *Blk) IOInHandler(port uint64, bytes []byte) error {
+ v.mux.Lock()
+ defer v.mux.Unlock()
+
offset := int(port - BlkIOPortStart)
b, err := v.Hdr.Bytes()
@@ -147,10 +155,16 @@ func (v *Blk) IO() error {
}
usedRing.Idx++
+
+ v.mux.Lock()
v.LastAvailIdx[sel]++
+ v.mux.Unlock()
}
+ v.mux.Lock()
v.Hdr.commonHeader.isr = 0x1
+ v.mux.Unlock()
+
if err := v.IRQInjector.InjectVirtioBlkIRQ(); err != nil {
return err
}
@@ -159,6 +173,9 @@ func (v *Blk) IO() error {
}
func (v *Blk) IOOutHandler(port uint64, bytes []byte) error {
+ v.mux.Lock()
+ defer v.mux.Unlock()
+
offset := int(port - BlkIOPortStart)
switch offset {
diff --git a/virtio/net.go b/virtio/net.go
index 7c2c18a2e130..01cec8286e40 100644
--- a/virtio/net.go
+++ b/virtio/net.go
@@ -8,6 +8,7 @@ import (
"io"
"os"
"os/signal"
+ "sync"
"syscall"
"unsafe"
@@ -47,6 +48,7 @@ type Net struct {
irq uint8
IRQInjector IRQInjector
+ mux sync.Mutex
}
func (h netHdr) Bytes() ([]byte, error) {
@@ -65,7 +67,10 @@ type netHeader struct {
_ uint16 // maxVirtQueuePairs
}
-func (v Net) GetDeviceHeader() pci.DeviceHeader {
+func (v *Net) GetDeviceHeader() pci.DeviceHeader {
+ v.mux.Lock()
+ defer v.mux.Unlock()
+
return pci.DeviceHeader{
DeviceID: 0x1000,
VendorID: 0x1AF4,
@@ -82,15 +87,20 @@ func (v Net) GetDeviceHeader() pci.DeviceHeader {
}
}
-func (v Net) IOInHandler(port uint64, bytes []byte) error {
+func (v *Net) IOInHandler(port uint64, bytes []byte) error {
+ v.mux.Lock()
+ defer v.mux.Unlock()
+
offset := int(port - NetIOPortStart)
b, err := v.Hdr.Bytes()
+
if err != nil {
return err
}
l := len(bytes)
+
copy(bytes[:l], b[offset:offset+l])
return nil
@@ -119,7 +129,10 @@ func (v *Net) Rx() error {
sel := 0
- if v.VirtQueue[sel] == nil {
+ v.mux.Lock()
+ q := v.VirtQueue[sel]
+ v.mux.Unlock()
+ if q == nil {
return ErrVQNotInit
}
@@ -171,7 +184,9 @@ func (v *Net) Rx() error {
usedRing.Idx++
+ v.mux.Lock()
v.Hdr.commonHeader.isr = 0x1
+ v.mux.Unlock()
return v.IRQInjector.InjectVirtioNetIRQ()
}
@@ -229,15 +244,23 @@ func (v *Net) Tx() error {
return err
}
usedRing.Idx++
+
+ v.mux.Lock()
v.LastAvailIdx[sel]++
+ v.mux.Unlock()
}
+ v.mux.Lock()
v.Hdr.commonHeader.isr = 0x1
+ v.mux.Unlock()
return v.IRQInjector.InjectVirtioNetIRQ()
}
func (v *Net) IOOutHandler(port uint64, bytes []byte) error {
+ v.mux.Lock()
+ defer v.mux.Unlock()
+
offset := int(port - NetIOPortStart)
switch offset {
from gokvm.
Related Issues (14)
- add virtio for console
- flaky tests in kvm package
- [BUG] Shutdown does not exits the VM HOT 2
- shutdown command got hung HOT 2
- Discussion: What modes of booting to support.
- Discussion: New package for flags parsing. HOT 7
- CI credits: Whoopsie HOT 2
- panic when experiment gokvm with custom init binary HOT 2
- Panic: unexpected kvm exit reason 8 HOT 7
- Create a new release HOT 1
- Use the correct value of tsc_early_khz
- a poweroff command should result in an exit HOT 1
- Need vhost / vsock support HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gokvm.