vDPA/ifcvf: detect and report max allowed vq size
authorZhu Lingshan <lingshan.zhu@intel.com>
Mon, 12 Jun 2023 15:14:19 +0000 (23:14 +0800)
committerMichael S. Tsirkin <mst@redhat.com>
Mon, 3 Jul 2023 16:15:12 +0000 (12:15 -0400)
Rather than a hardcode, this commit detects
and reports the max value of allowed size
of the virtqueues

Signed-off-by: Zhu Lingshan <lingshan.zhu@intel.com>
Message-Id: <20230612151420.1019504-3-lingshan.zhu@intel.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
drivers/vdpa/ifcvf/ifcvf_base.c
drivers/vdpa/ifcvf/ifcvf_base.h
drivers/vdpa/ifcvf/ifcvf_main.c

index f86495a..f4d7d96 100644 (file)
@@ -69,6 +69,37 @@ static int ifcvf_read_config_range(struct pci_dev *dev,
        return 0;
 }
 
+static u16 ifcvf_get_vq_size(struct ifcvf_hw *hw, u16 qid)
+{
+       u16 queue_size;
+
+       vp_iowrite16(qid, &hw->common_cfg->queue_select);
+       queue_size = vp_ioread16(&hw->common_cfg->queue_size);
+
+       return queue_size;
+}
+
+/* This function returns the max allowed safe size for
+ * all virtqueues. It is the minimal size that can be
+ * suppprted by all virtqueues.
+ */
+u16 ifcvf_get_max_vq_size(struct ifcvf_hw *hw)
+{
+       u16 queue_size, max_size, qid;
+
+       max_size = ifcvf_get_vq_size(hw, 0);
+       for (qid = 1; qid < hw->nr_vring; qid++) {
+               queue_size = ifcvf_get_vq_size(hw, qid);
+               /* 0 means the queue is unavailable */
+               if (!queue_size)
+                       continue;
+
+               max_size = min(queue_size, max_size);
+       }
+
+       return max_size;
+}
+
 int ifcvf_init_hw(struct ifcvf_hw *hw, struct pci_dev *pdev)
 {
        struct virtio_pci_cap cap;
index fa79718..30935a9 100644 (file)
@@ -28,7 +28,6 @@
 #define IFCVF_MAX_QUEUES       17
 
 #define IFCVF_QUEUE_ALIGNMENT  PAGE_SIZE
-#define IFCVF_QUEUE_MAX                32768
 #define IFCVF_PCI_MAX_RESOURCE 6
 
 #define IFCVF_LM_CFG_SIZE              0x40
@@ -138,4 +137,5 @@ bool ifcvf_get_vq_ready(struct ifcvf_hw *hw, u16 qid);
 void ifcvf_set_vq_ready(struct ifcvf_hw *hw, u16 qid, bool ready);
 void ifcvf_set_driver_features(struct ifcvf_hw *hw, u64 features);
 u64 ifcvf_get_driver_features(struct ifcvf_hw *hw);
+u16 ifcvf_get_max_vq_size(struct ifcvf_hw *hw);
 #endif /* _IFCVF_H_ */
index 2af0de7..c3ece39 100644 (file)
@@ -451,7 +451,9 @@ static int ifcvf_vdpa_reset(struct vdpa_device *vdpa_dev)
 
 static u16 ifcvf_vdpa_get_vq_num_max(struct vdpa_device *vdpa_dev)
 {
-       return IFCVF_QUEUE_MAX;
+       struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
+
+       return ifcvf_get_max_vq_size(vf);
 }
 
 static int ifcvf_vdpa_get_vq_state(struct vdpa_device *vdpa_dev, u16 qid,