@@ -422,7 +422,7 @@ static void reclaim_dma_bufs(void)
422
422
}
423
423
}
424
424
425
- static struct port_buffer * alloc_buf (struct virtqueue * vq , size_t buf_size ,
425
+ static struct port_buffer * alloc_buf (struct virtio_device * vdev , size_t buf_size ,
426
426
int pages )
427
427
{
428
428
struct port_buffer * buf ;
@@ -445,16 +445,16 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
445
445
return buf ;
446
446
}
447
447
448
- if (is_rproc_serial (vq -> vdev )) {
448
+ if (is_rproc_serial (vdev )) {
449
449
/*
450
450
* Allocate DMA memory from ancestor. When a virtio
451
451
* device is created by remoteproc, the DMA memory is
452
452
* associated with the grandparent device:
453
453
* vdev => rproc => platform-dev.
454
454
*/
455
- if (!vq -> vdev -> dev .parent || !vq -> vdev -> dev .parent -> parent )
455
+ if (!vdev -> dev .parent || !vdev -> dev .parent -> parent )
456
456
goto free_buf ;
457
- buf -> dev = vq -> vdev -> dev .parent -> parent ;
457
+ buf -> dev = vdev -> dev .parent -> parent ;
458
458
459
459
/* Increase device refcnt to avoid freeing it */
460
460
get_device (buf -> dev );
@@ -838,7 +838,7 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
838
838
839
839
count = min ((size_t )(32 * 1024 ), count );
840
840
841
- buf = alloc_buf (port -> out_vq , count , 0 );
841
+ buf = alloc_buf (port -> portdev -> vdev , count , 0 );
842
842
if (!buf )
843
843
return - ENOMEM ;
844
844
@@ -957,7 +957,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
957
957
if (ret < 0 )
958
958
goto error_out ;
959
959
960
- buf = alloc_buf (port -> out_vq , 0 , pipe -> nrbufs );
960
+ buf = alloc_buf (port -> portdev -> vdev , 0 , pipe -> nrbufs );
961
961
if (!buf ) {
962
962
ret = - ENOMEM ;
963
963
goto error_out ;
@@ -1374,7 +1374,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
1374
1374
1375
1375
nr_added_bufs = 0 ;
1376
1376
do {
1377
- buf = alloc_buf (vq , PAGE_SIZE , 0 );
1377
+ buf = alloc_buf (vq -> vdev , PAGE_SIZE , 0 );
1378
1378
if (!buf )
1379
1379
break ;
1380
1380
@@ -1402,7 +1402,6 @@ static int add_port(struct ports_device *portdev, u32 id)
1402
1402
{
1403
1403
char debugfs_name [16 ];
1404
1404
struct port * port ;
1405
- struct port_buffer * buf ;
1406
1405
dev_t devt ;
1407
1406
unsigned int nr_added_bufs ;
1408
1407
int err ;
@@ -1513,8 +1512,6 @@ static int add_port(struct ports_device *portdev, u32 id)
1513
1512
return 0 ;
1514
1513
1515
1514
free_inbufs :
1516
- while ((buf = virtqueue_detach_unused_buf (port -> in_vq )))
1517
- free_buf (buf , true);
1518
1515
free_device :
1519
1516
device_destroy (pdrvdata .class , port -> dev -> devt );
1520
1517
free_cdev :
@@ -1539,34 +1536,14 @@ static void remove_port(struct kref *kref)
1539
1536
1540
1537
static void remove_port_data (struct port * port )
1541
1538
{
1542
- struct port_buffer * buf ;
1543
-
1544
1539
spin_lock_irq (& port -> inbuf_lock );
1545
1540
/* Remove unused data this port might have received. */
1546
1541
discard_port_data (port );
1547
1542
spin_unlock_irq (& port -> inbuf_lock );
1548
1543
1549
- /* Remove buffers we queued up for the Host to send us data in. */
1550
- do {
1551
- spin_lock_irq (& port -> inbuf_lock );
1552
- buf = virtqueue_detach_unused_buf (port -> in_vq );
1553
- spin_unlock_irq (& port -> inbuf_lock );
1554
- if (buf )
1555
- free_buf (buf , true);
1556
- } while (buf );
1557
-
1558
1544
spin_lock_irq (& port -> outvq_lock );
1559
1545
reclaim_consumed_buffers (port );
1560
1546
spin_unlock_irq (& port -> outvq_lock );
1561
-
1562
- /* Free pending buffers from the out-queue. */
1563
- do {
1564
- spin_lock_irq (& port -> outvq_lock );
1565
- buf = virtqueue_detach_unused_buf (port -> out_vq );
1566
- spin_unlock_irq (& port -> outvq_lock );
1567
- if (buf )
1568
- free_buf (buf , true);
1569
- } while (buf );
1570
1547
}
1571
1548
1572
1549
/*
@@ -1791,13 +1768,24 @@ static void control_work_handler(struct work_struct *work)
1791
1768
spin_unlock (& portdev -> c_ivq_lock );
1792
1769
}
1793
1770
1771
+ static void flush_bufs (struct virtqueue * vq , bool can_sleep )
1772
+ {
1773
+ struct port_buffer * buf ;
1774
+ unsigned int len ;
1775
+
1776
+ while ((buf = virtqueue_get_buf (vq , & len )))
1777
+ free_buf (buf , can_sleep );
1778
+ }
1779
+
1794
1780
static void out_intr (struct virtqueue * vq )
1795
1781
{
1796
1782
struct port * port ;
1797
1783
1798
1784
port = find_port_by_vq (vq -> vdev -> priv , vq );
1799
- if (!port )
1785
+ if (!port ) {
1786
+ flush_bufs (vq , false);
1800
1787
return ;
1788
+ }
1801
1789
1802
1790
wake_up_interruptible (& port -> waitqueue );
1803
1791
}
@@ -1808,8 +1796,10 @@ static void in_intr(struct virtqueue *vq)
1808
1796
unsigned long flags ;
1809
1797
1810
1798
port = find_port_by_vq (vq -> vdev -> priv , vq );
1811
- if (!port )
1799
+ if (!port ) {
1800
+ flush_bufs (vq , false);
1812
1801
return ;
1802
+ }
1813
1803
1814
1804
spin_lock_irqsave (& port -> inbuf_lock , flags );
1815
1805
port -> inbuf = get_inbuf (port );
@@ -1984,24 +1974,54 @@ static const struct file_operations portdev_fops = {
1984
1974
1985
1975
static void remove_vqs (struct ports_device * portdev )
1986
1976
{
1977
+ struct virtqueue * vq ;
1978
+
1979
+ virtio_device_for_each_vq (portdev -> vdev , vq ) {
1980
+ struct port_buffer * buf ;
1981
+
1982
+ flush_bufs (vq , true);
1983
+ while ((buf = virtqueue_detach_unused_buf (vq )))
1984
+ free_buf (buf , true);
1985
+ }
1987
1986
portdev -> vdev -> config -> del_vqs (portdev -> vdev );
1988
1987
kfree (portdev -> in_vqs );
1989
1988
kfree (portdev -> out_vqs );
1990
1989
}
1991
1990
1992
- static void remove_controlq_data (struct ports_device * portdev )
1991
+ static void virtcons_remove (struct virtio_device * vdev )
1993
1992
{
1994
- struct port_buffer * buf ;
1995
- unsigned int len ;
1993
+ struct ports_device * portdev ;
1994
+ struct port * port , * port2 ;
1996
1995
1997
- if (!use_multiport (portdev ))
1998
- return ;
1996
+ portdev = vdev -> priv ;
1999
1997
2000
- while ((buf = virtqueue_get_buf (portdev -> c_ivq , & len )))
2001
- free_buf (buf , true);
1998
+ spin_lock_irq (& pdrvdata_lock );
1999
+ list_del (& portdev -> list );
2000
+ spin_unlock_irq (& pdrvdata_lock );
2002
2001
2003
- while ((buf = virtqueue_detach_unused_buf (portdev -> c_ivq )))
2004
- free_buf (buf , true);
2002
+ /* Disable interrupts for vqs */
2003
+ vdev -> config -> reset (vdev );
2004
+ /* Finish up work that's lined up */
2005
+ if (use_multiport (portdev ))
2006
+ cancel_work_sync (& portdev -> control_work );
2007
+ else
2008
+ cancel_work_sync (& portdev -> config_work );
2009
+
2010
+ list_for_each_entry_safe (port , port2 , & portdev -> ports , list )
2011
+ unplug_port (port );
2012
+
2013
+ unregister_chrdev (portdev -> chr_major , "virtio-portsdev" );
2014
+
2015
+ /*
2016
+ * When yanking out a device, we immediately lose the
2017
+ * (device-side) queues. So there's no point in keeping the
2018
+ * guest side around till we drop our final reference. This
2019
+ * also means that any ports which are in an open state will
2020
+ * have to just stop using the port, as the vqs are going
2021
+ * away.
2022
+ */
2023
+ remove_vqs (portdev );
2024
+ kfree (portdev );
2005
2025
}
2006
2026
2007
2027
/*
@@ -2070,6 +2090,7 @@ static int virtcons_probe(struct virtio_device *vdev)
2070
2090
2071
2091
spin_lock_init (& portdev -> ports_lock );
2072
2092
INIT_LIST_HEAD (& portdev -> ports );
2093
+ INIT_LIST_HEAD (& portdev -> list );
2073
2094
2074
2095
virtio_device_ready (portdev -> vdev );
2075
2096
@@ -2087,8 +2108,15 @@ static int virtcons_probe(struct virtio_device *vdev)
2087
2108
if (!nr_added_bufs ) {
2088
2109
dev_err (& vdev -> dev ,
2089
2110
"Error allocating buffers for control queue\n" );
2090
- err = - ENOMEM ;
2091
- goto free_vqs ;
2111
+ /*
2112
+ * The host might want to notify mgmt sw about device
2113
+ * add failure.
2114
+ */
2115
+ __send_control_msg (portdev , VIRTIO_CONSOLE_BAD_ID ,
2116
+ VIRTIO_CONSOLE_DEVICE_READY , 0 );
2117
+ /* Device was functional: we need full cleanup. */
2118
+ virtcons_remove (vdev );
2119
+ return - ENOMEM ;
2092
2120
}
2093
2121
} else {
2094
2122
/*
@@ -2119,11 +2147,6 @@ static int virtcons_probe(struct virtio_device *vdev)
2119
2147
2120
2148
return 0 ;
2121
2149
2122
- free_vqs :
2123
- /* The host might want to notify mgmt sw about device add failure */
2124
- __send_control_msg (portdev , VIRTIO_CONSOLE_BAD_ID ,
2125
- VIRTIO_CONSOLE_DEVICE_READY , 0 );
2126
- remove_vqs (portdev );
2127
2150
free_chrdev :
2128
2151
unregister_chrdev (portdev -> chr_major , "virtio-portsdev" );
2129
2152
free :
@@ -2132,43 +2155,6 @@ static int virtcons_probe(struct virtio_device *vdev)
2132
2155
return err ;
2133
2156
}
2134
2157
2135
- static void virtcons_remove (struct virtio_device * vdev )
2136
- {
2137
- struct ports_device * portdev ;
2138
- struct port * port , * port2 ;
2139
-
2140
- portdev = vdev -> priv ;
2141
-
2142
- spin_lock_irq (& pdrvdata_lock );
2143
- list_del (& portdev -> list );
2144
- spin_unlock_irq (& pdrvdata_lock );
2145
-
2146
- /* Disable interrupts for vqs */
2147
- vdev -> config -> reset (vdev );
2148
- /* Finish up work that's lined up */
2149
- if (use_multiport (portdev ))
2150
- cancel_work_sync (& portdev -> control_work );
2151
- else
2152
- cancel_work_sync (& portdev -> config_work );
2153
-
2154
- list_for_each_entry_safe (port , port2 , & portdev -> ports , list )
2155
- unplug_port (port );
2156
-
2157
- unregister_chrdev (portdev -> chr_major , "virtio-portsdev" );
2158
-
2159
- /*
2160
- * When yanking out a device, we immediately lose the
2161
- * (device-side) queues. So there's no point in keeping the
2162
- * guest side around till we drop our final reference. This
2163
- * also means that any ports which are in an open state will
2164
- * have to just stop using the port, as the vqs are going
2165
- * away.
2166
- */
2167
- remove_controlq_data (portdev );
2168
- remove_vqs (portdev );
2169
- kfree (portdev );
2170
- }
2171
-
2172
2158
static struct virtio_device_id id_table [] = {
2173
2159
{ VIRTIO_ID_CONSOLE , VIRTIO_DEV_ANY_ID },
2174
2160
{ 0 },
@@ -2209,7 +2195,6 @@ static int virtcons_freeze(struct virtio_device *vdev)
2209
2195
*/
2210
2196
if (use_multiport (portdev ))
2211
2197
virtqueue_disable_cb (portdev -> c_ivq );
2212
- remove_controlq_data (portdev );
2213
2198
2214
2199
list_for_each_entry (port , & portdev -> ports , list ) {
2215
2200
virtqueue_disable_cb (port -> in_vq );
0 commit comments