diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-25 21:30:21 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-25 21:30:21 -0500 |
| commit | c42b4e6501cdaabee8cc292ae1ef0f66bf4825c1 (patch) | |
| tree | 8ae9c4f0881891459107a226968a65a265b34134 | |
| parent | aebf045382edb32bd763d8edea02a559e7dc41e9 (diff) | |
Revert "n_gsm: race between ld close and gsmtty open"
This reverts commit c284ee2cf12b55fa8496b2d098bf0938688f1c1c. Turns out
the locking was incorrect.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Cc: Chao Bi <chao.bi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/tty/n_gsm.c | 37 |
1 files changed, 10 insertions, 27 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 069bfd654485..c0f76da55304 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
| @@ -2054,11 +2054,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
| 2054 | dlci->state == DLCI_CLOSED); | 2054 | dlci->state == DLCI_CLOSED); |
| 2055 | } | 2055 | } |
| 2056 | /* Free up any link layer users */ | 2056 | /* Free up any link layer users */ |
| 2057 | spin_lock(&gsm->lock); | ||
| 2058 | for (i = 0; i < NUM_DLCI; i++) | 2057 | for (i = 0; i < NUM_DLCI; i++) |
| 2059 | if (gsm->dlci[i]) | 2058 | if (gsm->dlci[i]) |
| 2060 | gsm_dlci_release(gsm->dlci[i]); | 2059 | gsm_dlci_release(gsm->dlci[i]); |
| 2061 | spin_unlock(&gsm->lock); | ||
| 2062 | /* Now wipe the queues */ | 2060 | /* Now wipe the queues */ |
| 2063 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) | 2061 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) |
| 2064 | kfree(txq); | 2062 | kfree(txq); |
| @@ -2911,33 +2909,23 @@ static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 2911 | This is ok from a locking | 2909 | This is ok from a locking |
| 2912 | perspective as we don't have to worry about this | 2910 | perspective as we don't have to worry about this |
| 2913 | if DLCI0 is lost */ | 2911 | if DLCI0 is lost */ |
| 2914 | spin_lock(&gsm->lock); | 2912 | if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) |
| 2915 | if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) { | ||
| 2916 | spin_unlock(&gsm->lock); | ||
| 2917 | return -EL2NSYNC; | 2913 | return -EL2NSYNC; |
| 2918 | } | ||
| 2919 | dlci = gsm->dlci[line]; | 2914 | dlci = gsm->dlci[line]; |
| 2920 | if (dlci == NULL) { | 2915 | if (dlci == NULL) { |
| 2921 | alloc = true; | 2916 | alloc = true; |
| 2922 | dlci = gsm_dlci_alloc(gsm, line); | 2917 | dlci = gsm_dlci_alloc(gsm, line); |
| 2923 | } | 2918 | } |
| 2924 | if (dlci == NULL) { | 2919 | if (dlci == NULL) |
| 2925 | spin_unlock(&gsm->lock); | ||
| 2926 | return -ENOMEM; | 2920 | return -ENOMEM; |
| 2927 | } | ||
| 2928 | ret = tty_port_install(&dlci->port, driver, tty); | 2921 | ret = tty_port_install(&dlci->port, driver, tty); |
| 2929 | if (ret) { | 2922 | if (ret) { |
| 2930 | if (alloc) | 2923 | if (alloc) |
| 2931 | dlci_put(dlci); | 2924 | dlci_put(dlci); |
| 2932 | spin_unlock(&gsm->lock); | ||
| 2933 | return ret; | 2925 | return ret; |
| 2934 | } | 2926 | } |
| 2935 | 2927 | ||
| 2936 | dlci_get(dlci); | ||
| 2937 | dlci_get(gsm->dlci[0]); | ||
| 2938 | mux_get(gsm); | ||
| 2939 | tty->driver_data = dlci; | 2928 | tty->driver_data = dlci; |
| 2940 | spin_unlock(&gsm->lock); | ||
| 2941 | 2929 | ||
| 2942 | return 0; | 2930 | return 0; |
| 2943 | } | 2931 | } |
| @@ -2948,6 +2936,9 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) | |||
| 2948 | struct tty_port *port = &dlci->port; | 2936 | struct tty_port *port = &dlci->port; |
| 2949 | 2937 | ||
| 2950 | port->count++; | 2938 | port->count++; |
| 2939 | dlci_get(dlci); | ||
| 2940 | dlci_get(dlci->gsm->dlci[0]); | ||
| 2941 | mux_get(dlci->gsm); | ||
| 2951 | tty_port_tty_set(port, tty); | 2942 | tty_port_tty_set(port, tty); |
| 2952 | 2943 | ||
| 2953 | dlci->modem_rx = 0; | 2944 | dlci->modem_rx = 0; |
| @@ -2974,7 +2965,7 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
| 2974 | mutex_unlock(&dlci->mutex); | 2965 | mutex_unlock(&dlci->mutex); |
| 2975 | gsm = dlci->gsm; | 2966 | gsm = dlci->gsm; |
| 2976 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) | 2967 | if (tty_port_close_start(&dlci->port, tty, filp) == 0) |
| 2977 | return; | 2968 | goto out; |
| 2978 | gsm_dlci_begin_close(dlci); | 2969 | gsm_dlci_begin_close(dlci); |
| 2979 | if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { | 2970 | if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { |
| 2980 | if (C_HUPCL(tty)) | 2971 | if (C_HUPCL(tty)) |
| @@ -2982,7 +2973,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
| 2982 | } | 2973 | } |
| 2983 | tty_port_close_end(&dlci->port, tty); | 2974 | tty_port_close_end(&dlci->port, tty); |
| 2984 | tty_port_tty_set(&dlci->port, NULL); | 2975 | tty_port_tty_set(&dlci->port, NULL); |
| 2985 | return; | 2976 | out: |
| 2977 | dlci_put(dlci); | ||
| 2978 | dlci_put(gsm->dlci[0]); | ||
| 2979 | mux_put(gsm); | ||
| 2986 | } | 2980 | } |
| 2987 | 2981 | ||
| 2988 | static void gsmtty_hangup(struct tty_struct *tty) | 2982 | static void gsmtty_hangup(struct tty_struct *tty) |
| @@ -3159,16 +3153,6 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) | |||
| 3159 | return gsmtty_modem_update(dlci, encode); | 3153 | return gsmtty_modem_update(dlci, encode); |
| 3160 | } | 3154 | } |
| 3161 | 3155 | ||
| 3162 | static void gsmtty_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
| 3163 | { | ||
| 3164 | struct gsm_dlci *dlci = tty->driver_data; | ||
| 3165 | struct gsm_mux *gsm = dlci->gsm; | ||
| 3166 | |||
| 3167 | dlci_put(dlci); | ||
| 3168 | dlci_put(gsm->dlci[0]); | ||
| 3169 | mux_put(gsm); | ||
| 3170 | driver->ttys[tty->index] = NULL; | ||
| 3171 | } | ||
| 3172 | 3156 | ||
| 3173 | /* Virtual ttys for the demux */ | 3157 | /* Virtual ttys for the demux */ |
| 3174 | static const struct tty_operations gsmtty_ops = { | 3158 | static const struct tty_operations gsmtty_ops = { |
| @@ -3188,7 +3172,6 @@ static const struct tty_operations gsmtty_ops = { | |||
| 3188 | .tiocmget = gsmtty_tiocmget, | 3172 | .tiocmget = gsmtty_tiocmget, |
| 3189 | .tiocmset = gsmtty_tiocmset, | 3173 | .tiocmset = gsmtty_tiocmset, |
| 3190 | .break_ctl = gsmtty_break_ctl, | 3174 | .break_ctl = gsmtty_break_ctl, |
| 3191 | .remove = gsmtty_remove, | ||
| 3192 | }; | 3175 | }; |
| 3193 | 3176 | ||
| 3194 | 3177 | ||
