Commit 7d7b93c1452f381350dbaf276a63357fa6559e6d

Authored by Alan Cox
Committed by Linus Torvalds
1 parent 99f1fe189d

tty: kref the tty driver object

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 5 changed files with 80 additions and 58 deletions Side-by-side Diff

drivers/char/ip2/ip2main.c
... ... @@ -264,8 +264,8 @@
264 264 /**********/
265 265  
266 266 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
267   -#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
268   - tty->name,(pCh->flags),ip2_tty_driver->refcount, \
  267 +#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \
  268 + tty->name,(pCh->flags), \
269 269 tty->count,/*GET_USE_COUNT(module)*/0,s)
270 270 #else
271 271 #define DBG_CNT(s)
... ... @@ -2893,7 +2893,7 @@
2893 2893 case 13:
2894 2894 switch ( cmd ) {
2895 2895 case 64: /* Driver - ip2stat */
2896   - rc = put_user(ip2_tty_driver->refcount, pIndex++ );
  2896 + rc = put_user(-1, pIndex++ );
2897 2897 rc = put_user(irq_counter, pIndex++ );
2898 2898 rc = put_user(bh_counter, pIndex++ );
2899 2899 break;
... ... @@ -571,8 +571,11 @@
571 571 if (tty_register_driver(pts_driver))
572 572 panic("Couldn't register Unix98 pts driver");
573 573  
  574 + /* FIXME: WTF */
  575 +#if 0
574 576 pty_table[1].data = &ptm_driver->refcount;
575   - register_sysctl_table(pty_root_table);
  577 +#endif
  578 + register_sysctl_table(pty_root_table);
576 579  
577 580 /* Now create the /dev/ptmx special device */
578 581 tty_default_fops(&ptmx_fops);
drivers/char/tty_io.c
... ... @@ -276,7 +276,7 @@
276 276 if (device < base || device >= base + p->num)
277 277 continue;
278 278 *index = device - base;
279   - return p;
  279 + return tty_driver_kref_get(p);
280 280 }
281 281 return NULL;
282 282 }
... ... @@ -320,7 +320,7 @@
320 320  
321 321 if (tty_line >= 0 && tty_line <= p->num && p->ops &&
322 322 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) {
323   - res = p;
  323 + res = tty_driver_kref_get(p);
324 324 *line = tty_line;
325 325 break;
326 326 }
... ... @@ -1410,7 +1410,7 @@
1410 1410 *o_ltp_loc = o_ltp;
1411 1411 o_tty->termios = *o_tp_loc;
1412 1412 o_tty->termios_locked = *o_ltp_loc;
1413   - driver->other->refcount++;
  1413 + tty_driver_kref_get(driver->other);
1414 1414 if (driver->subtype == PTY_TYPE_MASTER)
1415 1415 o_tty->count++;
1416 1416  
... ... @@ -1438,7 +1438,7 @@
1438 1438 /* Compatibility until drivers always set this */
1439 1439 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1440 1440 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1441   - driver->refcount++;
  1441 + tty_driver_kref_get(driver);
1442 1442 tty->count++;
1443 1443  
1444 1444 /*
... ... @@ -1530,8 +1530,7 @@
1530 1530 else
1531 1531 tty_shutdown(tty);
1532 1532 tty->magic = 0;
1533   - /* FIXME: locking on tty->driver->refcount */
1534   - tty->driver->refcount--;
  1533 + tty_driver_kref_put(driver);
1535 1534 module_put(driver->owner);
1536 1535  
1537 1536 file_list_lock();
... ... @@ -1854,7 +1853,7 @@
1854 1853 mutex_unlock(&tty_mutex);
1855 1854 return -ENXIO;
1856 1855 }
1857   - driver = tty->driver;
  1856 + driver = tty_driver_kref_get(tty->driver);
