aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>2016-02-09 02:25:17 +0200
committerIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>2016-02-10 15:39:22 +0200
commit8c7fe1e9f1cc7f4427a356c7c58563ff75743723 (patch)
treea93ba875ebda86eaa666fb7e551724d100388d5b
parent1bf5202e27134a0eb14f2ff3a7b2b3cc6779a724 (diff)
linux-ks2: schdedule: fix multischedule to use preschedule
It's supposed to be faster to send preschedule command when we potentially are going to receive more packets. Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
-rw-r--r--platform/linux-keystone2/odp_schedule.c79
1 files changed, 76 insertions, 3 deletions
diff --git a/platform/linux-keystone2/odp_schedule.c b/platform/linux-keystone2/odp_schedule.c
index 069def1e..2cc01c73 100644
--- a/platform/linux-keystone2/odp_schedule.c
+++ b/platform/linux-keystone2/odp_schedule.c
@@ -135,9 +135,82 @@ odp_event_t odp_schedule(odp_queue_t *out_queue, uint64_t wait)
int odp_schedule_multi(odp_queue_t *out_queue, uint64_t wait,
odp_event_t out_ev[], int num)
{
- ODP_AS_STR(num > 0, "Zero buffers requested\n");
- out_ev[0] = odp_schedule(out_queue, wait);
- return (out_ev[0] == ODP_EVENT_INVALID) ? 0 : 1;
+ int first = 1;
+ int rx_num = 0;
+ odp_time_t time, start_time, diff, wtime;
+ em_event_t em_event;
+ em_queue_t em_queue = EM_QUEUE_UNDEF;
+ odp_event_t event = ODP_EVENT_INVALID;
+
+ odp_pr_dbg("scheduling ....\n");
+ odp_schedule_release_atomic();
+
+ num--;
+ while (1) {
+ em_event = ti_em_schedule_once(&em_queue);
+ if (rx_num < num)
+ ti_em_preschedule();
+
+ if (odp_likely(em_event != EM_EVENT_UNDEF)) {
+
+ odp_queue_t src_queue = _odp_queue_from_em_queue(em_queue);
+
+ event = (odp_event_t)ti_em_to_packet(em_event);
+ out_ev[rx_num] = event;
+
+ /**
+ * Convert buffer pointers to virtual addresses as the
+ * rest of code assumes them to be virtual.
+ *
+ * @todo: Double convertion phy->virt->phy->virt is
+ * done, because EM returns virtual address and McSDK
+ * doesn't have API to convert only buffers. That can
+ * be fixed.
+ * Better to postpone conversion until buffer is needed.
+ */
+ Osal_qmssConvertDescPhyToVirt(0, Osal_qmssVirtToPhy(
+ _odp_ev_to_cppi_desc(event)));
+ if (out_queue)
+ *out_queue = src_queue;
+
+ /* Packets from PKTIN queues have to be updated */
+ if (odp_queue_type(src_queue) == ODP_QUEUE_TYPE_PKTIN)
+ pktin_update_event(event,
+ _odp_queue_to_qentry(src_queue));
+
+ odp_pr_dbg("Got event from EM: %x, em_queue: %x, odp_queue: %x, buf: %p, thr: %d\n",
+ em_event,
+ em_queue,
+ _odp_queue_from_em_queue(em_queue),
+ event,
+ odp_thread_id());
+
+ if (rx_num++ < num)
+ continue;
+ break;
+ }
+
+ if (wait == ODP_SCHED_WAIT)
+ continue;
+
+ if (wait == ODP_SCHED_NO_WAIT)
+ break;
+
+ if (first) {
+ wtime = odp_time_local_from_ns(wait);
+ start_time = odp_time_local();
+ first = 0;
+ continue;
+ }
+
+ time = odp_time_local();
+ diff = odp_time_diff(time, start_time);
+
+ if (odp_time_cmp(wtime, diff) < 0)
+ break;
+ }
+
+ return rx_num;
}