4 * Data structure and helper functions for tracking pending FSF
7 * Copyright IBM Corp. 2009
10 #ifndef ZFCP_REQLIST_H
11 #define ZFCP_REQLIST_H
13 /* number of hash buckets */
14 #define ZFCP_REQ_LIST_BUCKETS 128
17 * struct zfcp_reqlist - Container for request list (reqlist)
18 * @lock: Spinlock for protecting the hash list
19 * @list: Array of hashbuckets, each is a list of requests in this bucket
23 struct list_head buckets
[ZFCP_REQ_LIST_BUCKETS
];
26 static inline int zfcp_reqlist_hash(unsigned long req_id
)
28 return req_id
% ZFCP_REQ_LIST_BUCKETS
;
32 * zfcp_reqlist_alloc - Allocate and initialize reqlist
34 * Returns pointer to allocated reqlist on success, or NULL on
37 static inline struct zfcp_reqlist
*zfcp_reqlist_alloc(void)
40 struct zfcp_reqlist
*rl
;
42 rl
= kzalloc(sizeof(struct zfcp_reqlist
), GFP_KERNEL
);
46 spin_lock_init(&rl
->lock
);
48 for (i
= 0; i
< ZFCP_REQ_LIST_BUCKETS
; i
++)
49 INIT_LIST_HEAD(&rl
->buckets
[i
]);
55 * zfcp_reqlist_isempty - Check whether the request list empty
56 * @rl: pointer to reqlist
58 * Returns: 1 if list is empty, 0 if not
60 static inline int zfcp_reqlist_isempty(struct zfcp_reqlist
*rl
)
64 for (i
= 0; i
< ZFCP_REQ_LIST_BUCKETS
; i
++)
65 if (!list_empty(&rl
->buckets
[i
]))
71 * zfcp_reqlist_free - Free allocated memory for reqlist
72 * @rl: The reqlist where to free memory
74 static inline void zfcp_reqlist_free(struct zfcp_reqlist
*rl
)
77 BUG_ON(!zfcp_reqlist_isempty(rl
));
82 static inline struct zfcp_fsf_req
*
83 _zfcp_reqlist_find(struct zfcp_reqlist
*rl
, unsigned long req_id
)
85 struct zfcp_fsf_req
*req
;
88 i
= zfcp_reqlist_hash(req_id
);
89 list_for_each_entry(req
, &rl
->buckets
[i
], list
)
90 if (req
->req_id
== req_id
)
96 * zfcp_reqlist_find - Lookup FSF request by its request id
97 * @rl: The reqlist where to lookup the FSF request
98 * @req_id: The request id to look for
100 * Returns a pointer to the FSF request with the specified request id
101 * or NULL if there is no known FSF request with this id.
103 static inline struct zfcp_fsf_req
*
104 zfcp_reqlist_find(struct zfcp_reqlist
*rl
, unsigned long req_id
)
107 struct zfcp_fsf_req
*req
;
109 spin_lock_irqsave(&rl
->lock
, flags
);
110 req
= _zfcp_reqlist_find(rl
, req_id
);
111 spin_unlock_irqrestore(&rl
->lock
, flags
);
117 * zfcp_reqlist_find_rm - Lookup request by id and remove it from reqlist
118 * @rl: reqlist where to search and remove entry
119 * @req_id: The request id of the request to look for
121 * This functions tries to find the FSF request with the specified
122 * id and then removes it from the reqlist. The reqlist lock is held
123 * during both steps of the operation.
125 * Returns: Pointer to the FSF request if the request has been found,
126 * NULL if it has not been found.
128 static inline struct zfcp_fsf_req
*
129 zfcp_reqlist_find_rm(struct zfcp_reqlist
*rl
, unsigned long req_id
)
132 struct zfcp_fsf_req
*req
;
134 spin_lock_irqsave(&rl
->lock
, flags
);
135 req
= _zfcp_reqlist_find(rl
, req_id
);
137 list_del(&req
->list
);
138 spin_unlock_irqrestore(&rl
->lock
, flags
);
144 * zfcp_reqlist_add - Add entry to reqlist
145 * @rl: reqlist where to add the entry
146 * @req: The entry to add
148 * The request id always increases. As an optimization new requests
149 * are added here with list_add_tail at the end of the bucket lists
150 * while old requests are looked up starting at the beginning of the
153 static inline void zfcp_reqlist_add(struct zfcp_reqlist
*rl
,
154 struct zfcp_fsf_req
*req
)
159 i
= zfcp_reqlist_hash(req
->req_id
);
161 spin_lock_irqsave(&rl
->lock
, flags
);
162 list_add_tail(&req
->list
, &rl
->buckets
[i
]);
163 spin_unlock_irqrestore(&rl
->lock
, flags
);
167 * zfcp_reqlist_move - Move all entries from reqlist to simple list
168 * @rl: The zfcp_reqlist where to remove all entries
169 * @list: The list where to move all entries
171 static inline void zfcp_reqlist_move(struct zfcp_reqlist
*rl
,
172 struct list_head
*list
)
177 spin_lock_irqsave(&rl
->lock
, flags
);
178 for (i
= 0; i
< ZFCP_REQ_LIST_BUCKETS
; i
++)
179 list_splice_init(&rl
->buckets
[i
], list
);
180 spin_unlock_irqrestore(&rl
->lock
, flags
);
183 #endif /* ZFCP_REQLIST_H */