@@ -265,6 +265,17 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
265265 */
266266
267267
268+ /**
269+ * tty_buffer_free_all - free buffers used by a tty
270+ * @tty: tty to free from
271+ *
272+ * Remove all the buffers pending on a tty whether queued with data
273+ * or in the free ring. Must be called when the tty is no longer in use
274+ *
275+ * Locking: none
276+ */
277+
278+
268279/**
269280 * tty_buffer_free_all - free buffers used by a tty
270281 * @tty: tty to free from
@@ -287,19 +298,47 @@ static void tty_buffer_free_all(struct tty_struct *tty)
287298 kfree (thead );
288299 }
289300 tty -> buf .tail = NULL ;
301+ tty -> buf .memory_used = 0 ;
290302}
291303
304+ /**
305+ * tty_buffer_init - prepare a tty buffer structure
306+ * @tty: tty to initialise
307+ *
308+ * Set up the initial state of the buffer management for a tty device.
309+ * Must be called before the other tty buffer functions are used.
310+ *
311+ * Locking: none
312+ */
313+
292314static void tty_buffer_init (struct tty_struct * tty )
293315{
294316 spin_lock_init (& tty -> buf .lock );
295317 tty -> buf .head = NULL ;
296318 tty -> buf .tail = NULL ;
297319 tty -> buf .free = NULL ;
320+ tty -> buf .memory_used = 0 ;
298321}
299322
300- static struct tty_buffer * tty_buffer_alloc (size_t size )
323+ /**
324+ * tty_buffer_alloc - allocate a tty buffer
325+ * @tty: tty device
326+ * @size: desired size (characters)
327+ *
328+ * Allocate a new tty buffer to hold the desired number of characters.
329+ * Return NULL if out of memory or the allocation would exceed the
330+ * per device queue
331+ *
332+ * Locking: Caller must hold tty->buf.lock
333+ */
334+
335+ static struct tty_buffer * tty_buffer_alloc (struct tty_struct * tty , size_t size )
301336{
302- struct tty_buffer * p = kmalloc (sizeof (struct tty_buffer ) + 2 * size , GFP_ATOMIC );
337+ struct tty_buffer * p ;
338+
339+ if (tty -> buf .memory_used + size > 65536 )
340+ return NULL ;
341+ p = kmalloc (sizeof (struct tty_buffer ) + 2 * size , GFP_ATOMIC );
303342 if (p == NULL )
304343 return NULL ;
305344 p -> used = 0 ;
@@ -309,17 +348,27 @@ static struct tty_buffer *tty_buffer_alloc(size_t size)
309348 p -> read = 0 ;
310349 p -> char_buf_ptr = (char * )(p -> data );
311350 p -> flag_buf_ptr = (unsigned char * )p -> char_buf_ptr + size ;
312- /* printk("Flip create %p\n", p); */
351+ tty -> buf . memory_used += size ;
313352 return p ;
314353}
315354
316- /* Must be called with the tty_read lock held. This needs to acquire strategy
317- code to decide if we should kfree or relink a given expired buffer */
355+ /**
356+ * tty_buffer_free - free a tty buffer
357+ * @tty: tty owning the buffer
358+ * @b: the buffer to free
359+ *
360+ * Free a tty buffer, or add it to the free list according to our
361+ * internal strategy
362+ *
363+ * Locking: Caller must hold tty->buf.lock
364+ */
318365
319366static void tty_buffer_free (struct tty_struct * tty , struct tty_buffer * b )
320367{
321368 /* Dumb strategy for now - should keep some stats */
322- /* printk("Flip dispose %p\n", b); */
369+ tty -> buf .memory_used -= b -> size ;
370+ WARN_ON (tty -> buf .memory_used < 0 );
371+
323372 if (b -> size >= 512 )
324373 kfree (b );
325374 else {
@@ -328,6 +377,18 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
328377 }
329378}
330379
380+ /**
381+ * tty_buffer_find - find a free tty buffer
382+ * @tty: tty owning the buffer
383+ * @size: characters wanted
384+ *
385+ * Locate an existing suitable tty buffer or if we are lacking one then
386+ * allocate a new one. We round our buffers off in 256 character chunks
387+ * to get better allocation behaviour.
388+ *
389+ * Locking: Caller must hold tty->buf.lock
390+ */
391+
331392static struct tty_buffer * tty_buffer_find (struct tty_struct * tty , size_t size )
332393{
333394 struct tty_buffer * * tbh = & tty -> buf .free ;
@@ -339,20 +400,28 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
339400 t -> used = 0 ;
340401 t -> commit = 0 ;
341402 t -> read = 0 ;
342- /* DEBUG ONLY */
343- /* memset(t->data, '*', size); */
344- /* printk("Flip recycle %p\n", t); */
403+ tty -> buf .memory_used += t -> size ;
345404 return t ;
346405 }
347406 tbh = & ((* tbh )-> next );
348407 }
349408 /* Round the buffer size out */
350409 size = (size + 0xFF ) & ~ 0xFF ;
351- return tty_buffer_alloc (size );
410+ return tty_buffer_alloc (tty , size );
352411 /* Should possibly check if this fails for the largest buffer we
353412 have queued and recycle that ? */
354413}
355414
415+ /**
416+ * tty_buffer_request_room - grow tty buffer if needed
417+ * @tty: tty structure
418+ * @size: size desired
419+ *
420+ * Make at least size bytes of linear space available for the tty
421+ * buffer. If we fail return the size we managed to find.
422+ *
423+ * Locking: Takes tty->buf.lock
424+ */
356425int tty_buffer_request_room (struct tty_struct * tty , size_t size )
357426{
358427 struct tty_buffer * b , * n ;
0 commit comments