One use of the goto that is commonly overlooked is it's use in writing code based on a state machine (such an Finite State Automaton for those of you following in your CS texts) where a state transition can't be smoothly done in the regular program flow.

Granted, a table could be constructed to represent your states and the transitions, and you could jump arround inside the table, however this would result in the program logic (the state transition table) being represented as program data and not executable code.

Since many modern processors have separate data and instruction caches, this could result in a significant decrease in performance when working on large amounts of data that would be difficult for the compiler to optimize out.

Using gotos in this way is fundamentally different than using them to fiddle with a for loop like zbuffer mentions above. While the example from the kernel is used as a work around for the compiler not creating optimal assembly code, using gotos in your state machine rather than using a table results in the machine actually being compiled to assembly.

With my defense of the goto out of the way, I have two warnings. First, if you don't understand what a state machine is, you probably shouldn't use one. Secondly, if you don't need brutal optimizations, a simple loop to dance around a staticly defined state table will be simpler to read & modify and less prone to errors.