Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drivers/hv: introduce vmbus_channel_set_cpu()

The core functionality in target_cpu_store() is also needed in a
subsequent patch for automatically changing the CPU when taking
a CPU offline. As such, factor out the body of target_cpu_store()
into new function vmbus_channel_set_cpu() that can also be used
elsewhere.

No functional change is intended.

Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Michael Kelley <mhklinux@outlook.com>
Cc: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/20250117203309.192072-2-hamzamahfooz@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <20250117203309.192072-2-hamzamahfooz@linux.microsoft.com>

authored by

Hamza Mahfooz and committed by
Wei Liu
5e4304ff 7c0db8a4

+32 -21
+31 -21
drivers/hv/vmbus_drv.c
··· 1611 1611 { 1612 1612 return sprintf(buf, "%u\n", channel->target_cpu); 1613 1613 } 1614 - static ssize_t target_cpu_store(struct vmbus_channel *channel, 1615 - const char *buf, size_t count) 1614 + 1615 + int vmbus_channel_set_cpu(struct vmbus_channel *channel, u32 target_cpu) 1616 1616 { 1617 - u32 target_cpu, origin_cpu; 1618 - ssize_t ret = count; 1617 + u32 origin_cpu; 1618 + int ret = 0; 1619 + 1620 + lockdep_assert_cpus_held(); 1621 + lockdep_assert_held(&vmbus_connection.channel_mutex); 1619 1622 1620 1623 if (vmbus_proto_version < VERSION_WIN10_V4_1) 1621 - return -EIO; 1622 - 1623 - if (sscanf(buf, "%uu", &target_cpu) != 1) 1624 1624 return -EIO; 1625 1625 1626 1626 /* Validate target_cpu for the cpumask_test_cpu() operation below. */ ··· 1630 1630 if (!cpumask_test_cpu(target_cpu, housekeeping_cpumask(HK_TYPE_MANAGED_IRQ))) 1631 1631 return -EINVAL; 1632 1632 1633 - /* No CPUs should come up or down during this. */ 1634 - cpus_read_lock(); 1635 - 1636 - if (!cpu_online(target_cpu)) { 1637 - cpus_read_unlock(); 1633 + if (!cpu_online(target_cpu)) 1638 1634 return -EINVAL; 1639 - } 1640 1635 1641 1636 /* 1642 - * Synchronizes target_cpu_store() and channel closure: 1637 + * Synchronizes vmbus_channel_set_cpu() and channel closure: 1643 1638 * 1644 1639 * { Initially: state = CHANNEL_OPENED } 1645 1640 * 1646 1641 * CPU1 CPU2 1647 1642 * 1648 - * [target_cpu_store()] [vmbus_disconnect_ring()] 1643 + * [vmbus_channel_set_cpu()] [vmbus_disconnect_ring()] 1649 1644 * 1650 1645 * LOCK channel_mutex LOCK channel_mutex 1651 1646 * LOAD r1 = state LOAD r2 = state ··· 1655 1660 * Note. The host processes the channel messages "sequentially", in 1656 1661 * the order in which they are received on a per-partition basis. 1657 1662 */ 1658 - mutex_lock(&vmbus_connection.channel_mutex); 1659 1663 1660 1664 /* 1661 1665 * Hyper-V will ignore MODIFYCHANNEL messages for "non-open" channels; ··· 1662 1668 */ 1663 1669 if (channel->state != CHANNEL_OPENED_STATE) { 1664 1670 ret = -EIO; 1665 - goto cpu_store_unlock; 1671 + goto end; 1666 1672 } 1667 1673 1668 1674 origin_cpu = channel->target_cpu; 1669 1675 if (target_cpu == origin_cpu) 1670 - goto cpu_store_unlock; 1676 + goto end; 1671 1677 1672 1678 if (vmbus_send_modifychannel(channel, 1673 1679 hv_cpu_number_to_vp_number(target_cpu))) { 1674 1680 ret = -EIO; 1675 - goto cpu_store_unlock; 1681 + goto end; 1676 1682 } 1677 1683 1678 1684 /* ··· 1702 1708 origin_cpu, target_cpu); 1703 1709 } 1704 1710 1705 - cpu_store_unlock: 1711 + end: 1712 + return ret; 1713 + } 1714 + 1715 + static ssize_t target_cpu_store(struct vmbus_channel *channel, 1716 + const char *buf, size_t count) 1717 + { 1718 + u32 target_cpu; 1719 + ssize_t ret; 1720 + 1721 + if (sscanf(buf, "%uu", &target_cpu) != 1) 1722 + return -EIO; 1723 + 1724 + cpus_read_lock(); 1725 + mutex_lock(&vmbus_connection.channel_mutex); 1726 + ret = vmbus_channel_set_cpu(channel, target_cpu); 1706 1727 mutex_unlock(&vmbus_connection.channel_mutex); 1707 1728 cpus_read_unlock(); 1708 - return ret; 1729 + 1730 + return ret ?: count; 1709 1731 } 1710 1732 static VMBUS_CHAN_ATTR(cpu, 0644, target_cpu_show, target_cpu_store); 1711 1733
+1
include/linux/hyperv.h
··· 1661 1661 const guid_t *shv_host_servie_id); 1662 1662 int vmbus_send_modifychannel(struct vmbus_channel *channel, u32 target_vp); 1663 1663 void vmbus_set_event(struct vmbus_channel *channel); 1664 + int vmbus_channel_set_cpu(struct vmbus_channel *channel, u32 target_cpu); 1664 1665 1665 1666 /* Get the start of the ring buffer. */ 1666 1667 static inline void *