Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/infiniband/core/iwcm.c
37212 views
1
/*
2
* Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
3
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
4
* Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
5
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
6
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
7
* Copyright (c) 2005 Network Appliance, Inc. All rights reserved.
8
*
9
* This software is available to you under a choice of one of two
10
* licenses. You may choose to be licensed under the terms of the GNU
11
* General Public License (GPL) Version 2, available from the file
12
* COPYING in the main directory of this source tree, or the
13
* OpenIB.org BSD license below:
14
*
15
* Redistribution and use in source and binary forms, with or
16
* without modification, are permitted provided that the following
17
* conditions are met:
18
*
19
* - Redistributions of source code must retain the above
20
* copyright notice, this list of conditions and the following
21
* disclaimer.
22
*
23
* - Redistributions in binary form must reproduce the above
24
* copyright notice, this list of conditions and the following
25
* disclaimer in the documentation and/or other materials
26
* provided with the distribution.
27
*
28
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
32
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
33
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
* SOFTWARE.
36
*
37
*/
38
#include <linux/dma-mapping.h>
39
#include <linux/err.h>
40
#include <linux/idr.h>
41
#include <linux/interrupt.h>
42
#include <linux/rbtree.h>
43
#include <linux/sched.h>
44
#include <linux/spinlock.h>
45
#include <linux/workqueue.h>
46
#include <linux/completion.h>
47
#include <linux/slab.h>
48
49
#include <rdma/iw_cm.h>
50
#include <rdma/ib_addr.h>
51
52
#include "iwcm.h"
53
54
MODULE_AUTHOR("Tom Tucker");
55
MODULE_DESCRIPTION("iWARP CM");
56
MODULE_LICENSE("Dual BSD/GPL");
57
58
static struct workqueue_struct *iwcm_wq;
59
struct iwcm_work {
60
struct work_struct work;
61
struct iwcm_id_private *cm_id;
62
struct list_head list;
63
struct iw_cm_event event;
64
struct list_head free_list;
65
};
66
67
/*
68
* The following services provide a mechanism for pre-allocating iwcm_work
69
* elements. The design pre-allocates them based on the cm_id type:
70
* LISTENING IDS: Get enough elements preallocated to handle the
71
* listen backlog.
72
* ACTIVE IDS: 4: CONNECT_REPLY, ESTABLISHED, DISCONNECT, CLOSE
73
* PASSIVE IDS: 3: ESTABLISHED, DISCONNECT, CLOSE
74
*
75
* Allocating them in connect and listen avoids having to deal
76
* with allocation failures on the event upcall from the provider (which
77
* is called in the interrupt context).
78
*
79
* One exception is when creating the cm_id for incoming connection requests.
80
* There are two cases:
81
* 1) in the event upcall, cm_event_handler(), for a listening cm_id. If
82
* the backlog is exceeded, then no more connection request events will
83
* be processed. cm_event_handler() returns -ENOMEM in this case. Its up
84
* to the provider to reject the connection request.
85
* 2) in the connection request workqueue handler, cm_conn_req_handler().
86
* If work elements cannot be allocated for the new connect request cm_id,
87
* then IWCM will call the provider reject method. This is ok since
88
* cm_conn_req_handler() runs in the workqueue thread context.
89
*/
90
91
static struct iwcm_work *get_work(struct iwcm_id_private *cm_id_priv)
92
{
93
struct iwcm_work *work;
94
95
if (list_empty(&cm_id_priv->work_free_list))
96
return NULL;
97
work = list_entry(cm_id_priv->work_free_list.next, struct iwcm_work,
98
free_list);
99
list_del_init(&work->free_list);
100
return work;
101
}
102
103
static void put_work(struct iwcm_work *work)
104
{
105
list_add(&work->free_list, &work->cm_id->work_free_list);
106
}
107
108
static void dealloc_work_entries(struct iwcm_id_private *cm_id_priv)
109
{
110
struct list_head *e, *tmp;
111
112
list_for_each_safe(e, tmp, &cm_id_priv->work_free_list)
113
kfree(list_entry(e, struct iwcm_work, free_list));
114
}
115
116
static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count)
117
{
118
struct iwcm_work *work;
119
120
BUG_ON(!list_empty(&cm_id_priv->work_free_list));
121
while (count--) {
122
work = kmalloc(sizeof(struct iwcm_work), GFP_KERNEL);
123
if (!work) {
124
dealloc_work_entries(cm_id_priv);
125
return -ENOMEM;
126
}
127
work->cm_id = cm_id_priv;
128
INIT_LIST_HEAD(&work->list);
129
put_work(work);
130
}
131
return 0;
132
}
133
134
/*
135
* Save private data from incoming connection requests to
136
* iw_cm_event, so the low level driver doesn't have to. Adjust
137
* the event ptr to point to the local copy.
138
*/
139
static int copy_private_data(struct iw_cm_event *event)
140
{
141
void *p;
142
143
p = kmemdup(event->private_data, event->private_data_len, GFP_ATOMIC);
144
if (!p)
145
return -ENOMEM;
146
event->private_data = p;
147
return 0;
148
}
149
150
static void free_cm_id(struct iwcm_id_private *cm_id_priv)
151
{
152
dealloc_work_entries(cm_id_priv);
153
kfree(cm_id_priv);
154
}
155
156
/*
157
* Release a reference on cm_id. If the last reference is being
158
* released, enable the waiting thread (in iw_destroy_cm_id) to
159
* get woken up, and return 1 if a thread is already waiting.
160
*/
161
static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
162
{
163
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
164
if (atomic_dec_and_test(&cm_id_priv->refcount)) {
165
BUG_ON(!list_empty(&cm_id_priv->work_list));
166
complete(&cm_id_priv->destroy_comp);
167
return 1;
168
}
169
170
return 0;
171
}
172
173
static void add_ref(struct iw_cm_id *cm_id)
174
{
175
struct iwcm_id_private *cm_id_priv;
176
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
177
atomic_inc(&cm_id_priv->refcount);
178
}
179
180
static void rem_ref(struct iw_cm_id *cm_id)
181
{
182
struct iwcm_id_private *cm_id_priv;
183
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
184
if (iwcm_deref_id(cm_id_priv) &&
185
test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
186
BUG_ON(!list_empty(&cm_id_priv->work_list));
187
free_cm_id(cm_id_priv);
188
}
189
}
190
191
static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
192
193
struct iw_cm_id *iw_create_cm_id(struct ib_device *device,
194
iw_cm_handler cm_handler,
195
void *context)
196
{
197
struct iwcm_id_private *cm_id_priv;
198
199
cm_id_priv = kzalloc(sizeof(*cm_id_priv), GFP_KERNEL);
200
if (!cm_id_priv)
201
return ERR_PTR(-ENOMEM);
202
203
cm_id_priv->state = IW_CM_STATE_IDLE;
204
cm_id_priv->id.device = device;
205
cm_id_priv->id.cm_handler = cm_handler;
206
cm_id_priv->id.context = context;
207
cm_id_priv->id.event_handler = cm_event_handler;
208
cm_id_priv->id.add_ref = add_ref;
209
cm_id_priv->id.rem_ref = rem_ref;
210
spin_lock_init(&cm_id_priv->lock);
211
atomic_set(&cm_id_priv->refcount, 1);
212
init_waitqueue_head(&cm_id_priv->connect_wait);
213
init_completion(&cm_id_priv->destroy_comp);
214
INIT_LIST_HEAD(&cm_id_priv->work_list);
215
INIT_LIST_HEAD(&cm_id_priv->work_free_list);
216
217
return &cm_id_priv->id;
218
}
219
EXPORT_SYMBOL(iw_create_cm_id);
220
221
222
static int iwcm_modify_qp_err(struct ib_qp *qp)
223
{
224
struct ib_qp_attr qp_attr;
225
226
if (!qp)
227
return -EINVAL;
228
229
qp_attr.qp_state = IB_QPS_ERR;
230
return ib_modify_qp(qp, &qp_attr, IB_QP_STATE);
231
}
232
233
/*
234
* This is really the RDMAC CLOSING state. It is most similar to the
235
* IB SQD QP state.
236
*/
237
static int iwcm_modify_qp_sqd(struct ib_qp *qp)
238
{
239
struct ib_qp_attr qp_attr;
240
241
BUG_ON(qp == NULL);
242
qp_attr.qp_state = IB_QPS_SQD;
243
return ib_modify_qp(qp, &qp_attr, IB_QP_STATE);
244
}
245
246
/*
247
* CM_ID <-- CLOSING
248
*
249
* Block if a passive or active connection is currently being processed. Then
250
* process the event as follows:
251
* - If we are ESTABLISHED, move to CLOSING and modify the QP state
252
* based on the abrupt flag
253
* - If the connection is already in the CLOSING or IDLE state, the peer is
254
* disconnecting concurrently with us and we've already seen the
255
* DISCONNECT event -- ignore the request and return 0
256
* - Disconnect on a listening endpoint returns -EINVAL
257
*/
258
int iw_cm_disconnect(struct iw_cm_id *cm_id, int abrupt)
259
{
260
struct iwcm_id_private *cm_id_priv;
261
unsigned long flags;
262
int ret = 0;
263
struct ib_qp *qp = NULL;
264
265
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
266
/* Wait if we're currently in a connect or accept downcall */
267
wait_event(cm_id_priv->connect_wait,
268
!test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags));
269
270
spin_lock_irqsave(&cm_id_priv->lock, flags);
271
switch (cm_id_priv->state) {
272
case IW_CM_STATE_ESTABLISHED:
273
cm_id_priv->state = IW_CM_STATE_CLOSING;
274
275
/* QP could be <nul> for user-mode client */
276
if (cm_id_priv->qp)
277
qp = cm_id_priv->qp;
278
else
279
ret = -EINVAL;
280
break;
281
case IW_CM_STATE_LISTEN:
282
ret = -EINVAL;
283
break;
284
case IW_CM_STATE_CLOSING:
285
/* remote peer closed first */
286
case IW_CM_STATE_IDLE:
287
/* accept or connect returned !0 */
288
break;
289
case IW_CM_STATE_CONN_RECV:
290
/*
291
* App called disconnect before/without calling accept after
292
* connect_request event delivered.
293
*/
294
break;
295
case IW_CM_STATE_CONN_SENT:
296
/* Can only get here if wait above fails */
297
default:
298
BUG();
299
}
300
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
301
302
if (qp) {
303
if (abrupt)
304
ret = iwcm_modify_qp_err(qp);
305
else
306
ret = iwcm_modify_qp_sqd(qp);
307
308
/*
309
* If both sides are disconnecting the QP could
310
* already be in ERR or SQD states
311
*/
312
ret = 0;
313
}
314
315
return ret;
316
}
317
EXPORT_SYMBOL(iw_cm_disconnect);
318
319
/*
320
* CM_ID <-- DESTROYING
321
*
322
* Clean up all resources associated with the connection and release
323
* the initial reference taken by iw_create_cm_id.
324
*/
325
static void destroy_cm_id(struct iw_cm_id *cm_id)
326
{
327
struct iwcm_id_private *cm_id_priv;
328
unsigned long flags;
329
int ret;
330
331
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
332
/*
333
* Wait if we're currently in a connect or accept downcall. A
334
* listening endpoint should never block here.
335
*/
336
wait_event(cm_id_priv->connect_wait,
337
!test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags));
338
339
spin_lock_irqsave(&cm_id_priv->lock, flags);
340
switch (cm_id_priv->state) {
341
case IW_CM_STATE_LISTEN:
342
cm_id_priv->state = IW_CM_STATE_DESTROYING;
343
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
344
/* destroy the listening endpoint */
345
ret = cm_id->device->iwcm->destroy_listen(cm_id);
346
spin_lock_irqsave(&cm_id_priv->lock, flags);
347
break;
348
case IW_CM_STATE_ESTABLISHED:
349
cm_id_priv->state = IW_CM_STATE_DESTROYING;
350
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
351
/* Abrupt close of the connection */
352
(void)iwcm_modify_qp_err(cm_id_priv->qp);
353
spin_lock_irqsave(&cm_id_priv->lock, flags);
354
break;
355
case IW_CM_STATE_IDLE:
356
case IW_CM_STATE_CLOSING:
357
cm_id_priv->state = IW_CM_STATE_DESTROYING;
358
break;
359
case IW_CM_STATE_CONN_RECV:
360
/*
361
* App called destroy before/without calling accept after
362
* receiving connection request event notification or
363
* returned non zero from the event callback function.
364
* In either case, must tell the provider to reject.
365
*/
366
cm_id_priv->state = IW_CM_STATE_DESTROYING;
367
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
368
cm_id->device->iwcm->reject(cm_id, NULL, 0);
369
spin_lock_irqsave(&cm_id_priv->lock, flags);
370
break;
371
case IW_CM_STATE_CONN_SENT:
372
case IW_CM_STATE_DESTROYING:
373
default:
374
BUG();
375
break;
376
}
377
if (cm_id_priv->qp) {
378
cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp);
379
cm_id_priv->qp = NULL;
380
}
381
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
382
383
(void)iwcm_deref_id(cm_id_priv);
384
}
385
386
/*
387
* This function is only called by the application thread and cannot
388
* be called by the event thread. The function will wait for all
389
* references to be released on the cm_id and then kfree the cm_id
390
* object.
391
*/
392
void iw_destroy_cm_id(struct iw_cm_id *cm_id)
393
{
394
struct iwcm_id_private *cm_id_priv;
395
396
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
397
BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags));
398
399
destroy_cm_id(cm_id);
400
401
wait_for_completion(&cm_id_priv->destroy_comp);
402
403
free_cm_id(cm_id_priv);
404
}
405
EXPORT_SYMBOL(iw_destroy_cm_id);
406
407
/*
408
* CM_ID <-- LISTEN
409
*
410
* Start listening for connect requests. Generates one CONNECT_REQUEST
411
* event for each inbound connect request.
412
*/
413
int iw_cm_listen(struct iw_cm_id *cm_id, int backlog)
414
{
415
struct iwcm_id_private *cm_id_priv;
416
unsigned long flags;
417
int ret;
418
419
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
420
421
ret = alloc_work_entries(cm_id_priv, backlog);
422
if (ret)
423
return ret;
424
425
spin_lock_irqsave(&cm_id_priv->lock, flags);
426
switch (cm_id_priv->state) {
427
case IW_CM_STATE_IDLE:
428
cm_id_priv->state = IW_CM_STATE_LISTEN;
429
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
430
ret = cm_id->device->iwcm->create_listen(cm_id, backlog);
431
if (ret)
432
cm_id_priv->state = IW_CM_STATE_IDLE;
433
spin_lock_irqsave(&cm_id_priv->lock, flags);
434
break;
435
default:
436
ret = -EINVAL;
437
}
438
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
439
440
return ret;
441
}
442
EXPORT_SYMBOL(iw_cm_listen);
443
444
/*
445
* CM_ID <-- IDLE
446
*
447
* Rejects an inbound connection request. No events are generated.
448
*/
449
int iw_cm_reject(struct iw_cm_id *cm_id,
450
const void *private_data,
451
u8 private_data_len)
452
{
453
struct iwcm_id_private *cm_id_priv;
454
unsigned long flags;
455
int ret;
456
457
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
458
set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
459
460
spin_lock_irqsave(&cm_id_priv->lock, flags);
461
if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) {
462
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
463
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
464
wake_up_all(&cm_id_priv->connect_wait);
465
return -EINVAL;
466
}
467
cm_id_priv->state = IW_CM_STATE_IDLE;
468
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
469
470
ret = cm_id->device->iwcm->reject(cm_id, private_data,
471
private_data_len);
472
473
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
474
wake_up_all(&cm_id_priv->connect_wait);
475
476
return ret;
477
}
478
EXPORT_SYMBOL(iw_cm_reject);
479
480
/*
481
* CM_ID <-- ESTABLISHED
482
*
483
* Accepts an inbound connection request and generates an ESTABLISHED
484
* event. Callers of iw_cm_disconnect and iw_destroy_cm_id will block
485
* until the ESTABLISHED event is received from the provider.
486
*/
487
int iw_cm_accept(struct iw_cm_id *cm_id,
488
struct iw_cm_conn_param *iw_param)
489
{
490
struct iwcm_id_private *cm_id_priv;
491
struct ib_qp *qp;
492
unsigned long flags;
493
int ret;
494
495
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
496
set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
497
498
spin_lock_irqsave(&cm_id_priv->lock, flags);
499
if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) {
500
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
501
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
502
wake_up_all(&cm_id_priv->connect_wait);
503
return -EINVAL;
504
}
505
/* Get the ib_qp given the QPN */
506
qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn);
507
if (!qp) {
508
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
509
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
510
wake_up_all(&cm_id_priv->connect_wait);
511
return -EINVAL;
512
}
513
cm_id->device->iwcm->add_ref(qp);
514
cm_id_priv->qp = qp;
515
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
516
517
ret = cm_id->device->iwcm->accept(cm_id, iw_param);
518
if (ret) {
519
/* An error on accept precludes provider events */
520
BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV);
521
cm_id_priv->state = IW_CM_STATE_IDLE;
522
spin_lock_irqsave(&cm_id_priv->lock, flags);
523
if (cm_id_priv->qp) {
524
cm_id->device->iwcm->rem_ref(qp);
525
cm_id_priv->qp = NULL;
526
}
527
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
528
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
529
wake_up_all(&cm_id_priv->connect_wait);
530
}
531
532
return ret;
533
}
534
EXPORT_SYMBOL(iw_cm_accept);
535
536
/*
537
* Active Side: CM_ID <-- CONN_SENT
538
*
539
* If successful, results in the generation of a CONNECT_REPLY
540
* event. iw_cm_disconnect and iw_cm_destroy will block until the
541
* CONNECT_REPLY event is received from the provider.
542
*/
543
int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
544
{
545
struct iwcm_id_private *cm_id_priv;
546
int ret;
547
unsigned long flags;
548
struct ib_qp *qp;
549
550
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
551
552
ret = alloc_work_entries(cm_id_priv, 4);
553
if (ret)
554
return ret;
555
556
set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
557
spin_lock_irqsave(&cm_id_priv->lock, flags);
558
559
if (cm_id_priv->state != IW_CM_STATE_IDLE) {
560
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
561
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
562
wake_up_all(&cm_id_priv->connect_wait);
563
return -EINVAL;
564
}
565
566
/* Get the ib_qp given the QPN */
567
qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn);
568
if (!qp) {
569
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
570
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
571
wake_up_all(&cm_id_priv->connect_wait);
572
return -EINVAL;
573
}
574
cm_id->device->iwcm->add_ref(qp);
575
cm_id_priv->qp = qp;
576
cm_id_priv->state = IW_CM_STATE_CONN_SENT;
577
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
578
579
ret = cm_id->device->iwcm->connect(cm_id, iw_param);
580
if (ret) {
581
spin_lock_irqsave(&cm_id_priv->lock, flags);
582
if (cm_id_priv->qp) {
583
cm_id->device->iwcm->rem_ref(qp);
584
cm_id_priv->qp = NULL;
585
}
586
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
587
BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
588
cm_id_priv->state = IW_CM_STATE_IDLE;
589
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
590
wake_up_all(&cm_id_priv->connect_wait);
591
}
592
593
return ret;
594
}
595
EXPORT_SYMBOL(iw_cm_connect);
596
597
/*
598
* Passive Side: new CM_ID <-- CONN_RECV
599
*
600
* Handles an inbound connect request. The function creates a new
601
* iw_cm_id to represent the new connection and inherits the client
602
* callback function and other attributes from the listening parent.
603
*
604
* The work item contains a pointer to the listen_cm_id and the event. The
605
* listen_cm_id contains the client cm_handler, context and
606
* device. These are copied when the device is cloned. The event
607
* contains the new four tuple.
608
*
609
* An error on the child should not affect the parent, so this
610
* function does not return a value.
611
*/
612
static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
613
struct iw_cm_event *iw_event)
614
{
615
unsigned long flags;
616
struct iw_cm_id *cm_id;
617
struct iwcm_id_private *cm_id_priv;
618
int ret;
619
620
/*
621
* The provider should never generate a connection request
622
* event with a bad status.
623
*/
624
BUG_ON(iw_event->status);
625
626
/*
627
* We could be destroying the listening id. If so, ignore this
628
* upcall.
629
*/
630
spin_lock_irqsave(&listen_id_priv->lock, flags);
631
if (listen_id_priv->state != IW_CM_STATE_LISTEN) {
632
spin_unlock_irqrestore(&listen_id_priv->lock, flags);
633
goto out;
634
}
635
spin_unlock_irqrestore(&listen_id_priv->lock, flags);
636
637
cm_id = iw_create_cm_id(listen_id_priv->id.device,
638
listen_id_priv->id.cm_handler,
639
listen_id_priv->id.context);
640
/* If the cm_id could not be created, ignore the request */
641
if (IS_ERR(cm_id))
642
goto out;
643
644
cm_id->provider_data = iw_event->provider_data;
645
cm_id->local_addr = iw_event->local_addr;
646
cm_id->remote_addr = iw_event->remote_addr;
647
648
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
649
cm_id_priv->state = IW_CM_STATE_CONN_RECV;
650
651
ret = alloc_work_entries(cm_id_priv, 3);
652
if (ret) {
653
iw_cm_reject(cm_id, NULL, 0);
654
iw_destroy_cm_id(cm_id);
655
goto out;
656
}
657
658
/* Call the client CM handler */
659
ret = cm_id->cm_handler(cm_id, iw_event);
660
if (ret) {
661
iw_cm_reject(cm_id, NULL, 0);
662
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
663
destroy_cm_id(cm_id);
664
if (atomic_read(&cm_id_priv->refcount)==0)
665
free_cm_id(cm_id_priv);
666
}
667
668
out:
669
if (iw_event->private_data_len)
670
kfree(iw_event->private_data);
671
}
672
673
/*
674
* Passive Side: CM_ID <-- ESTABLISHED
675
*
676
* The provider generated an ESTABLISHED event which means that
677
* the MPA negotion has completed successfully and we are now in MPA
678
* FPDU mode.
679
*
680
* This event can only be received in the CONN_RECV state. If the
681
* remote peer closed, the ESTABLISHED event would be received followed
682
* by the CLOSE event. If the app closes, it will block until we wake
683
* it up after processing this event.
684
*/
685
static int cm_conn_est_handler(struct iwcm_id_private *cm_id_priv,
686
struct iw_cm_event *iw_event)
687
{
688
unsigned long flags;
689
int ret;
690
691
spin_lock_irqsave(&cm_id_priv->lock, flags);
692
693
/*
694
* We clear the CONNECT_WAIT bit here to allow the callback
695
* function to call iw_cm_disconnect. Calling iw_destroy_cm_id
696
* from a callback handler is not allowed.
697
*/
698
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
699
BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV);
700
cm_id_priv->state = IW_CM_STATE_ESTABLISHED;
701
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
702
ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
703
wake_up_all(&cm_id_priv->connect_wait);
704
705
return ret;
706
}
707
708
/*
709
* Active Side: CM_ID <-- ESTABLISHED
710
*
711
* The app has called connect and is waiting for the established event to
712
* post it's requests to the server. This event will wake up anyone
713
* blocked in iw_cm_disconnect or iw_destroy_id.
714
*/
715
static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv,
716
struct iw_cm_event *iw_event)
717
{
718
unsigned long flags;
719
int ret;
720
721
spin_lock_irqsave(&cm_id_priv->lock, flags);
722
/*
723
* Clear the connect wait bit so a callback function calling
724
* iw_cm_disconnect will not wait and deadlock this thread
725
*/
726
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
727
BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
728
if (iw_event->status == 0) {
729
cm_id_priv->id.local_addr = iw_event->local_addr;
730
cm_id_priv->id.remote_addr = iw_event->remote_addr;
731
cm_id_priv->state = IW_CM_STATE_ESTABLISHED;
732
} else {
733
/* REJECTED or RESET */
734
cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp);
735
cm_id_priv->qp = NULL;
736
cm_id_priv->state = IW_CM_STATE_IDLE;
737
}
738
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
739
ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
740
741
if (iw_event->private_data_len)
742
kfree(iw_event->private_data);
743
744
/* Wake up waiters on connect complete */
745
wake_up_all(&cm_id_priv->connect_wait);
746
747
return ret;
748
}
749
750
/*
751
* CM_ID <-- CLOSING
752
*
753
* If in the ESTABLISHED state, move to CLOSING.
754
*/
755
static void cm_disconnect_handler(struct iwcm_id_private *cm_id_priv,
756
struct iw_cm_event *iw_event)
757
{
758
unsigned long flags;
759
760
spin_lock_irqsave(&cm_id_priv->lock, flags);
761
if (cm_id_priv->state == IW_CM_STATE_ESTABLISHED)
762
cm_id_priv->state = IW_CM_STATE_CLOSING;
763
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
764
}
765
766
/*
767
* CM_ID <-- IDLE
768
*
769
* If in the ESTBLISHED or CLOSING states, the QP will have have been
770
* moved by the provider to the ERR state. Disassociate the CM_ID from
771
* the QP, move to IDLE, and remove the 'connected' reference.
772
*
773
* If in some other state, the cm_id was destroyed asynchronously.
774
* This is the last reference that will result in waking up
775
* the app thread blocked in iw_destroy_cm_id.
776
*/
777
static int cm_close_handler(struct iwcm_id_private *cm_id_priv,
778
struct iw_cm_event *iw_event)
779
{
780
unsigned long flags;
781
int ret = 0;
782
spin_lock_irqsave(&cm_id_priv->lock, flags);
783
784
if (cm_id_priv->qp) {
785
cm_id_priv->id.device->iwcm->rem_ref(cm_id_priv->qp);
786
cm_id_priv->qp = NULL;
787
}
788
switch (cm_id_priv->state) {
789
case IW_CM_STATE_ESTABLISHED:
790
case IW_CM_STATE_CLOSING:
791
cm_id_priv->state = IW_CM_STATE_IDLE;
792
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
793
ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
794
spin_lock_irqsave(&cm_id_priv->lock, flags);
795
break;
796
case IW_CM_STATE_DESTROYING:
797
break;
798
default:
799
BUG();
800
}
801
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
802
803
return ret;
804
}
805
806
static int process_event(struct iwcm_id_private *cm_id_priv,
807
struct iw_cm_event *iw_event)
808
{
809
int ret = 0;
810
811
switch (iw_event->event) {
812
case IW_CM_EVENT_CONNECT_REQUEST:
813
cm_conn_req_handler(cm_id_priv, iw_event);
814
break;
815
case IW_CM_EVENT_CONNECT_REPLY:
816
ret = cm_conn_rep_handler(cm_id_priv, iw_event);
817
break;
818
case IW_CM_EVENT_ESTABLISHED:
819
ret = cm_conn_est_handler(cm_id_priv, iw_event);
820
break;
821
case IW_CM_EVENT_DISCONNECT:
822
cm_disconnect_handler(cm_id_priv, iw_event);
823
break;
824
case IW_CM_EVENT_CLOSE:
825
ret = cm_close_handler(cm_id_priv, iw_event);
826
break;
827
default:
828
BUG();
829
}
830
831
return ret;
832
}
833
834
/*
835
* Process events on the work_list for the cm_id. If the callback
836
* function requests that the cm_id be deleted, a flag is set in the
837
* cm_id flags to indicate that when the last reference is
838
* removed, the cm_id is to be destroyed. This is necessary to
839
* distinguish between an object that will be destroyed by the app
840
* thread asleep on the destroy_comp list vs. an object destroyed
841
* here synchronously when the last reference is removed.
842
*/
843
static void cm_work_handler(struct work_struct *_work)
844
{
845
struct iwcm_work *work = container_of(_work, struct iwcm_work, work);
846
struct iw_cm_event levent;
847
struct iwcm_id_private *cm_id_priv = work->cm_id;
848
unsigned long flags;
849
int empty;
850
int ret = 0;
851
int destroy_id;
852
853
spin_lock_irqsave(&cm_id_priv->lock, flags);
854
empty = list_empty(&cm_id_priv->work_list);
855
while (!empty) {
856
work = list_entry(cm_id_priv->work_list.next,
857
struct iwcm_work, list);
858
list_del_init(&work->list);
859
empty = list_empty(&cm_id_priv->work_list);
860
levent = work->event;
861
put_work(work);
862
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
863
864
ret = process_event(cm_id_priv, &levent);
865
if (ret) {
866
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
867
destroy_cm_id(&cm_id_priv->id);
868
}
869
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
870
destroy_id = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
871
if (iwcm_deref_id(cm_id_priv)) {
872
if (destroy_id) {
873
BUG_ON(!list_empty(&cm_id_priv->work_list));
874
free_cm_id(cm_id_priv);
875
}
876
return;
877
}
878
spin_lock_irqsave(&cm_id_priv->lock, flags);
879
}
880
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
881
}
882
883
/*
884
* This function is called on interrupt context. Schedule events on
885
* the iwcm_wq thread to allow callback functions to downcall into
886
* the CM and/or block. Events are queued to a per-CM_ID
887
* work_list. If this is the first event on the work_list, the work
888
* element is also queued on the iwcm_wq thread.
889
*
890
* Each event holds a reference on the cm_id. Until the last posted
891
* event has been delivered and processed, the cm_id cannot be
892
* deleted.
893
*
894
* Returns:
895
* 0 - the event was handled.
896
* -ENOMEM - the event was not handled due to lack of resources.
897
*/
898
static int cm_event_handler(struct iw_cm_id *cm_id,
899
struct iw_cm_event *iw_event)
900
{
901
struct iwcm_work *work;
902
struct iwcm_id_private *cm_id_priv;
903
unsigned long flags;
904
int ret = 0;
905
906
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
907
908
spin_lock_irqsave(&cm_id_priv->lock, flags);
909
work = get_work(cm_id_priv);
910
if (!work) {
911
ret = -ENOMEM;
912
goto out;
913
}
914
915
INIT_WORK(&work->work, cm_work_handler);
916
work->cm_id = cm_id_priv;
917
work->event = *iw_event;
918
919
if ((work->event.event == IW_CM_EVENT_CONNECT_REQUEST ||
920
work->event.event == IW_CM_EVENT_CONNECT_REPLY) &&
921
work->event.private_data_len) {
922
ret = copy_private_data(&work->event);
923
if (ret) {
924
put_work(work);
925
goto out;
926
}
927
}
928
929
atomic_inc(&cm_id_priv->refcount);
930
if (list_empty(&cm_id_priv->work_list)) {
931
list_add_tail(&work->list, &cm_id_priv->work_list);
932
queue_work(iwcm_wq, &work->work);
933
} else
934
list_add_tail(&work->list, &cm_id_priv->work_list);
935
out:
936
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
937
return ret;
938
}
939
940
static int iwcm_init_qp_init_attr(struct iwcm_id_private *cm_id_priv,
941
struct ib_qp_attr *qp_attr,
942
int *qp_attr_mask)
943
{
944
unsigned long flags;
945
int ret;
946
947
spin_lock_irqsave(&cm_id_priv->lock, flags);
948
switch (cm_id_priv->state) {
949
case IW_CM_STATE_IDLE:
950
case IW_CM_STATE_CONN_SENT:
951
case IW_CM_STATE_CONN_RECV:
952
case IW_CM_STATE_ESTABLISHED:
953
*qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS;
954
qp_attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE|
955
IB_ACCESS_REMOTE_READ;
956
ret = 0;
957
break;
958
default:
959
ret = -EINVAL;
960
break;
961
}
962
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
963
return ret;
964
}
965
966
static int iwcm_init_qp_rts_attr(struct iwcm_id_private *cm_id_priv,
967
struct ib_qp_attr *qp_attr,
968
int *qp_attr_mask)
969
{
970
unsigned long flags;
971
int ret;
972
973
spin_lock_irqsave(&cm_id_priv->lock, flags);
974
switch (cm_id_priv->state) {
975
case IW_CM_STATE_IDLE:
976
case IW_CM_STATE_CONN_SENT:
977
case IW_CM_STATE_CONN_RECV:
978
case IW_CM_STATE_ESTABLISHED:
979
*qp_attr_mask = 0;
980
ret = 0;
981
break;
982
default:
983
ret = -EINVAL;
984
break;
985
}
986
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
987
return ret;
988
}
989
990
int iw_cm_init_qp_attr(struct iw_cm_id *cm_id,
991
struct ib_qp_attr *qp_attr,
992
int *qp_attr_mask)
993
{
994
struct iwcm_id_private *cm_id_priv;
995
int ret;
996
997
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
998
switch (qp_attr->qp_state) {
999
case IB_QPS_INIT:
1000
case IB_QPS_RTR:
1001
ret = iwcm_init_qp_init_attr(cm_id_priv,
1002
qp_attr, qp_attr_mask);
1003
break;
1004
case IB_QPS_RTS:
1005
ret = iwcm_init_qp_rts_attr(cm_id_priv,
1006
qp_attr, qp_attr_mask);
1007
break;
1008
default:
1009
ret = -EINVAL;
1010
break;
1011
}
1012
return ret;
1013
}
1014
EXPORT_SYMBOL(iw_cm_init_qp_attr);
1015
1016
static int __init iw_cm_init(void)
1017
{
1018
iwcm_wq = create_singlethread_workqueue("iw_cm_wq");
1019
if (!iwcm_wq)
1020
return -ENOMEM;
1021
1022
return 0;
1023
}
1024
1025
static void __exit iw_cm_cleanup(void)
1026
{
1027
destroy_workqueue(iwcm_wq);
1028
}
1029
1030
module_init(iw_cm_init);
1031
module_exit(iw_cm_cleanup);
1032
1033