diff options
| author | Ursula Braun <ursula.braun@de.ibm.com> | 2010-07-22 19:15:05 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-07-23 15:36:23 -0400 |
| commit | 9dc48ccc68b9dfc01c2beee2d4317fb3df3fdce9 (patch) | |
| tree | 83d101e637385276ca40af1bb70ecc14ab24e33f /drivers/s390/net | |
| parent | 75e0de13631e115768a97131a2d7f5259217512d (diff) | |
qeth: serialize sysfs-triggered device configurations
This patch serializes device removal and other sysfs-triggered
configurations by moving removal of sysfs-attributes to the beginning
of the remove functions. And it serializes online/offline setting
and discipline-switching (causing reestablishing of the net_device)
by making use of a new discipline mutex.
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net')
| -rw-r--r-- | drivers/s390/net/qeth_core.h | 1 | ||||
| -rw-r--r-- | drivers/s390/net/qeth_core_main.c | 11 | ||||
| -rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 4 | ||||
| -rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 5 | ||||
| -rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 8 |
5 files changed, 22 insertions, 7 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index e7e99e6cad21..41ddf86c3421 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
| @@ -747,6 +747,7 @@ struct qeth_card { | |||
| 747 | struct qdio_ssqd_desc ssqd; | 747 | struct qdio_ssqd_desc ssqd; |
| 748 | debug_info_t *debug; | 748 | debug_info_t *debug; |
| 749 | struct mutex conf_mutex; | 749 | struct mutex conf_mutex; |
| 750 | struct mutex discipline_mutex; | ||
| 750 | }; | 751 | }; |
| 751 | 752 | ||
| 752 | struct qeth_card_list_struct { | 753 | struct qeth_card_list_struct { |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 844935fbe6a8..f33da45c35ef 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -1084,6 +1084,7 @@ static int qeth_setup_card(struct qeth_card *card) | |||
| 1084 | spin_lock_init(&card->ip_lock); | 1084 | spin_lock_init(&card->ip_lock); |
| 1085 | spin_lock_init(&card->thread_mask_lock); | 1085 | spin_lock_init(&card->thread_mask_lock); |
| 1086 | mutex_init(&card->conf_mutex); | 1086 | mutex_init(&card->conf_mutex); |
| 1087 | mutex_init(&card->discipline_mutex); | ||
| 1087 | card->thread_start_mask = 0; | 1088 | card->thread_start_mask = 0; |
| 1088 | card->thread_allowed_mask = 0; | 1089 | card->thread_allowed_mask = 0; |
| 1089 | card->thread_running_mask = 0; | 1090 | card->thread_running_mask = 0; |
| @@ -4348,16 +4349,18 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) | |||
| 4348 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | 4349 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); |
| 4349 | 4350 | ||
| 4350 | QETH_DBF_TEXT(SETUP, 2, "removedv"); | 4351 | QETH_DBF_TEXT(SETUP, 2, "removedv"); |
| 4351 | if (card->discipline.ccwgdriver) { | ||
| 4352 | card->discipline.ccwgdriver->remove(gdev); | ||
| 4353 | qeth_core_free_discipline(card); | ||
| 4354 | } | ||
| 4355 | 4352 | ||
| 4356 | if (card->info.type == QETH_CARD_TYPE_OSN) { | 4353 | if (card->info.type == QETH_CARD_TYPE_OSN) { |
| 4357 | qeth_core_remove_osn_attributes(&gdev->dev); | 4354 | qeth_core_remove_osn_attributes(&gdev->dev); |
| 4358 | } else { | 4355 | } else { |
| 4359 | qeth_core_remove_device_attributes(&gdev->dev); | 4356 | qeth_core_remove_device_attributes(&gdev->dev); |
| 4360 | } | 4357 | } |
| 4358 | |||
| 4359 | if (card->discipline.ccwgdriver) { | ||
| 4360 | card->discipline.ccwgdriver->remove(gdev); | ||
| 4361 | qeth_core_free_discipline(card); | ||
| 4362 | } | ||
| 4363 | |||
| 4361 | debug_unregister(card->debug); | 4364 | debug_unregister(card->debug); |
| 4362 | write_lock_irqsave(&qeth_core_card_list.rwlock, flags); | 4365 | write_lock_irqsave(&qeth_core_card_list.rwlock, flags); |
| 4363 | list_del(&card->list); | 4366 | list_del(&card->list); |
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 6b7fd88e8e4d..42fa783a70c8 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c | |||
| @@ -411,7 +411,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
| 411 | if (!card) | 411 | if (!card) |
| 412 | return -EINVAL; | 412 | return -EINVAL; |
| 413 | 413 | ||
| 414 | mutex_lock(&card->conf_mutex); | 414 | mutex_lock(&card->discipline_mutex); |
| 415 | if (card->state != CARD_STATE_DOWN) { | 415 | if (card->state != CARD_STATE_DOWN) { |
| 416 | rc = -EPERM; | 416 | rc = -EPERM; |
| 417 | goto out; | 417 | goto out; |
| @@ -446,7 +446,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
| 446 | 446 | ||
| 447 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 447 | rc = card->discipline.ccwgdriver->probe(card->gdev); |
| 448 | out: | 448 | out: |
| 449 | mutex_unlock(&card->conf_mutex); | 449 | mutex_unlock(&card->discipline_mutex); |
| 450 | return rc ? rc : count; | 450 | return rc ? rc : count; |
| 451 | } | 451 | } |
| 452 | 452 | ||
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 32d07c2dcc67..5e66333a8bea 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
| @@ -935,6 +935,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
| 935 | enum qeth_card_states recover_flag; | 935 | enum qeth_card_states recover_flag; |
| 936 | 936 | ||
| 937 | BUG_ON(!card); | 937 | BUG_ON(!card); |
| 938 | mutex_lock(&card->discipline_mutex); | ||
| 938 | mutex_lock(&card->conf_mutex); | 939 | mutex_lock(&card->conf_mutex); |
| 939 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 940 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
| 940 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 941 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
| @@ -1012,6 +1013,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
| 1012 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 1013 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
| 1013 | out: | 1014 | out: |
| 1014 | mutex_unlock(&card->conf_mutex); | 1015 | mutex_unlock(&card->conf_mutex); |
| 1016 | mutex_unlock(&card->discipline_mutex); | ||
| 1015 | return 0; | 1017 | return 0; |
| 1016 | 1018 | ||
| 1017 | out_remove: | 1019 | out_remove: |
| @@ -1025,6 +1027,7 @@ out_remove: | |||
| 1025 | else | 1027 | else |
| 1026 | card->state = CARD_STATE_DOWN; | 1028 | card->state = CARD_STATE_DOWN; |
| 1027 | mutex_unlock(&card->conf_mutex); | 1029 | mutex_unlock(&card->conf_mutex); |
| 1030 | mutex_unlock(&card->discipline_mutex); | ||
| 1028 | return rc; | 1031 | return rc; |
| 1029 | } | 1032 | } |
| 1030 | 1033 | ||
| @@ -1040,6 +1043,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
| 1040 | int rc = 0, rc2 = 0, rc3 = 0; | 1043 | int rc = 0, rc2 = 0, rc3 = 0; |
| 1041 | enum qeth_card_states recover_flag; | 1044 | enum qeth_card_states recover_flag; |
| 1042 | 1045 | ||
| 1046 | mutex_lock(&card->discipline_mutex); | ||
| 1043 | mutex_lock(&card->conf_mutex); | 1047 | mutex_lock(&card->conf_mutex); |
| 1044 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 1048 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
| 1045 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 1049 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
| @@ -1060,6 +1064,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
| 1060 | /* let user_space know that device is offline */ | 1064 | /* let user_space know that device is offline */ |
| 1061 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 1065 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
| 1062 | mutex_unlock(&card->conf_mutex); | 1066 | mutex_unlock(&card->conf_mutex); |
| 1067 | mutex_unlock(&card->discipline_mutex); | ||
| 1063 | return 0; | 1068 | return 0; |
| 1064 | } | 1069 | } |
| 1065 | 1070 | ||
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 15b5ca82bd26..e22ae248f613 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
| @@ -3354,6 +3354,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) | |||
| 3354 | { | 3354 | { |
| 3355 | struct qeth_card *card = dev_get_drvdata(&cgdev->dev); | 3355 | struct qeth_card *card = dev_get_drvdata(&cgdev->dev); |
| 3356 | 3356 | ||
| 3357 | qeth_l3_remove_device_attributes(&cgdev->dev); | ||
| 3358 | |||
| 3357 | qeth_set_allowed_threads(card, 0, 1); | 3359 | qeth_set_allowed_threads(card, 0, 1); |
| 3358 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); | 3360 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
| 3359 | 3361 | ||
| @@ -3367,7 +3369,6 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) | |||
| 3367 | card->dev = NULL; | 3369 | card->dev = NULL; |
| 3368 | } | 3370 | } |
| 3369 | 3371 | ||
| 3370 | qeth_l3_remove_device_attributes(&cgdev->dev); | ||
| 3371 | qeth_l3_clear_ip_list(card, 0, 0); | 3372 | qeth_l3_clear_ip_list(card, 0, 0); |
| 3372 | qeth_l3_clear_ipato_list(card); | 3373 | qeth_l3_clear_ipato_list(card); |
| 3373 | return; | 3374 | return; |
| @@ -3380,6 +3381,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
| 3380 | enum qeth_card_states recover_flag; | 3381 | enum qeth_card_states recover_flag; |
| 3381 | 3382 | ||
| 3382 | BUG_ON(!card); | 3383 | BUG_ON(!card); |
| 3384 | mutex_lock(&card->discipline_mutex); | ||
| 3383 | mutex_lock(&card->conf_mutex); | 3385 | mutex_lock(&card->conf_mutex); |
| 3384 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 3386 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
| 3385 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 3387 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
| @@ -3461,6 +3463,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
| 3461 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 3463 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
| 3462 | out: | 3464 | out: |
| 3463 | mutex_unlock(&card->conf_mutex); | 3465 | mutex_unlock(&card->conf_mutex); |
| 3466 | mutex_unlock(&card->discipline_mutex); | ||
| 3464 | return 0; | 3467 | return 0; |
| 3465 | out_remove: | 3468 | out_remove: |
| 3466 | card->use_hard_stop = 1; | 3469 | card->use_hard_stop = 1; |
| @@ -3473,6 +3476,7 @@ out_remove: | |||
| 3473 | else | 3476 | else |
| 3474 | card->state = CARD_STATE_DOWN; | 3477 | card->state = CARD_STATE_DOWN; |
| 3475 | mutex_unlock(&card->conf_mutex); | 3478 | mutex_unlock(&card->conf_mutex); |
| 3479 | mutex_unlock(&card->discipline_mutex); | ||
| 3476 | return rc; | 3480 | return rc; |
| 3477 | } | 3481 | } |
| 3478 | 3482 | ||
| @@ -3488,6 +3492,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
| 3488 | int rc = 0, rc2 = 0, rc3 = 0; | 3492 | int rc = 0, rc2 = 0, rc3 = 0; |
| 3489 | enum qeth_card_states recover_flag; | 3493 | enum qeth_card_states recover_flag; |
| 3490 | 3494 | ||
| 3495 | mutex_lock(&card->discipline_mutex); | ||
| 3491 | mutex_lock(&card->conf_mutex); | 3496 | mutex_lock(&card->conf_mutex); |
| 3492 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 3497 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
| 3493 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 3498 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
| @@ -3508,6 +3513,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
| 3508 | /* let user_space know that device is offline */ | 3513 | /* let user_space know that device is offline */ |
| 3509 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 3514 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
| 3510 | mutex_unlock(&card->conf_mutex); | 3515 | mutex_unlock(&card->conf_mutex); |
| 3516 | mutex_unlock(&card->discipline_mutex); | ||
| 3511 | return 0; | 3517 | return 0; |
| 3512 | } | 3518 | } |
| 3513 | 3519 | ||
