diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2008-06-12 13:19:19 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-14 12:18:10 -0400 |
commit | 90d07349f8d754b89de8c61bdef9f95688900f30 (patch) | |
tree | 742a449b46354085199c10c34804ff2ac6c06f09 /drivers/net | |
parent | bb8649d42989eddf9c7d128114c1adcffe9eef54 (diff) |
rndis_wlan: preallocate command buffer for set/get_oid
Reduce amount of kmalloc/kfree calls in set/get_oid by preallocating command
buffer.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/rndis_wlan.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 6eb487dcc42f..a0ad8e781dd3 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -314,6 +314,8 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, | |||
314 | #define WORK_LINK_DOWN (1<<1) | 314 | #define WORK_LINK_DOWN (1<<1) |
315 | #define WORK_SET_MULTICAST_LIST (1<<2) | 315 | #define WORK_SET_MULTICAST_LIST (1<<2) |
316 | 316 | ||
317 | #define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set)) | ||
318 | |||
317 | /* RNDIS device private data */ | 319 | /* RNDIS device private data */ |
318 | struct rndis_wext_private { | 320 | struct rndis_wext_private { |
319 | char name[32]; | 321 | char name[32]; |
@@ -362,6 +364,8 @@ struct rndis_wext_private { | |||
362 | u8 *wpa_ie; | 364 | u8 *wpa_ie; |
363 | int wpa_cipher_pair; | 365 | int wpa_cipher_pair; |
364 | int wpa_cipher_group; | 366 | int wpa_cipher_group; |
367 | |||
368 | u8 command_buffer[COMMAND_BUFFER_SIZE]; | ||
365 | }; | 369 | }; |
366 | 370 | ||
367 | 371 | ||
@@ -428,18 +432,23 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
428 | buflen = *len + sizeof(*u.get); | 432 | buflen = *len + sizeof(*u.get); |
429 | if (buflen < CONTROL_BUFFER_SIZE) | 433 | if (buflen < CONTROL_BUFFER_SIZE) |
430 | buflen = CONTROL_BUFFER_SIZE; | 434 | buflen = CONTROL_BUFFER_SIZE; |
431 | u.buf = kmalloc(buflen, GFP_KERNEL); | 435 | |
432 | if (!u.buf) | 436 | if (buflen > COMMAND_BUFFER_SIZE) { |
433 | return -ENOMEM; | 437 | u.buf = kmalloc(buflen, GFP_KERNEL); |
438 | if (!u.buf) | ||
439 | return -ENOMEM; | ||
440 | } else { | ||
441 | u.buf = priv->command_buffer; | ||
442 | } | ||
443 | |||
444 | mutex_lock(&priv->command_lock); | ||
445 | |||
434 | memset(u.get, 0, sizeof *u.get); | 446 | memset(u.get, 0, sizeof *u.get); |
435 | u.get->msg_type = RNDIS_MSG_QUERY; | 447 | u.get->msg_type = RNDIS_MSG_QUERY; |
436 | u.get->msg_len = ccpu2(sizeof *u.get); | 448 | u.get->msg_len = ccpu2(sizeof *u.get); |
437 | u.get->oid = oid; | 449 | u.get->oid = oid; |
438 | 450 | ||
439 | mutex_lock(&priv->command_lock); | ||
440 | ret = rndis_command(dev, u.header); | 451 | ret = rndis_command(dev, u.header); |
441 | mutex_unlock(&priv->command_lock); | ||
442 | |||
443 | if (ret == 0) { | 452 | if (ret == 0) { |
444 | ret = le32_to_cpu(u.get_c->len); | 453 | ret = le32_to_cpu(u.get_c->len); |
445 | *len = (*len > ret) ? ret : *len; | 454 | *len = (*len > ret) ? ret : *len; |
@@ -447,7 +456,10 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
447 | ret = rndis_error_status(u.get_c->status); | 456 | ret = rndis_error_status(u.get_c->status); |
448 | } | 457 | } |
449 | 458 | ||
450 | kfree(u.buf); | 459 | mutex_unlock(&priv->command_lock); |
460 | |||
461 | if (u.buf != priv->command_buffer) | ||
462 | kfree(u.buf); | ||
451 | return ret; | 463 | return ret; |
452 | } | 464 | } |
453 | 465 | ||
@@ -466,9 +478,16 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | |||
466 | buflen = len + sizeof(*u.set); | 478 | buflen = len + sizeof(*u.set); |
467 | if (buflen < CONTROL_BUFFER_SIZE) | 479 | if (buflen < CONTROL_BUFFER_SIZE) |
468 | buflen = CONTROL_BUFFER_SIZE; | 480 | buflen = CONTROL_BUFFER_SIZE; |
469 | u.buf = kmalloc(buflen, GFP_KERNEL); | 481 | |
470 | if (!u.buf) | 482 | if (buflen > COMMAND_BUFFER_SIZE) { |
471 | return -ENOMEM; | 483 | u.buf = kmalloc(buflen, GFP_KERNEL); |
484 | if (!u.buf) | ||
485 | return -ENOMEM; | ||
486 | } else { | ||
487 | u.buf = priv->command_buffer; | ||
488 | } | ||
489 | |||
490 | mutex_lock(&priv->command_lock); | ||
472 | 491 | ||
473 | memset(u.set, 0, sizeof *u.set); | 492 | memset(u.set, 0, sizeof *u.set); |
474 | u.set->msg_type = RNDIS_MSG_SET; | 493 | u.set->msg_type = RNDIS_MSG_SET; |
@@ -479,14 +498,14 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | |||
479 | u.set->handle = ccpu2(0); | 498 | u.set->handle = ccpu2(0); |
480 | memcpy(u.buf + sizeof(*u.set), data, len); | 499 | memcpy(u.buf + sizeof(*u.set), data, len); |
481 | 500 | ||
482 | mutex_lock(&priv->command_lock); | ||
483 | ret = rndis_command(dev, u.header); | 501 | ret = rndis_command(dev, u.header); |
484 | mutex_unlock(&priv->command_lock); | ||
485 | |||
486 | if (ret == 0) | 502 | if (ret == 0) |
487 | ret = rndis_error_status(u.set_c->status); | 503 | ret = rndis_error_status(u.set_c->status); |
488 | 504 | ||
489 | kfree(u.buf); | 505 | mutex_unlock(&priv->command_lock); |
506 | |||
507 | if (u.buf != priv->command_buffer) | ||
508 | kfree(u.buf); | ||
490 | return ret; | 509 | return ret; |
491 | } | 510 | } |
492 | 511 | ||