uio_hv_generic: use correct channel in isr
Need to mask the correct sub-channel in the callback from VMBUS
isr. Otherwise, can get in to infinite interrupt storm.
Fixes: 37b96a4931 ("uio_hv_generic: support sub-channels")
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9ab877a6cc
commit
135db384a2
@@ -94,10 +94,11 @@ hv_uio_irqcontrol(struct uio_info *info, s32 irq_state)
|
|||||||
*/
|
*/
|
||||||
static void hv_uio_channel_cb(void *context)
|
static void hv_uio_channel_cb(void *context)
|
||||||
{
|
{
|
||||||
struct hv_uio_private_data *pdata = context;
|
struct vmbus_channel *chan = context;
|
||||||
struct hv_device *dev = pdata->device;
|
struct hv_device *hv_dev = chan->device_obj;
|
||||||
|
struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
|
||||||
|
|
||||||
dev->channel->inbound.ring_buffer->interrupt_mask = 1;
|
chan->inbound.ring_buffer->interrupt_mask = 1;
|
||||||
virt_mb();
|
virt_mb();
|
||||||
|
|
||||||
uio_event_notify(&pdata->info);
|
uio_event_notify(&pdata->info);
|
||||||
@@ -180,19 +181,18 @@ static const struct bin_attribute ring_buffer_bin_attr = {
|
|||||||
.mmap = hv_uio_ring_mmap,
|
.mmap = hv_uio_ring_mmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Callback from VMBUS subystem when new channel created. */
|
/* Callback from VMBUS subsystem when new channel created. */
|
||||||
static void
|
static void
|
||||||
hv_uio_new_channel(struct vmbus_channel *new_sc)
|
hv_uio_new_channel(struct vmbus_channel *new_sc)
|
||||||
{
|
{
|
||||||
struct hv_device *hv_dev = new_sc->primary_channel->device_obj;
|
struct hv_device *hv_dev = new_sc->primary_channel->device_obj;
|
||||||
struct device *device = &hv_dev->device;
|
struct device *device = &hv_dev->device;
|
||||||
struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
|
|
||||||
const size_t ring_bytes = HV_RING_SIZE * PAGE_SIZE;
|
const size_t ring_bytes = HV_RING_SIZE * PAGE_SIZE;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Create host communication ring */
|
/* Create host communication ring */
|
||||||
ret = vmbus_open(new_sc, ring_bytes, ring_bytes, NULL, 0,
|
ret = vmbus_open(new_sc, ring_bytes, ring_bytes, NULL, 0,
|
||||||
hv_uio_channel_cb, pdata);
|
hv_uio_channel_cb, new_sc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(device, "vmbus_open subchannel failed: %d\n", ret);
|
dev_err(device, "vmbus_open subchannel failed: %d\n", ret);
|
||||||
return;
|
return;
|
||||||
@@ -234,7 +234,7 @@ hv_uio_probe(struct hv_device *dev,
|
|||||||
|
|
||||||
ret = vmbus_open(dev->channel, HV_RING_SIZE * PAGE_SIZE,
|
ret = vmbus_open(dev->channel, HV_RING_SIZE * PAGE_SIZE,
|
||||||
HV_RING_SIZE * PAGE_SIZE, NULL, 0,
|
HV_RING_SIZE * PAGE_SIZE, NULL, 0,
|
||||||
hv_uio_channel_cb, pdata);
|
hv_uio_channel_cb, dev->channel);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user