1858 1857 index = tty->index;
1859 1858 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
1860 1859 /* noctty = 1; */
1861 1860  
... ... @@ -1865,14 +1864,14 @@
1865 1864 #ifdef CONFIG_VT
1866 1865 if (device == MKDEV(TTY_MAJOR, 0)) {
1867 1866 extern struct tty_driver *console_driver;
1868   - driver = console_driver;
  1867 + driver = tty_driver_kref_get(console_driver);
1869 1868 index = fg_console;
1870 1869 noctty = 1;
1871 1870 goto got_driver;
1872 1871 }
1873 1872 #endif
1874 1873 if (device == MKDEV(TTYAUX_MAJOR, 1)) {
1875   - driver = console_device(&index);
  1874 + driver = tty_driver_kref_get(console_device(&index));
1876 1875 if (driver) {
1877 1876 /* Don't let /dev/console block */
1878 1877 filp->f_flags |= O_NONBLOCK;
... ... @@ -1891,6 +1890,7 @@
1891 1890 got_driver:
1892 1891 retval = tty_init_dev(driver, index, &tty, 0);
1893 1892 mutex_unlock(&tty_mutex);
  1893 + tty_driver_kref_put(driver);
1894 1894 if (retval)
1895 1895 return retval;
1896 1896  
... ... @@ -2866,7 +2866,6 @@
2866 2866 return tty->ops->put_char(tty, ch);
2867 2867 return tty->ops->write(tty, &ch, 1);
2868 2868 }
2869   -
2870 2869 EXPORT_SYMBOL_GPL(tty_put_char);
2871 2870  
2872 2871 struct class *tty_class;
... ... @@ -2909,6 +2908,7 @@
2909 2908  
2910 2909 return device_create_drvdata(tty_class, device, dev, NULL, name);
2911 2910 }
  2911 +EXPORT_SYMBOL(tty_register_device);
2912 2912  
2913 2913 /**
2914 2914 * tty_unregister_device - unregister a tty device
... ... @@ -2926,8 +2926,6 @@
2926 2926 device_destroy(tty_class,
2927 2927 MKDEV(driver->major, driver->minor_start) + index);
2928 2928 }
2929   -
2930   -EXPORT_SYMBOL(tty_register_device);
2931 2929 EXPORT_SYMBOL(tty_unregister_device);
2932 2930  
2933 2931 struct tty_driver *alloc_tty_driver(int lines)
2934 2932  
2935 2933  
2936 2934  
2937 2935  
2938 2936  
2939 2937  
2940 2938  
... ... @@ -2936,27 +2934,70 @@
2936 2934  
2937 2935 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
2938 2936 if (driver) {
  2937 + kref_init(&driver->kref);
2939 2938 driver->magic = TTY_DRIVER_MAGIC;
2940 2939 driver->num = lines;
2941 2940 /* later we'll move allocation of tables here */
2942 2941 }
2943 2942 return driver;
2944 2943 }
  2944 +EXPORT_SYMBOL(alloc_tty_driver);
2945 2945  
2946   -void put_tty_driver(struct tty_driver *driver)
  2946 +static void destruct_tty_driver(struct kref *kref)
2947 2947 {
  2948 + struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
  2949 + int i;
  2950 + struct ktermios *tp;
  2951 + void *p;
  2952 +
  2953 + if (driver->flags & TTY_DRIVER_INSTALLED) {
  2954 + /*
  2955 + * Free the termios and termios_locked structures because
  2956 + * we don't want to get memory leaks when modular tty
  2957 + * drivers are removed from the kernel.
  2958 + */
  2959 + for (i = 0; i < driver->num; i++) {
  2960 + tp = driver->termios[i];
  2961 + if (tp) {
  2962 + driver->termios[i] = NULL;
  2963 + kfree(tp);
  2964 + }
  2965 + tp = driver->termios_locked[i];
  2966 + if (tp) {
  2967 + driver->termios_locked[i] = NULL;
  2968 + kfree(tp);
  2969 + }
  2970 + if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
  2971 + tty_unregister_device(driver, i);
  2972 + }
  2973 + p = driver->ttys;
  2974 + proc_tty_unregister_driver(driver);
  2975 + driver->ttys = NULL;
  2976 + driver->termios = driver->termios_locked = NULL;
  2977 + kfree(p);
  2978 + cdev_del(&driver->cdev);
  2979 + }
2948 2980 kfree(driver);
2949 2981 }
2950 2982  
  2983 +void tty_driver_kref_put(struct tty_driver *driver)
  2984 +{
  2985 + kref_put(&driver->kref, destruct_tty_driver);
  2986 +}
  2987 +EXPORT_SYMBOL(tty_driver_kref_put);
  2988 +
2951 2989 void tty_set_operations(struct tty_driver *driver,
2952 2990 const struct tty_operations *op)
2953 2991 {
2954 2992 driver->ops = op;
2955 2993 };
  2994 +EXPORT_SYMBOL(tty_set_operations);
2956 2995  
2957   -EXPORT_SYMBOL(alloc_tty_driver);
  2996 +void put_tty_driver(struct tty_driver *d)
  2997 +{
  2998 + tty_driver_kref_put(d);
  2999 +}
