RE: [Patch v4 1/2] PCI: hv: Decouple the func definition in hv_dr_state from VSP message

From: Long Li
Date: Thu Feb 06 2020 - 18:51:18 EST


Hi guys,

Ping again...

Please take a look at these two patches.

Thanks

Long

>Subject: RE: [Patch v4 1/2] PCI: hv: Decouple the func definition in hv_dr_state
>from VSP message
>
>Hi Lorenzo,
>
>Can you take a look at this patch?
>
>Thanks
>
>Long
>
>>Subject: [Patch v4 1/2] PCI: hv: Decouple the func definition in
>>hv_dr_state from VSP message
>>
>>From: Long Li <longli@xxxxxxxxxxxxx>
>>
>>hv_dr_state is used to find present PCI devices on the bus. The
>>structure reuses struct pci_function_description from VSP message to describe
>a device.
>>
>>To prepare support for pci_function_description v2, decouple this
>>dependence in hv_dr_state so it can work with both v1 and v2 VSP messages.
>>
>>There is no functionality change.
>>
>>Signed-off-by: Long Li <longli@xxxxxxxxxxxxx>
>>Reviewed-by: Michael Kelley <mikelley@xxxxxxxxxxxxx>
>>---
>>Changes
>>v2: Changed some spaces to tabs, changed failure code to -ENOMEM
>>v3: Revised comment for function hv_pci_devices_present(), reformatted
>>patch title
>>v4: Fixed spelling
>>
>> drivers/pci/controller/pci-hyperv.c | 101 +++++++++++++++++++---------
>> 1 file changed, 70 insertions(+), 31 deletions(-)
>>
>>diff --git a/drivers/pci/controller/pci-hyperv.c
>>b/drivers/pci/controller/pci- hyperv.c index f1f300218fab..3b3e1967cf08
>>100644
>>--- a/drivers/pci/controller/pci-hyperv.c
>>+++ b/drivers/pci/controller/pci-hyperv.c
>>@@ -507,10 +507,24 @@ struct hv_dr_work {
>> struct hv_pcibus_device *bus;
>> };
>>
>>+struct hv_pcidev_description {
>>+ u16 v_id; /* vendor ID */
>>+ u16 d_id; /* device ID */
>>+ u8 rev;
>>+ u8 prog_intf;
>>+ u8 subclass;
>>+ u8 base_class;
>>+ u32 subsystem_id;
>>+ union win_slot_encoding win_slot;
>>+ u32 ser; /* serial number */
>>+ u32 flags;
>>+ u16 virtual_numa_node;
>>+};
>>+
>> struct hv_dr_state {
>> struct list_head list_entry;
>> u32 device_count;
>>- struct pci_function_description func[0];
>>+ struct hv_pcidev_description func[0];
>> };
>>
>> enum hv_pcichild_state {
>>@@ -527,7 +541,7 @@ struct hv_pci_dev {
>> refcount_t refs;
>> enum hv_pcichild_state state;
>> struct pci_slot *pci_slot;
>>- struct pci_function_description desc;
>>+ struct hv_pcidev_description desc;
>> bool reported_missing;
>> struct hv_pcibus_device *hbus;
>> struct work_struct wrk;
>>@@ -1862,7 +1876,7 @@ static void q_resource_requirements(void
>>*context, struct pci_response *resp,
>> * Return: Pointer to the new tracking struct
>> */
>> static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus,
>>- struct pci_function_description *desc)
>>+ struct hv_pcidev_description *desc)
>> {
>> struct hv_pci_dev *hpdev;
>> struct pci_child_message *res_req;
>>@@ -1973,7 +1987,7 @@ static void pci_devices_present_work(struct
>>work_struct *work) {
>> u32 child_no;
>> bool found;
>>- struct pci_function_description *new_desc;
>>+ struct hv_pcidev_description *new_desc;
>> struct hv_pci_dev *hpdev;
>> struct hv_pcibus_device *hbus;
>> struct list_head removed;
>>@@ -2090,43 +2104,26 @@ static void pci_devices_present_work(struct
>>work_struct *work)
>> put_hvpcibus(hbus);
>> kfree(dr);
>> }
>>-
>> /**
>>- * hv_pci_devices_present() - Handles list of new children
>>+ * hv_pci_start_relations_work() - Queue work to start device
>>+ discovery
>> * @hbus: Root PCI bus, as understood by this driver
>>- * @relations: Packet from host listing children
>>+ * @dr: The list of children returned from host
>> *
>>- * This function is invoked whenever a new list of devices for
>>- * this bus appears.
>>+ * Return: 0 on success, -errno on failure
>> */
>>-static void hv_pci_devices_present(struct hv_pcibus_device *hbus,
>>- struct pci_bus_relations *relations)
>>+static int hv_pci_start_relations_work(struct hv_pcibus_device *hbus,
>>+ struct hv_dr_state *dr)
>> {
>>- struct hv_dr_state *dr;
>> struct hv_dr_work *dr_wrk;
>>- unsigned long flags;
>> bool pending_dr;
>>+ unsigned long flags;
>>
>> dr_wrk = kzalloc(sizeof(*dr_wrk), GFP_NOWAIT);
>> if (!dr_wrk)
>>- return;
>>-
>>- dr = kzalloc(offsetof(struct hv_dr_state, func) +
>>- (sizeof(struct pci_function_description) *
>>- (relations->device_count)), GFP_NOWAIT);
>>- if (!dr) {
>>- kfree(dr_wrk);
>>- return;
>>- }
>>+ return -ENOMEM;
>>
>> INIT_WORK(&dr_wrk->wrk, pci_devices_present_work);
>> dr_wrk->bus = hbus;
>>- dr->device_count = relations->device_count;
>>- if (dr->device_count != 0) {
>>- memcpy(dr->func, relations->func,
>>- sizeof(struct pci_function_description) *
>>- dr->device_count);
>>- }
>>
>> spin_lock_irqsave(&hbus->device_list_lock, flags);
>> /*
>>@@ -2144,6 +2141,47 @@ static void hv_pci_devices_present(struct
>>hv_pcibus_device *hbus,
>> get_hvpcibus(hbus);
>> queue_work(hbus->wq, &dr_wrk->wrk);
>> }
>>+
>>+ return 0;
>>+}
>>+
>>+/**
>>+ * hv_pci_devices_present() - Handle list of new children
>>+ * @hbus: Root PCI bus, as understood by this driver
>>+ * @relations: Packet from host listing children
>>+ *
>>+ * Process a new list of devices on the bus. The list of devices is
>>+ * discovered by VSP and sent to us via VSP message PCI_BUS_RELATIONS,
>>+ * whenever a new list of devices for this bus appears.
>>+ */
>>+static void hv_pci_devices_present(struct hv_pcibus_device *hbus,
>>+ struct pci_bus_relations *relations) {
>>+ struct hv_dr_state *dr;
>>+ int i;
>>+
>>+ dr = kzalloc(offsetof(struct hv_dr_state, func) +
>>+ (sizeof(struct hv_pcidev_description) *
>>+ (relations->device_count)), GFP_NOWAIT);
>>+
>>+ if (!dr)
>>+ return;
>>+
>>+ dr->device_count = relations->device_count;
>>+ for (i = 0; i < dr->device_count; i++) {
>>+ dr->func[i].v_id = relations->func[i].v_id;
>>+ dr->func[i].d_id = relations->func[i].d_id;
>>+ dr->func[i].rev = relations->func[i].rev;
>>+ dr->func[i].prog_intf = relations->func[i].prog_intf;
>>+ dr->func[i].subclass = relations->func[i].subclass;
>>+ dr->func[i].base_class = relations->func[i].base_class;
>>+ dr->func[i].subsystem_id = relations->func[i].subsystem_id;
>>+ dr->func[i].win_slot = relations->func[i].win_slot;
>>+ dr->func[i].ser = relations->func[i].ser;
>>+ }
>>+
>>+ if (hv_pci_start_relations_work(hbus, dr))
>>+ kfree(dr);
>> }
>>
>> /**
>>@@ -3018,7 +3056,7 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
>> struct pci_packet teardown_packet;
>> u8 buffer[sizeof(struct pci_message)];
>> } pkt;
>>- struct pci_bus_relations relations;
>>+ struct hv_dr_state *dr;
>> struct hv_pci_compl comp_pkt;
>> int ret;
>>
>>@@ -3030,8 +3068,9 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
>> return;
>>
>> /* Delete any children which might still exist. */
>>- memset(&relations, 0, sizeof(relations));
>>- hv_pci_devices_present(hbus, &relations);
>>+ dr = kzalloc(sizeof(*dr), GFP_KERNEL);
>>+ if (dr && hv_pci_start_relations_work(hbus, dr))
>>+ kfree(dr);
>>
>> ret = hv_send_resources_released(hdev);
>> if (ret)
>>--
>>2.17.1