hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * Copyright(c) 2018 Intel Corporation.
 *
 */
#include "iowait.h"
#include "trace_iowait.h"
 
/* 1 priority == 16 starve_cnt */
#define IOWAIT_PRIORITY_STARVE_SHIFT 4
 
void iowait_set_flag(struct iowait *wait, u32 flag)
{
   trace_hfi1_iowait_set(wait, flag);
   set_bit(flag, &wait->flags);
}
 
bool iowait_flag_set(struct iowait *wait, u32 flag)
{
   return test_bit(flag, &wait->flags);
}
 
inline void iowait_clear_flag(struct iowait *wait, u32 flag)
{
   trace_hfi1_iowait_clear(wait, flag);
   clear_bit(flag, &wait->flags);
}
 
/**
 * iowait_init() - initialize wait structure
 * @wait: wait struct to initialize
 * @tx_limit: limit for overflow queuing
 * @func: restart function for workqueue
 * @sleep: sleep function for no space
 * @resume: wakeup function for no space
 *
 * This function initializes the iowait
 * structure embedded in the QP or PQ.
 *
 */
void iowait_init(struct iowait *wait, u32 tx_limit,
        void (*func)(struct work_struct *work),
        void (*tidfunc)(struct work_struct *work),
        int (*sleep)(struct sdma_engine *sde,
                 struct iowait_work *wait,
                 struct sdma_txreq *tx,
                 uint seq,
                 bool pkts_sent),
        void (*wakeup)(struct iowait *wait, int reason),
        void (*sdma_drained)(struct iowait *wait),
        void (*init_priority)(struct iowait *wait))
{
   int i;
 
   wait->count = 0;
   INIT_LIST_HEAD(&wait->list);
   init_waitqueue_head(&wait->wait_dma);
   init_waitqueue_head(&wait->wait_pio);
   atomic_set(&wait->sdma_busy, 0);
   atomic_set(&wait->pio_busy, 0);
   wait->tx_limit = tx_limit;
   wait->sleep = sleep;
   wait->wakeup = wakeup;
   wait->sdma_drained = sdma_drained;
   wait->init_priority = init_priority;
   wait->flags = 0;
   for (i = 0; i < IOWAIT_SES; i++) {
       wait->wait[i].iow = wait;
       INIT_LIST_HEAD(&wait->wait[i].tx_head);
       if (i == IOWAIT_IB_SE)
           INIT_WORK(&wait->wait[i].iowork, func);
       else
           INIT_WORK(&wait->wait[i].iowork, tidfunc);
   }
}
 
/**
 * iowait_cancel_work - cancel all work in iowait
 * @w: the iowait struct
 */
void iowait_cancel_work(struct iowait *w)
{
   cancel_work_sync(&iowait_get_ib_work(w)->iowork);
   /* Make sure that the iowork for TID RDMA is used */
   if (iowait_get_tid_work(w)->iowork.func)
       cancel_work_sync(&iowait_get_tid_work(w)->iowork);
}
 
/**
 * iowait_set_work_flag - set work flag based on leg
 * @w - the iowait work struct
 */
int iowait_set_work_flag(struct iowait_work *w)
{
   if (w == &w->iow->wait[IOWAIT_IB_SE]) {
       iowait_set_flag(w->iow, IOWAIT_PENDING_IB);
       return IOWAIT_IB_SE;
   }
   iowait_set_flag(w->iow, IOWAIT_PENDING_TID);
   return IOWAIT_TID_SE;
}
 
/**
 * iowait_priority_update_top - update the top priority entry
 * @w: the iowait struct
 * @top: a pointer to the top priority entry
 * @idx: the index of the current iowait in an array
 * @top_idx: the array index for the iowait entry that has the top priority
 *
 * This function is called to compare the priority of a given
 * iowait with the given top priority entry. The top index will
 * be returned.
 */
uint iowait_priority_update_top(struct iowait *w,
               struct iowait *top,
               uint idx, uint top_idx)
{
   u8 cnt, tcnt;
 
   /* Convert priority into starve_cnt and compare the total.*/
   cnt = (w->priority << IOWAIT_PRIORITY_STARVE_SHIFT) + w->starved_cnt;
   tcnt = (top->priority << IOWAIT_PRIORITY_STARVE_SHIFT) +
       top->starved_cnt;
   if (cnt > tcnt)
       return idx;
   else
       return top_idx;
}