2958 3000 EXPORT_SYMBOL(put_tty_driver);
2959   -EXPORT_SYMBOL(tty_set_operations);
2960 3001  
2961 3002 /*
2962 3003 * Called by a tty driver to register itself.
... ... @@ -2968,9 +3009,6 @@
2968 3009 dev_t dev;
2969 3010 void **p = NULL;
2970 3011  
2971   - if (driver->flags & TTY_DRIVER_INSTALLED)
2972   - return 0;
2973   -
2974 3012 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
2975 3013 p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL);
2976 3014 if (!p)
... ... @@ -3024,6 +3062,7 @@
3024 3062 tty_register_device(driver, i, NULL);
3025 3063 }
3026 3064 proc_tty_register_driver(driver);
  3065 + driver->flags |= TTY_DRIVER_INSTALLED;
3027 3066 return 0;
3028 3067 }
3029 3068  
3030 3069  
3031 3070  
3032 3071  
... ... @@ -3034,46 +3073,19 @@
3034 3073 */
3035 3074 int tty_unregister_driver(struct tty_driver *driver)
3036 3075 {
3037   - int i;
3038   - struct ktermios *tp;
3039   - void *p;
3040   -
  3076 +#if 0
  3077 + /* FIXME */
3041 3078 if (driver->refcount)
3042 3079 return -EBUSY;
3043   -
  3080 +#endif
3044 3081 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
3045 3082 driver->num);
3046 3083 mutex_lock(&tty_mutex);
3047 3084 list_del(&driver->tty_drivers);
3048 3085 mutex_unlock(&tty_mutex);
3049   -
3050   - /*
3051   - * Free the termios and termios_locked structures because
3052   - * we don't want to get memory leaks when modular tty
3053   - * drivers are removed from the kernel.
3054   - */
3055   - for (i = 0; i < driver->num; i++) {
3056   - tp = driver->termios[i];
3057   - if (tp) {
3058   - driver->termios[i] = NULL;
3059   - kfree(tp);
3060   - }
3061   - tp = driver->termios_locked[i];
3062   - if (tp) {
3063   - driver->termios_locked[i] = NULL;
3064   - kfree(tp);
3065   - }
3066   - if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
3067   - tty_unregister_device(driver, i);
3068   - }
3069   - p = driver->ttys;
3070   - proc_tty_unregister_driver(driver);
3071   - driver->ttys = NULL;
3072   - driver->termios = driver->termios_locked = NULL;
3073   - kfree(p);
3074   - cdev_del(&driver->cdev);
3075 3086 return 0;
3076 3087 }
  3088 +
3077 3089 EXPORT_SYMBOL(tty_unregister_driver);
3078 3090  
3079 3091 dev_t tty_devnum(struct tty_struct *tty)
drivers/net/wan/Kconfig
... ... @@ -205,7 +205,7 @@
205 205  
206 206 config PC300
207 207 tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)"
208   - depends on HDLC && PCI
  208 + depends on HDLC && PCI && BROKEN
209 209 ---help---
210 210 Driver for the Cyclades-PC300 synchronous communication boards.
211 211  
include/linux/tty_driver.h
... ... @@ -253,6 +253,7 @@
253 253  
254 254 struct tty_driver {
255 255 int magic; /* magic number for this structure */
  256 + struct kref kref; /* Reference management */
256 257 struct cdev cdev;
257 258 struct module *owner;
258 259 const char *driver_name;
... ... @@ -266,7 +267,6 @@
266 267 short subtype; /* subtype of tty driver */
267 268 struct ktermios init_termios; /* Initial termios */
268 269 int flags; /* tty driver flags */
269   - int refcount; /* for loadable tty drivers */
270 270 struct proc_dir_entry *proc_entry; /* /proc fs entry */
271 271 struct tty_driver *other; /* only used for the PTY driver */
272 272  
273 273  
... ... @@ -288,11 +288,18 @@
288 288  
289 289 extern struct list_head tty_drivers;
290 290  
291   -struct tty_driver *alloc_tty_driver(int lines);
292   -void put_tty_driver(struct tty_driver *driver);
293   -void tty_set_operations(struct tty_driver *driver,
  291 +extern struct tty_driver *alloc_tty_driver(int lines);
  292 +extern void put_tty_driver(struct tty_driver *driver);
  293 +extern void tty_set_operations(struct tty_driver *driver,
294 294 const struct tty_operations *op);
295 295 extern struct tty_driver *tty_find_polling_driver(char *name, int *line);
  296 +
  297 +extern void tty_driver_kref_put(struct tty_driver *driver);
  298 +extern inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d)
  299 +{
  300 + kref_get(&d->kref);
  301 + return d;
  302 +}
296 303  
297 304 /* tty driver magic number */
298 305 #define TTY_DRIVER_MAGIC 0x5402