Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 111485
b: refs/heads/master
c: 09856c1
h: refs/heads/master
i:
  111483: 00d2bf6
v: v3
  • Loading branch information
Gerrit Renker committed Sep 4, 2008
1 parent b7c46c9 commit 43f62aa
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5d3dac267a7fd0811ec777e76a81f97f5cdcb395
refs/heads/master: 09856c108956c99088ead9267ccbd1dab77f7043
39 changes: 29 additions & 10 deletions trunk/net/dccp/ccid.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,22 +196,41 @@ int ccid_unregister(struct ccid_operations *ccid_ops)

EXPORT_SYMBOL_GPL(ccid_unregister);

/**
* ccid_request_module - Pre-load CCID module for later use
* This should be called only from process context (e.g. during connection
* setup) and is necessary for later calls to ccid_new (typically in software
* interrupt), so that it has the modules available when they are needed.
*/
static int ccid_request_module(u8 id)
{
if (!in_atomic()) {
ccids_read_lock();
if (ccids[id] == NULL) {
ccids_read_unlock();
return request_module("net-dccp-ccid-%d", id);
}
ccids_read_unlock();
}
return 0;
}

int ccid_request_modules(u8 const *ccid_array, u8 array_len)
{
#ifdef CONFIG_KMOD
while (array_len--)
if (ccid_request_module(ccid_array[array_len]))
return -1;
#endif
return 0;
}

struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
{
struct ccid_operations *ccid_ops;
struct ccid *ccid = NULL;

ccids_read_lock();
#ifdef CONFIG_KMOD
if (ccids[id] == NULL) {
/* We only try to load if in process context */
ccids_read_unlock();
if (gfp & GFP_ATOMIC)
goto out;
request_module("net-dccp-ccid-%d", id);
ccids_read_lock();
}
#endif
ccid_ops = ccids[id];
if (ccid_ops == NULL)
goto out_unlock;
Expand Down
1 change: 1 addition & 0 deletions trunk/net/dccp/ccid.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ extern int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len);
extern int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
char __user *, int __user *);

extern int ccid_request_modules(u8 const *ccid_array, u8 array_len);
extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
gfp_t gfp);

Expand Down
5 changes: 5 additions & 0 deletions trunk/net/dccp/feat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,11 @@ int dccp_feat_init(struct sock *sk)
ccid_get_builtin_ccids(&rx.val, &rx.len))
return -ENOBUFS;

/* Pre-load all CCID modules that are going to be advertised */
rc = -EUNATCH;
if (ccid_request_modules(tx.val, tx.len))
goto free_ccid_lists;

if (!dccp_feat_prefer(sysctl_dccp_feat_tx_ccid, tx.val, tx.len) ||
!dccp_feat_prefer(sysctl_dccp_feat_rx_ccid, rx.val, rx.len))
goto free_ccid_lists;
Expand Down

0 comments on commit 43f62aa

Please sign in to comment.